如何在 Java 中使用 DateTimeZone

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20615288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:08:52  来源:igfitidea点击:

How to use DateTimeZone in Java

javajodatime

提问by abiieez

I've been trying to convert a server's date and time to user's one with the following code

我一直在尝试使用以下代码将服务器的日期和时间转换为用户的日期和时间

@Test
public void playingWithJodaTime() {

    LocalDateTime localDateTime = new LocalDateTime();
    System.out.println("server localDateTime : "
            + localDateTime.toDateTime(DateTimeZone.getDefault()).toDate());
    System.out.println("user's localDateTime : "
            + localDateTime.toDateTime(DateTimeZone.forID("Asia/Jakarta"))
                    .toDate());
}

Printed result

打印结果

server localDateTime : Tue Dec 17 00:04:29 SGT 2013
user's localDateTime : Tue Dec 17 01:04:29 SGT 2013

However the printed result is not like what I expected since the server time zone is (UTC+08:00) Kuala Lumpur, Singaporewhile the user's is (UTC+07:00) Bangkok, Hanoi, Jakarta.

但是,打印的结果与我预期的不同,因为服务器时区是(UTC+08:00) Kuala Lumpur, Singapore用户的(UTC+07:00) Bangkok, Hanoi, Jakarta.

What did I do wrong here ?

我在这里做错了什么?

采纳答案by Ilya

You are converting DateTimeto java Date(why?).
java.util.Dateuses default JVM's time zone
So, you missed time zone at this conversion.

您正在将DateTime转换为 java Date(为什么?)。
java.util.Date使用默认 JVM 的时区
因此,您在此转换中错过了时区。

This example works as expected:

此示例按预期工作:

LocalDateTime localDateTime = new LocalDateTime();
System.out.println("server localDateTime : "
        + localDateTime.toDateTime(DateTimeZone.getDefault()));
System.out.println("user's localDateTime : "
        + localDateTime.toDateTime(DateTimeZone.forID("Asia/Jakarta")));  

if you want to convert joda DateTime to something else, then convert it to Calendar

如果要将 joda DateTime 转换为其他内容,则将其转换为Calendar

  LocalDateTime localDateTime = new LocalDateTime();
  System.out.println("server localDateTime : "
        + localDateTime.toDateTime(DateTimeZone.getDefault()).toGregorianCalendar());
  System.out.println("user's localDateTime : "
        + localDateTime.toDateTime(DateTimeZone.forID("Asia/Jakarta")).toGregorianCalendar());

回答by cyon

A LocalDateTimerepresents a datetime withouta time zone.

ALocalDateTime表示没有时区的日期时间。

By calling toDateTime(DateTimeZone)you enrich the LocalDateTimewith the provided timezone to get a DateTimewhich has the same date and time as the original LocalDateTimebut is associated with the provided timezone. Note that you do not convert when calling toDateTime, because the original local datetime does not have an associated timezone.

通过调用toDateTime(DateTimeZone)LocalDateTime使用提供的时区来丰富以获取DateTime与原始时区具有相同日期和时间LocalDateTime但与提供的时区相关联的 。请注意,调用 时不要转换toDateTime,因为原始本地日期时间没有关联的时区。

On The server :

在服务器上:

  1. The server local datetime is Tue Dec 17 00:04:29 2013.
  2. You associate a UTC+08:00timezone.
  3. With toDate().toString()this is converted to a representation in the default timezone +08:00(or SGT) which is Tue Dec 17 00:04:29 SGT 2013. The conversion is an identity because the associated timezone is SGT.
  1. 服务器本地日期时间是Tue Dec 17 00:04:29 2013.
  2. 您关联一个UTC+08:00时区。
  3. toDate().toString()此被转换为表示在默认时区 +08:00(或SGT),这是Tue Dec 17 00:04:29 SGT 2013。转换是一个标识,因为关联的时区是SGT

On the user:

在用户上:

  1. The user has local datetime Tue Dec 17 00:04:29 2013
  2. You associate a UTC+07:00timezone.
  3. With toDate().toString()you convert to representation in the default timezone +08:00(or SGT) so the time is Tue Dec 17 01:04:29 SGT 2013. There is a +1 hour time difference between Singapore and Jakarata and so it is 1 am in Singapore when it's midnight in Jakarta.
  1. 用户有本地日期时间 Tue Dec 17 00:04:29 2013
  2. 您关联一个UTC+07:00时区。
  3. 随着toDate().toString()您转换为默认时区+08:00(或SGT)中的表示, 因此时间为Tue Dec 17 01:04:29 SGT 2013. 新加坡和雅加达之间有 +1 小时的时差,因此在雅加达午夜时分是新加坡的凌晨 1 点。

回答by Meno Hochschild

The error is the use of toDate(). Why? By saying toDate() you convert your LocalDateTime to a java.util.Date which is timezone-independent. But then you use implicitly the toString()-method on j.u.Date which uses your default timezone, so in both cases you get the same representation.

错误是使用了 toDate()。为什么?通过说 toDate(),您可以将 LocalDateTime 转换为与时区无关的 java.util.Date。但是随后您在 juDate 上隐式使用了 toString() 方法,该方法使用您的默认时区,因此在这两种情况下您都会获得相同的表示。

The solution is just to leave out the call of toDate(). JodaTime objects have better toString()-implementations closely following ISO standard and will print the result in different timezones as you have specified.

解决方案只是省略 toDate() 的调用。JodaTime 对象具有更好的 toString() 实现,紧密遵循 ISO 标准,并将按照您指定的不同时区打印结果。

回答by A_01

For me this code did the job.

对我来说,这段代码完成了这项工作。

    DateTime dt =DateTime.now();
    System.out.println(dt);

    dt =DateTime.now().withZone(DateTimeZone.forID("Asia/Jakarta"));
    System.out.println(dt);

    dt =DateTime.now().withZone(DateTimeZone.forID("Europe/London"));
    System.out.println(dt);

Where classes are

课程在哪里

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;

Output is :

输出是:

2018-07-17T14:30:51.744+05:30
2018-07-17T16:00:51.829+07:00
2018-07-17T10:00:51.830+01:00