三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

中级——新版日期类

中级——新版日期类

Java8后,增设了四种表示日期的类
LocalDate: 表示没有时间部分的日期(年、月、日)例如:2024-04-27
LocalTime: 表示没有日期部分的时间(时、分、秒、纳秒)例如:14:30:00
LocalDateTime: 表示日期和时间的组合(没有时区信息)例如:2024-04-27T14:30:00
ZonedDateTime: 表示带有时区的日期和时间,例如:2024-04-27T14:30:00+08:00[Asia/Shanghai]

LocalDate类(表示日期)

不同的创建方法
LocalDate date = LocalDate.now();  //需要使用其内部的静态方法创建对象
LocalDate date1 = LocalDate.of(2025, 10, 11);  //按年月日创建所见即所得
LocalDate date2 = LocalDate.of(2025, Month.AUGUST, 18);   //同上,按年月日创建
LocalDate date3 = LocalDate.ofYearDay(2025, 240);   //直接取2025年的第240天
System.out.println(date);类中方法
System.out.println("月份: " + date.getMonth());
System.out.println("月份数字: " + date.getMonthValue());
System.out.println("年份: " + date.getYear());
System.out.println("今年的第几天: " + date.getDayOfYear());
System.out.println("这个月的第几天: " + date.getDayOfMonth());
System.out.println("这周的第几天: " + date.getDayOfWeek());还能通过plus与minus增减天数、月数等,但LocalDate本身的日期是不可变的,
我们进行加减操作之后得到的结果是对于原对象的拷贝重新生成的对象,
包括我们如果想要单独修改年月日,也只能使用with方法来创建副本

LocalTime类(表示时间)

支持用静态方法或直接使用内置的静态变量
LocalTime time = LocalTime.now();   //现在的时间
LocalTime time1 = LocalTime.of(12, 30);   //指定时分
LocalTime time2 = LocalTime.of(12, 30, 0);   //指定时分秒
LocalTime time3 = LocalTime.of(12, 30, 0, 0);  //指定时分秒以及纳秒(注意不是毫秒)
LocalTime time4 = LocalTime.MAX;   //LocalTime最大支持时间,也是即将到达下一天的最大时间23:59:59.999
LocalTime time5 = LocalTime.MIN;   //LocalTime最小支持时间,也是一天开始的时间0:00:00.000
LocalTime time6 = LocalTime.MIDNIGHT;   //同上,午夜,也就是一天开始的时间0:00:00.000
LocalTime time7 = LocalTime.NOON;    //中午,12:00:00.000
//仅能代表某时刻,不包含日期类中方法
LocalTime time = LocalTime.now();
System.out.println("小时: " + time.getHour());
System.out.println("分钟: " + time.getMinute());
System.out.println("秒: " + time.getSecond());其增减时间、修改时刻的操作与LocalDate类相同,且原理相同

LocalDateTime类

LocalDateTime time = LocalDateTime.now();
LocalDateTime time2 = LocalDateTime.of(LocalDate.now(), LocalTime.now()); //融合两个对象
LocalDateTime time3 = LocalDateTime.of(2025, 10, 1, 23, 18, 0);  //年月日时分秒该类为二者结合,方法更全,而上述两类也内置了补全日期或时刻的方法
LocalDate date = LocalDate.now();
System.out.println(date.atTime(LocalTime.now()));  //补齐时分秒
System.out.println(date.atTime(12, 0, 0)); //补齐时分秒LocalTime time = LocalTime.now();
System.out.println(time.atDate(LocalDate.of(2025, 1, 1)));  //补齐年月日LocalDateTime time = LocalDateTime.now();
time.toLocalTime(); 
time.toLocalDate();

DateTimeFormatter(格式化时间)

用法和之前的SimpleDateFormat类似,如果我们需要将字符串日期进行转换,可以像这样做:
//首先创建日期格式化工具
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//使用parse指定格式进行转换
LocalDateTime now = LocalDateTime.parse("2025-01-01 01:18:22", formatter);
System.out.println(now);也可以直接通过SimpleDateFormat进行转换,会返回一个TemporalAccessor类型的对象,它是我们之前认识的几种日期对象的公共父接口,但是注意,它的具体实现类并不是我们想要的类型,而是其他的实现类,不过日期类同样有对应的from转换方法:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime time = LocalDateTime.from(formatter.parse("2025-01-01 01:18:22"));
//使用from转换返回的TemporalAccessor为对应日期对象如果要把日期转换为格式化的字符串,也是和之前一样的,直接使用format方法即可:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(formatter.format(LocalDateTime.now()));

OffsetDateTime(具有偏移值,内部保存时区)

其他类型在创建时也能添加时区
LocalDate date = LocalDate.now(ZoneId.of("UTC+0"));  //直接指定UTC时区
LocalDateTime time = LocalDateTime.now(ZoneId.of("UTC+0"));
OffsetDateTime offset = OffsetDateTime.now(ZoneId.of("UTC+0"));之前几种时间类型允许传入时区,生成出来的时间也确实是对应时区的时间,但是其中不会保存有关时区的设置,得到的只是对应时区的时间,而OffsetDateTime内部会保存时区,我们可以通过getOffset()获取:
OffsetDateTime offset = OffsetDateTime.now(ZoneId.of("UTC+5"));
//返回一个ZoneOffset对象,包含时间偏移量信息
System.out.println(offset.getOffset());  //当时区为UTC标准时区打印Z,其他时间打印+05:00这种
时间偏移量可精确到秒
OffsetDateTime offset = OffsetDateTime.now(ZoneId.of("UTC+05:00:02"));
System.out.println(offset);  //2025-07-08T15:52:39.926356+05:00:02

ZonedDateTime类(包含时区信息,如ID等)

ZonedDateTime time = ZonedDateTime.now();
ZonedDateTime time = LocalDateTime.now().atZone(ZoneOffset.UTC);  //LocalDateTime补全时区信息
System.out.println(time);默认的时区为系统设定的时区,我们也可以手动指定其他地区。我们可以打印看下当前时区信息:
ZonedDateTime time = ZonedDateTime.now();
System.out.println(time.getZone());

Instant类(时间戳)

Instant instant = Instant.now();
Instant.ofEpochSecond(1);  //也可以通过时间点创建,这里是1970-01-01 0:00:01
Instant.ofEpochSecond(0, 1);  //可以精确到纳秒
System.out.println(instant);
从打印结果可以看到,其输出默认为格林威治时间,而不是根据当前系统时区展示,所以确实很像是只表示时间戳,而非给我们当做时间对象使用的,并且它的内部不存在任何获取日期时间信息的方法,像是一个砍掉所有功能只用于保存时间的LocalDateTime对象。对于我们之前使用的Date对象,在Java8之后同样也可以快速转换为Instant对象:
Date date = new Date();
Instant instant = date.toInstant();

During与Period类(时间差)

Duration duration = Duration.ofSeconds(1);   //表示相差时间1秒
Duration.between(LocalTime.now(), LocalTime.now().plusDays(1));  //通过between来计算两个时间的差值
Period period = Period.ofDays(1);   //表示相差时间1天
其中,Duration用于计算时间更精确的差值,精确到秒和纳秒,而Period用于粗略计算差值,精确到天。
← 返回列表