我想使用Java 8 Date Time API从亚洲/加尔各答的时间计算亚洲/迪拜时区的时间 [英] I want to calculate time in Asia/Dubai timezone from the time of Asia/Kolkata using java 8 Date Time API

查看:105
本文介绍了我想使用Java 8 Date Time API从亚洲/加尔各答的时间计算亚洲/迪拜时区的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 ZoneId dubai = ZoneId.of("Asia/Dubai");
 LocalDate localDate = LocalDate.now();
 LocalTime localTime = LocalTime.now();
 ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate, localTime, dubai);
System.out.println("Dubai Tiime:"+zonedDateTime);

上面的代码仍在打印我当前所在区域(即亚洲/加尔各答)的时间

Above code is still printing the time of my current zone (i.e Asia/Kolkata)

我也尝试使用以下代码来实现相同的功能,但是它也在我当前所在的区域(亚洲/加尔各答)中打印时间:

Also i tried the following code to achieve the same but it is also printing time in my current zone(Asia/Kolkata):

ZoneOffset offset = ZoneOffset.of("+04:00");
LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime plusFour = OffsetDateTime.of(localDateTime, offset);
System.out.println("Dubai Time :"+plusFour);

我无法弄清楚为什么它不能提供理想的结果.

I am unable to figure out why its not providing desired result.

推荐答案

Kokorin的答案是正确的.这里还有更多讨论.

The answer by Kokorin is correct. Here's a bit more discussion.

当您调用now方法并且未传递任何参数时,您无法指定时区.因此,java.time在确定当前本地时间和当前本地日期时默默地应用了JVM的当前默认时区.

When you called the now method and passed no arguments, you failed to specify a time zone. In that omission, java.time silently applied your JVM’s current default time zone in determining the current local time and current local date.

您声称JVM的当前默认时区为Asia/Kolkata(印度时间).如果您在办公室运行该代码的时间是15:30,那么您的代码是在说让我以15:30的时间作为输入,以表示

You claim your JVM’s current default time zone is Asia/Kolkata (India time). If when you ran that code it was 15:30 time in your office, your code is saying "let's take my 15:30 and use that as input to represent a wall-clock time in Dubai". So while the current moment in Dubai was actually 14:00 (an hour and half closer to UTC than India I presume, not sure), you created a date-time for an hour and a half in the Dubai’s future: 15:30.

当您在行ZonedDateTime.of( localDate, localTime, dubai )中通过dubai时,您假设您是在要求时区之间进行调整.但是实际上您是在分配一个时区到一个简单的(本地")日期和时间,而根本没有时区.所有三个 Local…类内部没有存储时区;它们的目的是忽略时区.您的代码与您的意图不符.

When you passed dubai in the line ZonedDateTime.of( localDate, localTime, dubai ) you assumed you were asking for an adjustment between time zones. But in fact you were assigning a time zone to a plain ("Local") date and time that had no time zone at all. All three of the Local… classes store no time zone internally; their very purpose is to ignore time zone. Your code did not match your intentions.

请注意,在此版本的代码中,我如何传递您的

Note how in this revision to your code I pass your ZoneId object to both now methods. This would solve your problem.

    ZoneId dubai = ZoneId.of ( "Asia/Dubai" );
    LocalDate localDate = LocalDate.now ( dubai );  
    LocalTime localTime = LocalTime.now ( dubai ); // Capturing `14:00` in Dubai rather than than `15:30` in India as in your version of code.
    ZonedDateTime zonedDateTime = ZonedDateTime.of ( localDate , localTime , dubai );
    System.out.println ( "Dubai Tiime:" + zonedDateTime );

但这仍然是错误的代码.如果这对.now方法是在午夜时分调用的,则您将获得非常错误的信息(关闭大约24小时).

But this is still bad code. If those pair of .now methods were called over the stroke of midnight, you would have very wrong information (off by about 24 hours).

相反,您应该自动捕获当前时刻.使用用户Kokorin的代码,或使用下面显示的我的代码.

Instead you should capture the current moment atomically. Either user Kokorin's code, or use my code shown next.

Instant是UTC时间线上的时刻,分辨率为纳秒

An Instant is a moment on the timeline in UTC with a resolution of nanoseconds.

Instant instant = Instant.now();
ZoneId zoneId_Dubai = ZoneId.of( "Asia/Dubai" );
ZonedDateTime zdt_Dubai = ZonedDateTime.ofInstant( instant , zoneId_Dubai );

作为快捷方式,调用静态方法

As a shortcut, call the static method ZonedDateTime.now.

ZonedDateTime zdt_Dubai = ZonedDateTime.now( zoneId_Dubai );

要查看同一时刻,但要使用自己的壁钟时间,请调整为印度时间.

To see the same moment but with your own wall-clock time, adjust into India time.

ZonedDateTime zdt_Kolkata = zdt_Dubai.withZoneSameInstant( ZoneId.of( "Asia/Kolkata" ) );

大提示: 始终传递可选的时区参数.尽管我非常尊重java.time的工作,但我认为使时区参数在各种方法上可选为设计缺陷. JVM当前默认时区的无提示隐式应用程序对于许多程序员来说很容易陷入陷阱.顺便说一下, Locale ,请始终指定.

BIG TIP: Always pass the optional time zone arguments. While I tremendously respect the work that went into java.time, I consider making the time zone arguments optional on various methods to be a design flaw. The silent implicit application of your JVM’s current default time zone is just too easy a trap to fall into for so many programmers. By the way, ditto for Locale, always specify.

另一个提示: 思考,工作并存储在 UTC中.作为一名程序员,您必须学会在UTC上思考,让自己摆脱我在加尔各答的时光"和他们在迪拜的时光".您将使自己发疯,并使您的大脑受伤.在编程时,要知道唯一的真实时间是UTC .迪拜/加尔各答/蒙特利尔/奥克兰的其他所有时间都是烟和镜子,仅是幻觉.在您的大部分代码中使用Instant类,在进行日期/时间工作时将其设置为转到"类(仅对用户显示时区).在数据库中使用UTC.进行UTC登录.将您的服务器保持在UTC(或冰岛)时区.在将日期时间值序列化以存储或进行数据交换时,请使用UTC(并使用 ISO 8601 格式化顺便说一句).在桌上或显示UTC的屏幕上保持时钟.稍后,当您下班回家时,您可以回到自己当地的印度时光"思维中.

Another Tip: Think, work, and store in UTC. As a programmer you must learn to think in UTC, get your head out of "my time in Kolkata" and "their time in Dubai". You will drive yourself crazy and make your brain hurt. While programming, know that the only one true time is UTC. All the other Dubai/Kolkata/Montréal/Auckland times are smoke and mirrors, mere illusions. Use the Instant class in much of your code, make it your "go to" class when doing date-time work (only apply a time zone for display to the user). Use UTC in your database. Do your logging in UTC. Keep your servers on UTC (or Iceland) time zone. Use UTC when serializing date-time values to storage or in data-exchange (and use ISO 8601 formats btw). Keep a clock on your desk or screen displaying UTC. Later, when you go home from work, then you can slip back into your own local "India time" thinking.

这篇关于我想使用Java 8 Date Time API从亚洲/加尔各答的时间计算亚洲/迪拜时区的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆