And*_*ues 10 java time date java-8
我默认使用时区巴西,但是当捕获到纽约的一个LocalDateTime并转换为java.tim.Instant时,即时填充正确.问题是当我尝试使用Date.from(instantValue)生成一个Date,而不是生成纽约的日期时,我最终得到了来自巴西的当前日期.
ZoneId nyZone = ZoneId.of("America/New_York");
ZoneId brazilZone = ZoneId.of("America/Recife");
LocalDateTime ldtBrazil = LocalDateTime.now(brazilZone);
LocalDateTime ldtNY = LocalDateTime.now(nyZone);
Instant instantBrazil = ldtBrazil.toInstant(ZoneOffset.UTC);
Instant instantNY = ldtNY.toInstant(ZoneOffset.UTC);
System.out.println("-------LocalDateTime-------");
System.out.println("ldtBrazil : "+ldtBrazil);
System.out.println("ldtNY : "+ldtNY);
System.out.println("\n-------Instant-------");
System.out.println("instantBrazil: "+instantBrazil);
System.out.println("instantNY : "+instantNY);
long milliBrazil = instantBrazil.toEpochMilli();
long milliNY = instantNY.toEpochMilli();
System.out.println("\n----------Milli----------");
System.out.println("miliBrazil : "+milliBrazil);
System.out.println("miliNY : "+milliNY);
Date dateBrazil = Date.from(instantBrazil);
Date dateNY = Date.from(instantNY);
System.out.println("\n---------Date From Instant---------");
System.out.println("dateBrazil: "+dateBrazil);
System.out.println("dateNY : "+dateNY);
System.out.println("\n---------Date From Milli---------");
System.out.println("dateBrazil: "+new Date(milliBrazil));
System.out.println("dateNY : "+new Date(milliNY));
Run Code Online (Sandbox Code Playgroud)
结果
-------LocalDateTime-------
ldtBrazil : 2016-09-21T22:11:52.118
ldtNY : 2016-09-21T21:11:52.118
-------Instant-------
instantBrazil: 2016-09-21T22:11:52.118Z
instantNY : 2016-09-21T21:11:52.118Z
----------Milli----------
miliBrazil : 1474495912118
miliNY : 1474492312118
---------Date From Instant---------
dateBrazil: Wed Sep 21 19:11:52 BRT 2016
dateNY : Wed Sep 21 18:11:52 BRT 2016 //this data must be related to NY LocalDateTime, but reiceved a same date of Brazil.
---------Date From Milli---------
dateBrazil: Wed Sep 21 19:11:52 BRT 2016
dateNY : Wed Sep 21 18:11:52 BRT 2016
Run Code Online (Sandbox Code Playgroud)
Bas*_*que 20
LocalDateTime 意味着没有区域你似乎误解了目的LocalDateTime.
此类没有时区,也没有来自UTC的偏移量.这不是时间表上的一点.相反,它代表了一个关于可能时刻的模糊概念.命名为"本地..."可能是违反直觉的,因为它不会不表示任何特定地区,而是任何地方.
例如,今年的圣诞节是2016年12月25日的午夜,或者2016-12-25T00:00.这是没有意义的,除非您在新西兰奥克兰或加尔各答IN或巴黎FR或蒙特利尔加利福尼亚州申请圣诞节,每个时间轴都是时间轴上的不同点,随后越往西方.
永远不要使用,LocalDateTime因为您认为它将为您节省区域和抵消的麻烦.恰恰相反,你会把自己挖到一个带有模糊日期时间值的洞里.
您的大多数业务逻辑,日志记录,数据存储和数据交换都应该是UTC.将UTC视为一个真实的时间; 所有其他区域和抵消都伪装成打扮的UTC值.
在java.time中,这意味着Instant该类是您的首选类,即日期时间对象的基本构建块.该Instant级表示时间轴上的时刻UTC,分辨率为纳秒.
Instant now = Instant.now();
Run Code Online (Sandbox Code Playgroud)
ZonedDateTime仅在需要访问某些区域的挂钟时间时调整到时区.应用a ZoneId来获取ZonedDateTime对象.
ZoneId zNewYork = ZoneId.of("America/New_York");
ZoneId zRecife = ZoneId.of("America/Recife");
ZonedDateTime zdtNewYork = now.atZone( zNewYork );
ZonedDateTime zdtRecife = now.atZone( zRecife );
Run Code Online (Sandbox Code Playgroud)
所有这三个对象,now,zdtNewYork,和zdtRecife,是所有非常某一时刻,在时间轴上的相同点同时进行.这三个人共享同一个时代.唯一的区别是我们看到他们的挂钟时间的镜头.
避免使用与最早版本的Java捆绑在一起的麻烦的旧日期时间类.所以,避免java.util.Date和java.util.Calendar.他们真的那么糟糕.坚持使用java.time类.
如果必须与尚未针对java.time类型更新的旧代码进行交互,则可以转换为/来自java.time类型.寻找添加到旧类的新方法.该java.util.Date.from方法需要一个Instant.我们可以Instant从ZoneDateTime(或从OffsetDateTime)中提取.
java.util.Date utilDate = java.util.Date.from( zdtNewYork.toInstant() );
Run Code Online (Sandbox Code Playgroud)
走向另一个方向.
Instant instant = utilDate.toInstant();
Run Code Online (Sandbox Code Playgroud)
有关转换的更多信息,请参阅我对问题的回答,将java.util.Date转换为"java.time"类型?
避免使用从历史算起的数字,例如自1970年以来的UTC开始的毫秒数.计数有多种粒度(毫秒,微秒,纳秒,整秒等).除了1970年以外,各种计算机系统至少使用了十几个时代.这些数字在人类阅读时没有任何意义,因此可能无法检测到错误.
你可能会发现它们在练习时很有用.呼叫getEpochSecond和getNano打开Instant,或截断值呼叫toEpochMilli.
该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.
现在处于维护模式的Joda-Time项目建议迁移到java.time类.
要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.
您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*
从哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.
在我看来,你对a LocalDateTime和Instanta 之间的区别感到困惑(或者a 与a Date基本相同Instant).这些是完全不同的对象.
A LocalDateTime是特定的日历日期和特定的时钟时间.你可以把它想象成这张照片.
或者您可以将其视为年,月,日,小时,分钟和秒.但它没有时区.这就是日历所说的以及时钟所说的内容.
安Instant是一个时刻.例如,尼尔阿姆斯特朗第一次踏上月球的那一刻可以表现为一个Instant.JFK拍摄的那一刻也是如此.
再一次,没有时区.但它与a不同LocalDateTime.你不能写下什么时间,Instant除非你知道写下来的时区.哦,和a Date是一回事Instant.
因此,要在a LocalDateTime和a之间进行转换Instant,需要引用特定的时区.所以要表达尼尔阿姆斯特朗作为一年,一个月,一个月,一小时,一分钟和一秒钟登上月球的那一刻; 你需要知道使用什么时区.如果你使用UTC,那是1969年7月21日凌晨2点56分.如果你使用太平洋标准时间,那是1969年7月20日下午6点56分.
有了这些知识,让我们分析你的代码.你开始使用几个LocalDateTime对象.
现在,您使用UTC将这些转换为Instant对象.
然后你打印出来.我们需要知道一个时区才能做到这一点,但那没关系.一个Instant被印在UTC,不管是什么.这就是Z意味着什么.
现在,您将Instant对象转换为毫秒数.精细.这是自1970年1月1日午夜UTC以来的毫秒数.milliNY显然比milliBrazil少360万,因为它相当于Instant一小时前的一个.
然后将Instant对象转换为Date对象.这并没有真正改变任何东西,因为a Date和a Instant代表相同的东西,即使它们以不同方式打印出来.
您打印出那些转换的Date对象.他们在巴西时间打印,因为那是你的地方.它恰好dateNY比一小时前发生的那样dateBrazil; 但它们仍然在巴西时间打印,比UTC时间晚三个小时.所以你分别得到19:11:52和18:11:52.
最后,您Date从毫秒数开始制作几个对象.但是这些新Date对象dateBrazil与dateNY您已经拥有的对象完全相同,因为您使用相同的毫秒数制作它们.再次,他们在巴西时间印刷.
| 归档时间: |
|
| 查看次数: |
19536 次 |
| 最近记录: |