Joda Time给出了错误的时区

mat*_*oom 13 java jodatime

我正在使用Joda time(1.6)库并且它使用错误的时区(英国夏令时而不是GMT)继续返回DateTime对象.

我的Windows工作站(运行JDK 1.6.0_16)认为它在GMT中,如果从JDK日期/时间类获得默认时区,则它是正确的(GMT).我在Linux服务器上也有同样的行为.我认为在Joda的时区数据库文件中可能是一个错误,所以我用最新的数据库重建了jar但没有任何变化.

import java.util.TimeZone;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

public class TimeZoneTest {

    public static void main(String[] args) {                
        DateTimeFormatter timeParser = ISODateTimeFormat.timeParser();
        TimeZone timeZone = TimeZone.getDefault();
        System.out.println(timeZone.getID()); // "Europe/London"
        System.out.println(timeZone.getDisplayName()); // "Greenwich Mean Time"

        DateTimeZone defaultTimeZone = DateTimeZone.getDefault();
        System.out.println(defaultTimeZone.getID()); //"Europe/London"
        System.out.println(defaultTimeZone.getName(0L)); //"British Summer Time"

        DateTime currentTime = new DateTime();
        DateTimeZone currentZone = currentTime.getZone();
        System.out.println(currentZone.getID()); //"Europe/London"
        System.out.println(currentZone.getName(0L)); //"British Summer Time"            
    }
}
Run Code Online (Sandbox Code Playgroud)

通过静态初始化程序进行调试,org.joda.time.DateTimeZone我看到System.getProperty("user.timezone")调用"Europe/London"按预期方式给出.

jit*_*ter 30

好的,要了解这一点,你必须熟悉英国夏令时的实际意义以及它何时到位.为了使短传递0LgetName()它是1970-01-01T00:00:00Z如此DefaultTimeZone抬头的那一刻时区的名称.这是英国夏令时.

来自:http://www.nmm.ac.uk/explore/astronomy-and-time/time-facts/british-summer-time

1968年钟表在2月18日格林尼治标准时间前一小时推进,直到1968年10月27日至1971年10月31日期间英国标准时间(格林威治标准时间全年保存)时生效.

相反,如果您将传递适当的毫秒数1970-01-01T00:00:00Z.例如通过做

defaultTimeZone.getName(new GregorianCalendar().getTimeInMillis())
Run Code Online (Sandbox Code Playgroud)

你也会得到正确的字符串.基本上你只是给getName()方法输入了错误的参数,结果产生了意想不到的结果.

如果您想查看详细信息,请查看org/joda/time/tz/srcjoda源文件,了解joda如何确定时区.


代替

defaultTimeZone.getName(0L)
Run Code Online (Sandbox Code Playgroud)

你可以用

defaultTimeZone.toTimeZone().getDisplayName()
Run Code Online (Sandbox Code Playgroud)

这对我来说.

  • 真棒.谁有想过.我真的说"1970年1月1日在英国夏令时没有办法".更欺骗我.这也解释了导致问题的根本问题,即使用ISODateTimeFormat.timeParser()解析"10:00:00.0000000 + 00:00"导致GMT + 1中的DateTime.这是因为Joda没有时间和日期的独立概念所以这次解析相对于1970年1月1日,正如你所指出的那样是GMT + 1!疯.谢谢. (6认同)