日期计算的差异Java SimpleDateFormat

时间:2015-06-23 11:52:58

标签: java java-ee simpledateformat

我需要将日期解析为毫秒。我就是这样做的。

 private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

      public void setTime(String date) {
      try {
            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
            this.time = sdf.parse(date).getTime();
        } catch (ParseException e) {
                e.printStackTrace();
        }

这是我服务器中的问题。

例如,对于给定的输入日期“2015-06-20T01:57:13Z”,输出值为1592618233000 ms,但预期值应为1434765433000.

分析问题我发现转换后的157852800000 ms的差异给出了“Thu Jan 01 1975 05:30:00 GMT + 0530(IST)”日期。

我看到157852800000毫秒被添加到我服务器中的几个日期。这里没有代码问题。我正在使用上面显示的代码。当我在我的本地机器上运行它时,它工作得非常好。此外,我的服务器中的这种情况不会一直发生。

请就此提出建议。

4 个答案:

答案 0 :(得分:1)

这可能会或可能不会导致您的问题,但一般情况下您不应该使SimpleDateFormat成为静态字段。这是因为这个类是有状态的,因此不是线程安全的;当多个线程访问同一个实例时,可能会出现意外结果。

答案 1 :(得分:0)

也许是并发问题。 SimpleDateFormat不是线程安全的。因此,每次使用它时都要创建它或同步访问它并检查是否能解决您的问题。

答案 2 :(得分:0)

SimpleDateFormat不是线程安全的。多个线程可能正在访问同一个simpledateformat实例。通常不建议将其设为静态。每个实例都应该有自己的simpledateformat实例。

答案 3 :(得分:0)

显然你的结局出了问题。

这是我的代码版本。使用Java 8 Update 45。

try {
    String input = "2015-06-20T01:57:13Z";
    SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss'Z'" );

    sdf.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
    java.util.Date date = sdf.parse( input );
    long millisSinceEpoch = date.getTime();

    System.out.println( "millis: " + millisSinceEpoch );

} catch ( ParseException ex ) {
    // Handle exception
}

跑步时。

millis: 1434765433000

我得到了您的预期结果。

也许问题与您将SimpleDateFormat实例错误地用作静态有关,正如评论和答案中指出的那样。

顺便说一句,java.util.Date /。Calendar类非常麻烦。他们现在被以下任何一个取代:

默认情况下,这两个框架都支持您的输入字符串ISO 8601格式。

这两个框架都为其各自的日期时间对象分配了一个时区。

约达时间

以下是Joda-Time 2.8.1中的代码。搜索StackOverflow以获取更多示例和讨论。

String input = "2015-06-20T01:57:13Z";
DateTimeZone zone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeKolkata = new DateTime( input , zone );
DateTime dateTimeUtc = dateTimeKolkata.withZone( DateTimeZone.UTC );
long millisSinceEpoch = dateTimeKolkata.getMillis();

转储到控制台。

System.out.println( "dateTimeKolkata: " + dateTimeKolkata );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "millisSinceEpoch: " + millisSinceEpoch );

跑步时。

dateTimeKolkata: 2015-06-20T07:27:13.000+05:30
dateTimeUtc: 2015-06-20T01:57:13.000Z
millisSinceEpoch: 1434765433000

java.time

java.time的代码在概念上与上面看到的Joda-Time代码类似,只是java.time使用Factory方法而不是“new”构造函数。

有关代码示例,请参阅此问题Parse ISO timestamp using Java 8 java.time api (standard edition only)

避免Count-Since-Epoch

我建议尽可能避免直接使用count-from-epoch(在你的情况下为毫秒)。使用一个体面的日期时间框架并坚持使用其智能对象。您是否将文本作为原始字节数组而不是String个实例处理?相同的逻辑适用于日期时间值。