-2

我们收到的时间为小时 = 11,分钟 = 29,秒 = 54,毫秒 = 999 以及时区信息。

如何将此时间转换为没有日期部分的 unix 纪元毫秒。我试过这段代码:

    ZoneId zoneId = ZoneId.of("America/New_York");
    LocalDate now = LocalDate.now(zoneId);
    long epochMilli = ZonedDateTime.of(LocalDate.now(zoneId).atTime(11, 29, 20, 999 * 1000 * 1000), zoneId).toInstant().toEpochMilli();
    long unixEpocSeconds = epochMilli % (24 * 60 * 60 * 1000); //86400000

    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(zoneId));
    calendar.setTimeInMillis(unixEpocSeconds);
    System.out.println("( = " + (calendar.get(Calendar.HOUR)==11));
    System.out.println("( = " + (calendar.get(Calendar.MINUTE)==29));
    System.out.println("( = " + (calendar.get(Calendar.SECOND)==20));
    System.out.println("( = " + (calendar.get(Calendar.MILLISECOND)==999));

如何在没有日期组件的情况下获取 unix 纪元秒数,即如何获取 UTC 区域 / 而不是给定 zoneid 中的毫秒数。上面的代码运行 find if zoneId=UTC

4

1 回答 1

2

tl;博士

Duration.ofHours( 11L )
        .plusMinutes( 29L )
        .plusSeconds( 54L )
        .plusMillis( 999L ) 
        .toMillis()

41394999

时间跨度与时间

你的问题很困惑。与 UTC 相比,没有日期的时间是没有意义的。自 Unix 纪元参考日期以来的毫秒计数1970-01-01T00:00:00Z用于跟踪日期时间。

我怀疑您实际上是在处理一段时间,并将其误认为是一天中的时间。一个是针对时间线的,另一个不是。

Duration

与 Java 8 及更高版本捆绑的 java.time 类包括Duration用于处理此类未附加到时间线的时间跨度。

这些方法采用long数据类型,因此尾随L.

Duration d = Duration.ofHours( 11L ).plusMinutes( 29L ).plusSeconds( 54L ).plusMillis( 999L ) ;

毫秒数

你要求毫秒数,所以你去。请注意数据丢失,因为 aDuration具有更精细的纳秒分辨率,因此在转换为毫秒时,您将丢失任何更精细的秒数。

long millis = d.toMillis() ;  // Converts this duration to the total length in milliseconds.

41394999

但我建议您不要使用毫秒数来表示时间跨度或时间轴上的时刻。最好使用对象或标准化文本;继续阅读。

ISO 8601

ISO 8601标准定义了将日期时间值表示为文本的实用明确格式。

这包括持续时间的表示。格式是标记开始的PnYnMnDTnHnMnS地方,而将任何年-月-日部分与任何小时-分钟-秒部分分开。PT

java.time 类在其parsetoString方法中默认使用标准格式。

String output = d.toString() ;

PT11H29M54.999S

请参阅在 IdeOne.com 上实时运行的代码

您可以在 java.time 中直接解析此类字符串。

Duration d = Duration.parse( "PT11H29M54.999S" ) ;

我建议尽可能使用这种格式,尤其是在系统之间交换数据时。

在 Java 中工作时,传递Duration对象而不是单纯的文本。

时间线

您可以对对象执行日期时间数学运算Duration。例如,取您所在时区的当前时刻,并加上十一个半小时。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
ZonedDateTime later = now.plus( d ) ;

now.toString(): 2017-09-27T07:23:31.651+13:00[太平洋/奥克兰]

later.toString(): 2017-09-27T18:53:26.650+13:00[太平洋/奥克兰]

对于 UTC 值,请调用toInstant. 该类Instant表示 UTC 时间线上的一个时刻,分辨率为纳秒(小于毫秒)。

Instant instant = later.toInstant() ;  
于 2017-09-26T18:10:55.320 回答