如何在Java中使用DateTimeZone

如何在Java中使用DateTimeZone,java,jodatime,Java,Jodatime,我一直在尝试使用以下代码将服务器的日期和时间转换为用户的日期和时间 @Test public void playingWithJodaTime() { LocalDateTime localDateTime = new LocalDateTime(); System.out.println("server localDateTime : " + localDateTime.toDateTime(DateTimeZone.getDefault()).toD

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

@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)新加坡吉隆坡
,而用户的时区是
(UTC+07:00)曼谷、河内、雅加达

我在这里做错了什么?

您正在转换为java(为什么?)。
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转换为其他内容,请将其转换为

A表示没有时区的日期时间

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

在服务器上:

  • 服务器本地日期时间为2013年12月17日星期二00:04:29
  • 您关联一个
    UTC+08:00
    时区
  • 使用
    toDate().toString()
    这将转换为默认时区
    +08:00
    (或
    SGT
    )中的表示形式,即
    2013年12月17日星期二00:04:29 SGT
    。转换是一个标识,因为关联的时区是
    SGT
  • 关于用户:

  • 用户拥有本地日期时间
    2013年12月17日星期二00:04:29
  • 您将一个
    UTC+07:00
    时区关联起来
  • 使用
    toDate().toString()
    可以转换为默认时区
    +08:00
    (或
    SGT
    )的表示形式,因此时间为
    周二12月17日01:04:29 SGT 2013
    。新加坡和雅加达之间有+1小时的时差,所以雅加达的午夜是新加坡的凌晨1点

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


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

    对我来说,这段代码完成了任务

        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
    

    我太慢了。无论如何,我认为在JodaTime api中提供此方法toDate()是一个设计缺陷。JSR 310没有做到这一点。Joda Time中的
    toDate()
    方法需要作为网关与只支持java.util.Date的旧类交互。这种方法是一种特征,当然不是设计失败。Java 8中的JSR 310确实做了同样的事情,只是他们将Date类上的转换方法作为一个方法,而不是
    to
    方法。我知道toDate()作为旧jdk东西的网关/桥梁的用途。区别在于这个方法应该放在哪里,直接放在DateTime或者其他更好的地方?此stackoverflow问题表明此“功能”很容易被误用。我们应该尽量让用户远离j.u.Date,而不是鼓励他们使用它。我同意。JSR310团队的聪明人将转换方法移动到java.util.Date类,原因如下。
    2018-07-17T14:30:51.744+05:30
    2018-07-17T16:00:51.829+07:00
    2018-07-17T10:00:51.830+01:00