本文共 7672 字,大约阅读时间需要 25 分钟。
目录
一、java.time.LocalDateTime
1.1 基本使用
public static void main(String[] args){ LocalDate d = LocalDate.now(); // 当前日期 LocalTime t = LocalTime.now(); // 当前时间 LocalDateTime dt = LocalDateTime.now(); // 当前日期和时间 System.out.println(d); // 严格按照ISO 8601格式打印 System.out.println(t); // 严格按照ISO 8601格式打印 System.out.println(dt); // 严格按照ISO 8601格式打印 System.out.println("-----------------------"); LocalDateTime pdt = LocalDateTime.parse("2019-11-19T15:16:17"); LocalDate pd = LocalDate.parse("2019-11-19"); LocalTime pt = LocalTime.parse("15:16:17"); System.out.println(pdt); System.out.println(pd); System.out.println(pt);}
测试输出:
2019-10-29 11:54:32.796 2019-10-29T11:54:32.796 ----------------------- 2019-11-19T15:16:17 2019-11-19 15:16:17
从上述的测试可以发现:
1.LocalDateTime
、LocalDate
和LocalTime
默认严格按照规定的日期和时间格式进行打印。
ISO 8601规定的日期和时间分隔符是
T
。标准格式如下:
- 日期:yyyy-MM-dd
- 时间:HH:mm:ss
- 带毫秒的时间:HH:mm:ss.SSS
- 日期和时间:yyyy-MM-dd'T'HH:mm:ss
- 带毫秒的日期和时间:yyyy-MM-dd'T'HH:mm:ss.SSS
2. 通过指定的日期和时间创建LocalDateTime
可以通过of()
方法,of()方法有许多重载方式。
// 指定日期和时间:LocalDate d2 = LocalDate.of(2019, 11, 30); // 2019-11-30, 注意11=11月LocalTime t2 = LocalTime.of(15, 16, 17); // 15:16:17LocalDateTime dt2 = LocalDateTime.of(2019, 11, 30, 15, 16, 17);LocalDateTime dt3 = LocalDateTime.of(d2, t2);
3. 可以直接将标准格式的字符串传入LocalDateTime,调用parse()方法就可以直接解析。
1.2 加减调整
LocalDateTime
提供了对日期和时间进行加减和指定调整的的非常简单的链式调用:
public static void main(String[] args){ LocalDateTime dt = LocalDateTime.of(2019, 10, 26, 20, 30, 59); System.out.println("dt = " + dt); // 加6天减3小时: LocalDateTime dt2 = dt.plusDays(6).minusHours(3); System.out.println("dt2 = " + dt2); // 2019-11-01T17:30:59 // 减1月: LocalDateTime dt3 = dt.minusMonths(1); System.out.println("dt3 = " + dt3); // 2019-09-26T20:30:59 // 日期变为31日: LocalDateTime dt4 = dt.withDayOfMonth(31); System.out.println("dt4 = " + dt4); // 2019-10-31T20:30:59 // 月份变为9: LocalDateTime dt5 = dt.withMonth(9); System.out.println("dt5 = " + dt5); // 2019-09-26T20:30:59}
测试输出:
dt = 2019-10-26T20:30:59 dt2 = 2019-11-01T17:30:59 dt3 = 2019-09-26T20:30:59 dt4 = 2019-10-31T20:30:59 dt5 = 2019-09-26T20:30:59
从上述的测试可以发现:
1. 对日期的加减会自动调整月份,其实对月份的加减也会自动调整日期。
2. 对日期和时间的调整使用withXxx()方法,例如withHour(15)会把“10:11:12”变为“15:11:12”
调整年、月、日、时、分、秒的方法:
- 调整年:withYear()
- 调整月:withMonth()
- 调整日:withDayOfMonth()
- 调整时:withHour()
- 调整分:withMinute()
- 调整秒:withSecond()
1.3 复杂运算
实际上,LocalDateTime
还有一个通用的with()
方法允许我们做更复杂的运算:
public static void main(String[] args){ System.out.println("current date is " + LocalDate.now()); // 本月第一天0:00时刻: LocalDateTime firstDay = LocalDate.now().withDayOfMonth(1).atStartOfDay(); System.out.println(firstDay); // 本月最后1天: LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()); System.out.println(lastDay); // 下月第1天: LocalDate nextMonthFirstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth()); System.out.println(nextMonthFirstDay); // 本月第1个工作日: LocalDate firstWeekday = LocalDate.now().with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); System.out.println(firstWeekday); System.out.println("-----------------------"); LocalDateTime now = LocalDateTime.now(); System.out.println(now); LocalDateTime target = LocalDateTime.of(2019, 11, 19, 8, 15, 0); System.out.println(now.isBefore(target)); System.out.println(LocalDate.now().isBefore(LocalDate.of(2019, 11, 19))); System.out.println(LocalTime.now().isAfter(LocalTime.parse("08:15:00")));}
测试输出:
2019-10-01T00:00 2019-10-31 2019-11-01 2019-10-07 ----------------------- 2019-10-29T13:39:39.426 true true true
从上述的测试可以发现:
1. 要判断两个LocalDateTime
的时间先后,可以使用isBefore()
、isAfter()
方法。
2. LocalDateTime有许多with一类的方法,可以完成一些特定的操作。
1.4 区间间隔
Duration
表示两个时刻之间的时间间隔。另一个类似的Period
表示两个日期之间的天数:
public static void main(String[] args){ LocalDateTime start = LocalDateTime.of(2019, 11, 19, 8, 15, 0); LocalDateTime end = LocalDateTime.of(2020, 1, 9, 19, 25, 30); Duration d = Duration.between(start, end); System.out.println(d); // PT1235H10M30S Period p = LocalDate.of(2019, 11, 19).until(LocalDate.of(2020, 1, 9)); System.out.println(p); // P1M21D}
测试输出:
PT1235H10M30S P1M21D
从上述的测试可以发现:
1. 两个LocalDateTime
之间的差值使用Duration
表示,类似PT1235H10M30S
,表示1235小时10分钟30秒。
2. 两个LocalDate
之间的差值用Period
表示,类似P1M21D
,表示1个月21天。
3. Duration
和Period
的表示方法也符合ISO 8601的格式,它以P...T...
的形式表示,P...T
之间表示日期间隔,T
后面表示时间间隔。
二、java.time.ZonedDateTime
2.1 基本操作
LocalDateTime
总是表示本地日期和时间,要表示一个带时区的日期和时间,我们就需要ZonedDateTime
public static void main(String[] args){ // 默认时区 ZonedDateTime zbj = ZonedDateTime.now(); System.out.println(zbj); // 用指定时区获取当前时间 ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/New_York")); System.out.println(zny);}
测试输出:
2019-10-29T14:11:47.361+08:00[Asia/Shanghai] 2019-10-29T02:11:47.364-04:00[America/New_York]
从上述的测试可以发现:
1. ZonedDateTime和LocalDateTime一样,都是通过now()方法返回当前时间,只不过LocalDateTime没有时区信息。
public static void main(String[] args){ LocalDateTime ldt = LocalDateTime.of(2019, 9, 15, 15, 16, 17); System.out.println(ldt); ZonedDateTime zbj = ldt.atZone(ZoneId.systemDefault()); System.out.println(zbj); ZonedDateTime zny = ldt.atZone(ZoneId.of("America/New_York")); System.out.println(zny);}
测试输出:
2019-09-15T15:16:17 2019-09-15T15:16:17+08:00[Asia/Shanghai] 2019-09-15T15:16:17-04:00[America/New_York]
从上述的测试可以发现:
1. 给LocalDateTime附加一个ZoneId,就可以变为ZonedDateTime
2.2 时区转换
public static void main(String[] args){ // 以中国时区获取当前时间: ZonedDateTime zbj = ZonedDateTime.now(ZoneId.of("Asia/Shanghai")); System.out.println(zbj); // 转换为东京时间: ZonedDateTime zny = zbj.withZoneSameInstant(ZoneId.of("Asia/Tokyo")); System.out.println(zny); // 丢弃了时区信息 System.out.println(zny.toLocalDateTime());}
测试输出:
2019-10-29T14:47:04.234+08:00[Asia/Shanghai] 2019-10-29T15:47:04.234+09:00[Asia/Tokyo] 2019-10-29T15:47:04.234
从上述的测试可以发现:
1. 要转换时区,首先我们需要有一个ZonedDateTime
对象,然后,通过withZoneSameInstant()
将关联时区转换到另一个时区,转换后日期和时间都会相应调整。
2. 将ZonedDateTime转换为LocalDateTime时,直接丢弃时区信息。将LocalDateTime添加时区信息,就可以转换为ZonedDateTime了。
三、java.time.format.DateTimeFormatter
3.1 基本操作
public static void main(String[] args){ // 自定义格式化: DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); System.out.println(dtf.format(LocalDateTime.now())); // 用自定义格式解析: LocalDateTime dt2 = LocalDateTime.parse("2019/11/30 15:16:17", dtf); System.out.println(dt2);}
测试输出:
2019/10/29 11:27:08 2019-11-30T15:16:17
从上述的测试可以发现:
1. 对于自定义的日期时间格式,可以使用DateTimeFormatter来将其转换为ISO 8601格式。
2. 当我们直接调用System.out.println()
对一个ZonedDateTime
或者LocalDateTime
实例进行打印的时候,实际上,调用的是它们的toString()
方法,默认的toString()
方法显示的字符串就是按照ISO 8601
格式显示的。
四、java.time.Instant
4.1 基本操作
public static void main(String[] args) { Instant now = Instant.now(); System.out.println(now.getEpochSecond()); // 秒 System.out.println(now.toEpochMilli()); // 毫秒 System.out.println(System.currentTimeMillis());}
测试输出:
1572334867 1572334867288 1572334867288
从上述的测试可以发现:
1. 用Instant.now()
获取当前时间戳,效果和System.currentTimeMillis()
类似,只是多了更高精度的纳秒。
2. toEpochMilli()表示获取毫秒值时间戳,完全等同于System.currentTimeMillis()
时间戳是一个不断递增的整数,没有时区属性;对Instance附加一个时区,就可以创建出ZonedDateTime:
public static void main(String[] args){ // 以指定时间戳创建Instant: Instant ins = Instant.ofEpochMilli(1572334867288L); ZonedDateTime zdt = ins.atZone(ZoneId.systemDefault()); System.out.println(zdt); // 2019-10-29T15:41:07.288+08:00[Asia/Shanghai]}
测试输出:
2019-10-29T15:41:07.288+08:00[Asia/Shanghai]
从上述的测试可以发现:
1. 对于某一个时间戳,给它关联上指定的ZoneId
,就得到了ZonedDateTime
,继而可以获得了对应时区的LocalDateTime
2. LocalDateTime
,ZoneId
,Instant
,ZonedDateTime
和long
都可以互相转换的。
3. Instant
表示高精度时间戳,它可以和ZonedDateTime
以及long
互相转换。
转载地址:https://blog.csdn.net/WXS_0218/article/details/102796188 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!