如何在Java中使用DateTimeZone

时间:2013-12-16 16:05:10

标签: java jodatime

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

@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());
}

印刷结果

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

但是,由于服务器时区为(UTC+08:00) Kuala Lumpur, Singapore而用户为(UTC+07:00) Bangkok, Hanoi, Jakarta,因此打印结果与预期不符。

我在这里做错了什么?

4 个答案:

答案 0 :(得分:6)

您正在将DateTime转换为java Date(为什么?) java.util.Date使用默认JVM的时区
所以,你错过了这次转换的时区。

此示例按预期工作:

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")));  

如果您想将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());

答案 1 :(得分:2)

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

解决方案就是省去toDate()的调用。 JodaTime对象最好使用toString() - 严格遵循ISO标准的实现,并将按照您的指定在不同的时区打印结果。

答案 2 :(得分:1)

LocalDateTime表示日期时间,不含时区。

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

在服务器上:

  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
  4. 在用户身上:

    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点。

答案 3 :(得分:0)

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

    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);

班级在哪里

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

输出为:

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