Java查漏补缺-高级篇-Java中的常用类:日期时间处理相关API

JDK 8之前

在这里插入图片描述

java.lang.System静态方法

System类提供的public static long currentTimeMillis(),用于返回当前时间与1970年1月1日0时0分0秒的时间差,以毫秒为单位。

计算世界时间的主要标准有:

  • UTC: Coordinated Universal Time
  • GMT: Greenwich Mean Time
  • CST: Central Standard Time
java.util.Date类

表示特定的瞬间,精确到毫秒

  • 构造器
    • Date() 获取本地当前时间的Date对象
    • Date(long date) 创建指定毫秒数的Date对象
  • 常用方法
    • long getTime() 返回自1970年1月1日0时0分0秒 GMT 以来此Date对象表示的毫秒数,即时间戳
    • String toString() 把此对象转换为以下形式的String:dow(一周中的某一天) mon dd hh:mm:ss zzz(时间标准) yyyy

注意:很多方法已被废弃,因为不易于国际化

//构造器一:Date():创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString()); // Mon Jul 05 12:34:45 CST 2021

System.out.println(date1.getTime()); //1625459685618

//构造器二:创建指定毫秒数的Date对象
Date date2 = new Date(1625459685618L);
System.out.println(date2.toString());
java.util.Calendar类

Calendar是一个抽象基类,主要用于完成日期字段之间相互操作的功能。

获取Calendar实例的方法:

  • 调用Calendar.getInstance()
  • 调用子类GregorianCalendar构造器
    在这里插入图片描述

一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息,e.g.YEAR/MONTH/DAY_OF_WEEK/HOUR_OF_DAY/MINUTE/SECOND

  • void set(int field, int value)
  • void add(int field, int amount)
  • final Date getTime()
  • final void setTime(Date date)

注意

  • 获取月份时,范围是0-11
  • 获取星期时,以西方为准,即1是周日,7是周六
//1.实例化
//方式一:创建其子类(GregorianCalendar)的对象
//方式二:调用其静态方法getInstance()
Calendar calendar = Calendar.getInstance();
//        System.out.println(calendar.getClass());

//2.常用方法
//get()
int days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));

//set()
//calendar可变性
calendar.set(Calendar.DAY_OF_MONTH,22);
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days); // 22

//add()
calendar.add(Calendar.DAY_OF_MONTH,-3);  // 往前数3天
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);  // 19

//getTime():日历类---> Date
Date date = calendar.getTime();
System.out.println(date);

//setTime():Date ---> 日历类
Date date1 = new Date();
calendar.setTime(date1);
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
java.text.SimpleDateFormat类

该类是一个不与语言环境有关的方式来格式化和解析日期的具体类

它允许进行:

  • 格式化:Date => String

    • SimpleDateFormat() 默认的模式和语言环境创建对象
    • SimpleDateFormat(String pattern) 以pattern指定的格式创建对象
    • 通过SimpleDateFormat的实例调用方法String format(Date date)格式化时间对象date
    //实例化SimpleDateFormat:使用默认的构造器
    SimpleDateFormat sdf = new SimpleDateFormat();
    
    //格式化:日期 --->字符串
    Date date = new Date();
    System.out.println(date);
    
    String format = sdf.format(date);
    System.out.println(format);
    //按照指定的方式格式化:调用带参的构造器
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    //格式化
    String format1 = sdf1.format(date);
    System.out.println(format1);//2021-07-05 10:33:45
    
  • 解析:String => Date

    • Date parse(String source) 将给定字符串进行解析,生成一个日期对象
    //解析:格式化的逆过程,字符串 ---> 日期
    String str = "21-07-05 上午11:43";
    Date date1 = sdf.parse(str);
    System.out.println(date1);
    //解析:要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器参数体现),
    //否则,抛异常
    Date date2 = sdf1.parse("2021-07-05 10:33:45");
    System.out.println(date2);
    
    识别格式

在这里插入图片描述

JDK 8中新的API

JDK 8之前的API面临的问题:

  • 可变性:时间和日期这种类应该是不可变的
  • 偏移性:Date中的年份是从1900开始,而月份都从0开始
  • 格式化:只对Date有用,对Calendar无效
  • 非线程安全
  • 不能处理闰年

在JDK 8中吸收Joda-Time的精华,引入java.time系列API纠正了过去的缺陷,包括:

  • java.time 包含值对象的基础包
  • java.time.chrono 提供对不同的日历系统的访问
  • java.time.format 格式化和解析时间、日期
  • java.time.temporal 包括底层框架和扩展特性
  • java.time.zone 包含时区支持的类

常用的包就是基础包和format包。

常用的类包括:

  • 本地日期LocalDate
  • 本地时间LocalTime
  • 本地日期时间LocalDateTime
  • 时区ZonedDateTime
  • 持续时间Duration

此外,Date类中新增了toInstant()方法,用于把Date转换成新的表示形式。

LocalDate、LocalTime、LocalDateTime

这三个类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期时间,不包含当前的时间信息,也不包含与时区相关的信息。

ISO-8601日历系统是ISO指定的线代公民的日期和时间的表示法,即公历。

  • LocalDate代表ISO格式(yyyy-MM-dd)的日期,可以存储生日、纪念日等日期
  • LocalTime表示一个时间
  • LocalDateTime表示日期+时间,最常用
常用方法

在这里插入图片描述

/*
    LocalDate、LocalTime、LocalDateTime 的使用
    说明:
        1.LocalDateTime相较于LocalDate、LocalTime,使用频率要高
        2.类似于Calendar
 */
@Test
public void test1(){
    //now():获取当前的日期、时间、日期+时间
    LocalDate localDate = LocalDate.now();
    LocalTime localTime = LocalTime.now();
    LocalDateTime localDateTime = LocalDateTime.now();

    System.out.println(localDate);
    System.out.println(localTime);
    System.out.println(localDateTime);

    //of():设置指定的年、月、日、时、分、秒。没有偏移量
    LocalDateTime localDateTime1 = LocalDateTime.of(2021, 7, 6, 13, 23, 43);
    System.out.println(localDateTime1);


    //getXxx():获取相关的属性
    System.out.println(localDateTime.getDayOfMonth());
    System.out.println(localDateTime.getDayOfWeek());
    System.out.println(localDateTime.getMonth());
    System.out.println(localDateTime.getMonthValue());
    System.out.println(localDateTime.getMinute());

    //体现不可变性,改变属性不改变原有对象,会生成新对象
    //withXxx():设置相关的属性
    LocalDate localDate1 = localDate.withDayOfMonth(22);
    System.out.println(localDate);
    System.out.println(localDate1);


    LocalDateTime localDateTime2 = localDateTime.withHour(4);
    System.out.println(localDateTime);
    System.out.println(localDateTime2);

    //不可变性
    LocalDateTime localDateTime3 = localDateTime.plusMonths(3);
    System.out.println(localDateTime);
    System.out.println(localDateTime3);

    LocalDateTime localDateTime4 = localDateTime.minusDays(6);
    System.out.println(localDateTime);
    System.out.println(localDateTime4);
}
Instant

时间线上的一个瞬时点,可能被用来记录应用程序中的事件时间戳

java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间单位,表示时间线上的一个点,不需要任何上下文信息,精度可以达到纳秒级别。

时间戳是指格林威治时间1970年01月01号0时0分0秒(北京时间1970年01月01号8时0分0秒)起到当前时间的总秒数。(或以毫秒为单位)

1 ns = 10^-9 s

常用方法

在这里插入图片描述

/*
    Instant的使用
    类似于 java.util.Date类
 */
@Test
public void test2(){
    //now():获取本初子午线对应的标准时间
    Instant instant = Instant.now();
    System.out.println("instant = " + instant); // 2021-07-06T06:23:32.658Z

    //添加时间的偏移量
    OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
    System.out.println("offsetDateTime = " + offsetDateTime); // 2021-07-06T14:26:39.995+08:00

    //toEpochMilli():获取自1970年1月1日0时0分0秒(UTC)开始的毫秒数  ---> Date类的getTime()
    long milli = instant.toEpochMilli();
    System.out.println("milli = " + milli); // 1625552799995

    //ofEpochMilli():通过给定的毫秒数,获取Instant实例  -->Date(long millis)
    Instant instant1 = Instant.ofEpochMilli(1625552799995L);
    System.out.println("instant1 = " + instant1);  // 2021-07-06T06:26:39.995Z
}
DateTimeFormatter

java.time.format.DateTimeFormatter类提供了3种格式化方法,用于格式化与解析日期或时间:

  • 预定义的标准格式ISO_LOCAL_DATE_TIMEISO_LOCAL_DATEISO_LOCAL_TIME
  • 本地化相关的格式ofLocalizedDateTime(FormatStyle.LONG)
    • FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT 适用于LocalDate
    • FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT 适用于LocalDateTime
  • 自定义的格式(使用最多)ofPattern("yyyy-MM-dd HH:mm:ss")
常用方法

在这里插入图片描述

/*
    DateTimeFormatter:格式化或解析日期、时间
    类似于SimpleDateFormat
     */

@Test
public void test3(){
    // 方式一:预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
    DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
    // 格式化:日期-->字符串
    LocalDateTime localDateTime = LocalDateTime.now();
    String str1 = formatter.format(localDateTime);
    System.out.println("localDateTime = " + localDateTime);  // 2021-07-06T14:37:18.147
    System.out.println("str1 = " + str1); // 2021-07-06T14:37:18.147

    // 解析:字符串 -->日期
    TemporalAccessor parse = formatter.parse("2021-07-06T14:36:22.294");
    System.out.println("parse = " + parse);  // {},ISO resolved to 2021-07-06T14:36:22.294

    // 方式二:
    // 本地化相关的格式。如:ofLocalizedDateTime()
    // FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTime
    DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
    // 格式化
    String str2 = formatter1.format(localDateTime);
    // LONG:2021年7月6日 下午02时37分18秒
    // MEDIUM:2021-7-6 14:57:05
    // SHORT:21-7-6 下午2:57
    System.out.println("str2 = " + str2);

    // 本地化相关的格式。如:ofLocalizedDate()
    // FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 适用于LocalDate
    DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
    // 格式化
    String str3 = formatter2.format(LocalDate.now());
    // FULL:2021年7月6日 星期二
    // LONG:2021年7月6日
    // MEDIUM:2021-7-6
    // SHORT:21-7-6
    System.out.println("str3 = " + str3);

    //  重点: 方式三:自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
    DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    // 格式化
    String str4 = formatter3.format(LocalDateTime.now());
    System.out.println("str4 = " + str4); // 2021-07-06 14:37:18

    // 解析
    TemporalAccessor accessor = formatter3.parse("2021-07-06 14:36:22");
    System.out.println("accessor = " + accessor);  // {},ISO resolved to 2021-07-06T14:36:22
}
其他类
  • ZoneId 包含了所有的时区信息,一个时区的ID,格式为{区域}/{城市},e.g.Asia/Shanghai

    • ZoneId.getAvailableZoneIds() 获取所有的时区ID
    • ZoneId.of("xx/xxx") 获取指定时区的时间
  • ZonedDateTime 一个在ISON-8601日历系统时区的日期时间,e.g.2021-07-06T15:04:30+08:00 Asia/Shanghai

    • ZonedDateTime.now() 获取本时区的ZonedDateTime对象
    • ZonedDateTime.now(ZoneId.of("xx/xxx")) 获取指定时区的ZonedDateTime对象
  • Clock 使用时区提供对当前即时、日期和时间访问的时钟

  • Duration 持续时间,用于计算两个时间的间隔

    • static Duration between(LocalTime1/LocalDateTime1, LocalTime2/LocalDateTime2) 返回一个Duration对象,表示两个时间的间隔,可以通过getSeconds()/getNano()/toDays()来获取时间间隔
  • Period 日期间隔,用于计算两个日期的间隔,以年月日衡量

    • static Period between(LocalDate1, LocalDate2),返回一个Period对象,通过getYears()/getMonths()/getDays()来获取日期间隔
  • TemporalAdjuster 时间校正器

    // e.g. 获取当前日期的下一个周日是哪一天
    TemporalAdjuster ta = TemporalAdjusters.next(DayOfWeek.SUNDAY);
    LocalDateTime ldt = LocalDateTime.now().with(ta);
    // e.g. 获取下一个工作日是哪一天
    LocalDate ld = LocalDate.now().with(new TemporalAdjuster() {
       @Override
        public Temporal adjustInto(Temporal t) {
            LocalDate date = (LocalDate) t;
            if (date.getDayOfWeek().equals(DayOfWeek.FRIDAY)) {
                return date.plusDays(3);
            } else if (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) {
                return date.plusDays(2);
            } else {
                return date.plusDays(1);
            }
        }
    });
    
  • TemporalAdjusters 该类通过静态方法(firstDayOfXXX()/lastDayOfXXX()/nextXXX())提供了大量的常用TemporalAdjuster的实现

新旧API的转换

在这里插入图片描述

参考资料:全网最全Java零基础入门教程(含百道Java真题)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值