Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Joda时间的Java时区问题_Java_Date_Tomcat_Timezone_Jodatime - Fatal编程技术网

Joda时间的Java时区问题

Joda时间的Java时区问题,java,date,tomcat,timezone,jodatime,Java,Date,Tomcat,Timezone,Jodatime,我有一个相当恼人的问题,一些日期解析和获得正确的日期/时间从我的格式。下面是进行格式化的代码(压缩版本) DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd"); log.debug("Trying to convert {} using format {}.", val, "yyyy-MM-dd"); Date toDate = formatter.parseDateTime(inputText).toDate

我有一个相当恼人的问题,一些日期解析和获得正确的日期/时间从我的格式。下面是进行格式化的代码(压缩版本)

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
log.debug("Trying to convert {} using format {}.", val, "yyyy-MM-dd");
Date toDate = formatter.parseDateTime(inputText).toDate();
log.debug("Converted value to {}", toDate);
这里有一些值不正确的输出。这里的时区设置为EDT。(通过
date
命令和/etc/localtime符号链接进行检查

13:14:53.618 [http-bio-8080-exec-13] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Trying to convert 2013-07-08 using format yyyy-MM-dd.
13:14:53.619 [http-bio-8080-exec-13] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Converted value to Sun Jul 07 20:00:00 EDT 2013
这是使用OpenJDK 7在Tomcat 7上的AWS-LINUX上运行的。我们在AWS上运行了另一个实例,相同的代码产生了以下结果:

17:22:46.164 [http-bio-8080-exec-239] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Trying to convert 2013-07-08 using format yyyy-MM-dd.
17:22:46.165 [http-bio-8080-exec-239] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Converted value to Mon Jul 08 00:00:00 UTC 2013
此机器上的时区设置为UTC

在我的本地机器上,输出也是正确的(回到EDT,这里运行OS X上的oracles JDK):

同样,这三个点的代码都是相同的。我一辈子都不明白为什么我们有一个实例与其他实例的行为不一样。我将添加更多调试输出以尝试缩小范围,但现在我运气不佳

另外,还有一点很有趣。在Tomcat之外的机器上运行是错误的,使用相同的jdk和以下代码,我得到了我所期望的结果:

DateTimeFormatter f = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime parseDateTime = f.parseDateTime("2013-07-08");
System.out.println(parseDateTime.toDate());
输出:

Mon Jul 08 00:00:00 EDT 2013
更新

看起来Joda没有使用系统默认时区。以下是我输出数据的方式:

log.debug("Using joda timezone of: {}", DateTimeZone.getDefault());
log.debug("Default timezone of: {}", TimeZone.getDefault());
以下是输出:

AbstractParamToObjectProvider - Using joda timezone of: UTC
AbstractParamToObjectProvider - Default timezone of: sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]
这些东西中的一个和另一个不匹配…你知道为什么吗

解决方案

乔恩的回答是正确的,但这是最后的结论

不知何故,user.timezone被设置为UTC,Joda正在使用它,而默认时区不是(使用系统时区)。对于补丁,我执行了以下操作:

DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault()));

只是为了确保匹配。一个“正确”的修复方法是在应用程序启动时显式设置系统默认时区。

Joda Time执行以下步骤:

  • 使用
    user.timezone
    系统属性
  • 基于
    TimeZone.getDefault()的ID创建时区
  • 退回UTC
TimeZone.getDefault()
可能有点复杂,尽管它在许多情况下也使用
user.TimeZone


一种选择是在应用程序启动时将
时区
日期时区
的默认时区显式设置为UTC:对于web服务器,这是最合理的默认设置(尽管我个人更喜欢在适当的情况下显式说明时区).

Joda Time将执行以下步骤:

  • 使用
    user.timezone
    系统属性
  • 基于
    TimeZone.getDefault()的ID创建时区
  • 退回UTC
TimeZone.getDefault()
可能有点复杂,尽管它在许多情况下也使用
user.TimeZone


一种选择是在应用程序启动时将
时区
日期时区
的默认时区显式设置为UTC:对于web服务器,这是最合理的默认设置(尽管我个人更喜欢在适当的情况下显式说明时区).

尝试打印解析的
DateTime
的时区:
DateTime parsed=formatter.parseDateTime(inputText);System.out.println(parsed.getZone())
另外,如果你在解析一个日期,为什么要解析为
DateTime
而不是
LocalDate
呢?另外,在每台机器上打印
DateTimeZone.getDefault
——我想知道它是否没有正确地拾取它,所以它使用了与JDK不同的默认值。@JonSkeet这就是我所想的我想知道,为什么它只在tomcat中运行。只是部署了一些带有更多调试信息的更改(tz spit out),那么我会看到上面的内容。@JonSkeet看到我的更新,Joda似乎没有选择与Java类相同的时区。您的
user.timezone
系统属性的值是多少?还有其他设置吗?请尝试打印解析的
DateTime
DateTime parsed=formatter.parseDateTime(inputText);System.out.println(parsed.getZone())
另外,如果你在解析一个日期,为什么要解析为
DateTime
而不是
LocalDate
呢?另外,在每台机器上打印
DateTimeZone.getDefault
——我想知道它是否没有正确地拾取它,所以它使用了与JDK不同的默认值。@JonSkeet这就是我所想的我想知道,为什么它只在tomcat中运行。只是部署了一些带有更多调试信息的更改(tz spit out),那么我会看到上面说的。@JonSkeet看到我的更新,Joda似乎没有选择与Java类相同的时区。你的
user.timezone
系统属性的值是多少?还有其他设置吗?似乎是user.timezone属性导致了问题。但是,我不知道这是从哪里设置的至于Tomcat(找不到任何应该引用和实际设置它的地方)。我同意Jon Skeets的建议,在代码中指定所需的时区,而不是依赖任何默认值。Joda time为UTC提供了一个常量:
DateTimeZone.UTC
。例如,`DateTime DateTime=new DateTime(“2013-07-08”),DateTimeZone.UTC);“似乎是user.timezone属性导致了问题。但是,我不知道这是从哪里设置的,至于Tomcat(找不到任何应该引用和实际设置它的地方)。我同意Jon Skeets的建议,即在代码中指定所需的时区,而不是依赖任何默认值。Joda time为UTC提供了一个常量:
DateTimeZone.UTC
。例如,`DateTime DateTime=new DateTime(“2013-07-08”,DateTimeZone.UTC);'
DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault()));