【问题标题】:SimpleDateFormat wrong unix timestamp after parsing解析后 SimpleDateFormat 错误的 unix 时间戳
【发布时间】:2026-01-03 08:50:01
【问题描述】:

我正在尝试使用 SimpleDateFormat 在 unix 时间戳和自定义格式之间进行转换,反之亦然。 为了测试反之亦然的转换,我编写了以下测试用例:

public class Testception extends TestCase {
    public void testTheTestOrTestception() throws ParseException {
        Date datum = new Date(649555200000L);
        SimpleDateFormat dfm = new SimpleDateFormat("yyyy-MM-dd");
        TimeZone tZ = TimeZone.getTimeZone("Europe/Berlin");
        dfm.setTimeZone(tZ);
        String aDifferentFormat = dfm.format(datum);
        assertEquals("1990-08-02", aDifferentFormat);
        Date datum2 = dfm.parse(aDifferentFormat);
        assertEquals(649555200000L, datum2.getTime());
    }
}

我从一个 unixtimestamp (649555200000) 开始,将其转换为我的自定义格式 ("1990-08-02"),效果很好。但不幸的是,第二个断言失败,而不是预期的 649555200000L 结果是 649548000000L

提前致谢。

干杯 L0rdAli3n

【问题讨论】:

  • 你怎么知道应该是649555200000L?

标签: java date timezone simpledateformat


【解决方案1】:

这完全与时区有关。

您已将其设为午夜 UTC,并将其格式化为日期 - 但实际上是柏林时间凌晨 2 点。

然后您将解析 date,它将解析到该日期 in Berlin 的午夜,这比您的起点早两个小时。如果您想再次恢复午夜 UTC,只需将 SimpleDateFormat 的时区设置为 UTC 时区即可。

【讨论】:

  • 哇,有史以来最快的答案。你对 UTC 的提示很棒。你真的做到了 :) 你能快速解释一下你是如何发现我在 UTC 午夜放弃的吗?
  • @L0rdAli3n:我打印了new Date(649555200000L) 并查看了结果 :)(至于快 - 超过 5 分钟!为迟到道歉......)
  • 你是如何打印出新日期(649555200000L)的。因为我肯定不止一次通过 toString 和 toGMTString 看过日期对象?!?
  • @L0rdAli3n:我只使用了toString,知道结果会在我的本地时区。
  • 非常感谢。根据您的解释,toString-output 非常有意义:)
【解决方案2】:

代码没有问题,只是输入假设。

649555200000L 是 1990 年 8 月 2 日柏林的凌晨 2 点。实际结果是柏林午夜的正确值,这是当您将仅日期字符串模式解析为 java.util 时 java 将提供给您的值。日期。

【讨论】:

  • 感谢您的快速回复。你的答案是完全正确的,bu Jon Skeet 也提供了一个有效的修复。所以我接受了他的帖子作为答案,但你也得到了支持,干得好! :)
最近更新 更多