【问题标题】:Convert Date to Milliseconds in Java在 Java 中将日期转换为毫秒
【发布时间】:2014-07-18 05:01:55
【问题描述】:

我需要将日期转换为其相应的毫秒格式。为此,我正在使用 Java 中 Date 类的 getTime() 方法。但是生成的毫秒数不是我的实际日期。比我的约会少一天。例如,

我有22-Nov-2014。如果我将此日期转换为毫秒格式,则会生成1,416,594,600,000。实际上这个值对应于21-Nov-2014

请帮我获得一个精确的毫秒值,对应于 java 中的 Date

【问题讨论】:

  • 您能否向我们展示您用于进行转换的实际代码,以及您期望的输出以及实际获得的输出?另外,您所在的时区。

标签: java date milliseconds


【解决方案1】:

1416594600000 对应于 2014-11-21T18:30:00Z。换句话说,2014 年 11 月 21 日下午 6 点 30 分UTCEpoch Converter 是检查此类事情的绝佳资源。

现在,Date 对象本身没有任何时区信息。它只代表一个时间点。听起来您的“2014 年 11 月 22 日”值可能是 local 时区(印度?)的午夜。如果您从许多不同的时区生成值,并且您不存储哪个时区与哪个值对应,那么您基本上在这里丢失了一些信息。

如果您尝试只是表示一个日期(而不是一个时间点),但您必须将其存储为毫秒-since-the-unix-epoch 值,它可能会使将该日期的午夜存储在 UTC 中是有意义的,尽管您也应该非常清楚地表明这就是您正在做的事情。如果可以的话,您应该以某种方式存储该值,使其更明显是一个日期 - 例如在数据库中使用 DATE 字段。日期和时间工作通常并不像我们担心的那样困难如果您确切知道要建模的数据,并在代码中的任何地方都非常清楚。

使事情更清晰的一种方法是使用良好的日期/时间 API,它允许您表示比 java.util.Datejava.util.Calendar 更多种类的数据。 Joda Time 对此有好处,Java 8 有新的 java.time.* API。我强烈建议您尽快迁移到其中之一。

【讨论】:

    【解决方案2】:

    tl;博士

    LocalDate.of( 2014 , Month.NOVEMBER , 22 )
             .atStartOfDay( ZoneId.of ( "Asia/Kolkata" ) )
             .toInstant()
             .toEpochMilli()
    

    详情

    Answer by Jon Skeet 是正确而明智的。

    这是一些使用 java.time 类的示例代码。

    LocalDate

    LocalDate 类表示没有时间和时区的仅日期值。

    时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。

    ZoneId z = ZoneId.of( "America/Montreal" );
    LocalDate today = LocalDate.now( z );
    

    您可以指定LocalDate

    LocalDate ld = LocalDate.of( 2014 , Month.NOVEMBER , 22 );
    

    ld.toString(): 2014-11-22

    ZonedDateTime

    您需要一个自纪元以来的毫秒数。我确实建议使用从纪元开始计数来处理日期时间。但如果你坚持,我们就开始吧。

    毫秒数意味着我们需要一个日期一个时间。我们有个约会。我假设您希望将一天中的第一刻作为一天中的时间。 不要假设这次是00:00:00。夏令时 (DST) 等异常可能意味着一天从其他时间开始,例如 01:00:00。让 java.time 通过从 LocalDate 生成 ZonedDateTime 对象来确定第一个时刻。

    LocalDate ld = LocalDate.of ( 2014 , Month.NOVEMBER , 22 );
    ZoneId z = ZoneId.of ( "Asia/Kolkata" );
    ZonedDateTime zdt = ld.atStartOfDay ( z );
    

    zdt.toString(): 2014-11-22T00:00+05:30[亚洲/加尔各答]

    Instant

    如果需要,您可以提取 InstantInstant 类代表UTC 时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。开发人员应该将 UTC 视为真正的时间,而在工作时考虑他们自己的狭隘时区。

    Instant instant = zdt.toInstant ();
    

    instant.toString(): 2014-11-21T18:30:00Z

    从那一刻起,我们就可以请求自纪元以来的毫秒数。请注意,这涉及数据丢失,因为任何纳秒都会被截断为毫秒。

    long epochMillis = instant.toEpochMilli();
    

    java.util.Date

    我建议避免使用旧的日期时间类。但如果你必须,你可以转换。查看添加到旧类中的新方法,例如 java.util.Date

    java.util.Date utilDate = java.util.Date.from( instant );
    

    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date.Calendarjava.text.SimpleDateFormat

    Joda-Time 项目现在位于 maintenance mode,建议迁移到 java.time。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-08
      • 2019-12-24
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多