下面是我必须打印当前EST日期时间的代码,但它在我的时区打印出时间,即亚利桑那时间。我在这段代码中遗漏了什么。谢谢!
public static void main(String args[]) {
LocalDateTime datetime = LocalDateTime .now();
ZonedDateTime zdtNewYork = ZonedDateTime.of ( datetime , ZoneId.of ( "America/New_York" ) );
System.out.println(zdtNewYork.format(DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SSS")));
}
你捕获了亚利桑那州的日期和时间,然后拍了一个时区来声称(错误地)纽约在那一刻有相同的时间。
因此,当您生成显示这些值的文本时,您会看到在亚利桑那州首次捕获的时间。在任何时候你都没有从亚利桑那州调整到纽约。
LocalDateTime
is the wrong class切勿使用LocalDateTime
来跟踪时刻。根据定义,该类不能代表特定时刻,即时间轴上的一个点。它包含日期和时间,但缺少时区或从UTC偏移的上下文。如果我们不知道你是在日本东京,加尔各答印度,巴黎法国还是蒙特利尔魁北克中旬,那么“在今年1月23日中午”告诉我们是没有意义的 - 所有这些都是非常不同的时刻,相隔几小时。
为了使用错误的类,您调用了LocalDateTime.now
而未指定时区。因此,隐式应用了JVM的当前默认时区。您声称默认值是亚利桑那州的某个时区。所以这将是区域应用。
因此,您捕获了亚利桑那州的日期和时间。但是你丢弃了这个值在亚利桑那州时区的事实,因为你使用了LocalDateTime
。丢弃时区是LocalDateTime
类的全部要点。有些情况下这很有用,但肯定不适合你的情况。
然后你拿走了亚利桑那州的日期和时间,并声称这是纽约的日期和时间。纽约的实际时间比预先提前了几个小时,所以你告诉了一下。最后,您生成了显示fib的文本。
换句话说,显然你认为这一行:
ZonedDateTime.of ( datetime , ZoneId.of ( "America/New_York" ) )
...从亚利桑那州调整到纽约。但datetime
论证不再知道它来自亚利桑那州,因为LocalDateTime
没有区域/偏移的概念。没有进行任何调整。
你可以这样想:
LocalDateTime
=日期+时间
OffsetDateTime
=日期+时间+偏移量
ZonedDateTime
=日期+时间+区域
Instant
=日期+时间+ UTC
相反,我建议您始终明确指定所需/预期的时区。即使您想要当前的默认时区,也可以通过调用ZoneId.systemDefault
明确说明,这样任何阅读代码的程序员都清楚地了解您的意图。让时区或从UTC偏移是可选的是我在java.time中发现的其他惊人的类设计中要改变的少数几件事之一。使所需的区域/偏移量参数有助于教育更多程序员关于日期时间处理。
ZonedDateTime
is the right class要表示通过特定区域(时区)的人使用的挂钟时间看到的时刻,请使用ZonedDateTime
。
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
看到这个code run live at IdeOne.com。
zdt.toString():2019-03-04T18:17:08.014-05:00 [America / New_York]
我们可以轻松生成您想要的文本。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu HH:mm:ss.SSS" ) ;
String output = zdt.format( f ) ;
看到这个code run live at IdeOne.com。
03/04/2019 18:17:08.014
如果您确实想要在区域之间进行调整,请调用ZonedDateTime::withZoneSameInstant
方法。
ZonedDateTime zdtPhoenix = ZoneDateTime.now( ZoneId.of( "America/Phoenix" ) ) ;
ZonedDateTime zdtNewYork = zdtPhoenix.withZoneSameInstant( ZoneId.of( "America/New_York" ) ) ; // Same moment, same point on the timeline, different wall-clock time.
注意短语SameInstant
意味着你想要相同的时刻,时间轴上的同一个点,但是你想要通过纽约地区人们使用的挂钟时间看到它。
打印出当前的EST日期时间
以proper time zone name的格式指定Continent/Region
,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用或引用2-4字母缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
尝试类似的东西:
LocalDateTime datetime = LocalDateTime .now(ZoneId.of ( "America/New_York" ));
System.out.println(datetime.format(DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SSS")));