java中的时间与时区:LocalDateTime和Date

Posted mosakashaka

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中的时间与时区:LocalDateTime和Date相关的知识,希望对你有一定的参考价值。

LocalDateTime

LocalDateTime本身不包含时区信息,它存储的是年、月、日、时分秒,纳秒这样的数字。
在不同的时区下,这样的数字代表不同的时间。

比如一个LocalDateTime存储2020-01-01 08:00:00,这里省略纳秒。
对北京和东京的人来看这个时间,都认为是本地时间的话,在真实时间上,因为时区的差异,其实是相差1个小时的时间的。

构造函数

既然不带时区,那么考虑LocalDateTime的构造函数:

LocalDateTime dtUtc = LocalDateTime.now(ZoneOffset.UTC);

为什么这里又有时区了呢?其实这是一个方便的方法:

如果只是为了获取当前系统所在默认时区的一个本地时间,那么用LocalDateTime.now()无参数构造方法即可,而如果我想知道现在在UTC时区那里本地显示的是什么时间,就可以用LocalDateTime.now(ZoneOffset.UTC)这个构造方法了。

所以对于我们东八区来说:


//假如这个时间是:2020-01-01 10:00:00
LocalDateTime dtLocal = LocalDateTime.now();

//那么这个时间就会存储:2020-01-01 02:00:00,提前8个小时
LocalDateTime dtUtc = LocalDateTime.now(ZoneOffset.UTC);

在构造后,LocalDateTime同样不携带时区信息,仍然只是表示一个显示时间而已。

Date

Date存储的是一个毫秒数,准确说是从1970-01-01 00:00:00到现在经过的毫秒数。
而这个毫秒数是有时区的,它存储的永远是现在针对UTC时区时的1970年零点,经过的毫秒数。怎么理解?

比如两个程序员在同一时刻,一个在英国,一个在中国,同时调用new Date(),那么此时Date中存储的毫秒数是完全相同的(当然是理想情况的同时,以及系统没有误差)。所不同的是在输出时,GMT0时区,直接使用这个毫秒数计算得到显示时间,而北京GMT+8显示时,会在这个时间上增加8小时,即时区偏移。

所以如下两个格式化类型,在当前东八区的使用场景,输出实际是一样的:

        SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     // 北京
        bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));  // 设置北京时区

      SimpleDateFormat dftSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     // 不设置时区

构造

因为Date有时区信息,所以构造Date也就需要时区信息。
因此,不能直接从LocalDateTime转换成Date,因为无法确定这个LodalDateTime究竟是哪个时区的这个时间。
而要借助Instant,因为Instant也代表从UTC开始的一个偏移时间。

LocalDateTime dt  = LocalDateTime.now();
Date dt2 = Date.from(dt.toInstant(ZoneOffset.of("+8"))); //东八区

输出






以上是关于java中的时间与时区:LocalDateTime和Date的主要内容,如果未能解决你的问题,请参考以下文章

Java日期时间API系列19-----Jdk8中java.time包中的新的日期时间API类,ZonedDateTime与ZoneId和LocalDateTime的关系,ZonedDateTime格

在数据库中使用Java 8 LocalDate和LocalDateTime进行Hibernate

Spring boot:JSON将带有时区的日期和时间反序列化为LocalDateTime

Java ZonedDateTime转换成 LocalDateTime方法代码及之间区别

Java8 日期和时间实用技巧

Java日期时间API系列20-----Jdk8中java.time包中的新的日期时间API类,ZoneId时区ID大全等。