【问题标题】:How to convert INSTANT time UTC toEpochMilli in specific timeZone如何在特定时区将即时时间 UTC 转换为 EpochMilli
【发布时间】:2020-05-09 16:53:32
【问题描述】:

编辑:对不起,也许我的问题不正确......

我正在尝试将 UTC 时间戳转换为 Java(Kotlin) 中的本地时间戳

f。例。

UTC 时间 18:00 德国当地时间是 20:00 我需要 UTC 时间戳中的德国当地时间.....

    fun getLocalizedTime(locationId: Long, utcTimeInMs: Long? ): Long{
        val instant = Instant.ofEpochMilli(utcTimeInMs?:Instant.now().toEpochMilli())
        val zoneIdAsString = locationDataService.locationData.locations[locationId]?.timeZone
                ?: "UTC"
        val zoneId = ZoneId.of(zoneIdAsString)
        val zonedDateTime = ZonedDateTime.ofInstant(instant, zoneId)

        return instant.atZone(zoneId).toInstant().toEpochMilli()
    }
}

返回UTC时间:(

如何在特定时区将 INSTANT 时间 UTC 转换为 EpochMilli

【问题讨论】:

    标签: kotlin time timezone utc instant


    【解决方案1】:

    纪元毫秒以 UTC 为单位

    没有“toEpochMilli in specific timeZone”这样的东西,如果你按照传统定义去的话。从纪元引用算起的毫秒数始终为 UTC。

    一个纪元的毫秒计数以 UTC 时间计算。 java.time 和 Unix/POSIX 使用的纪元参考是 1970 年的第一个时刻 UTC,1970-01-01T00:00Z。末尾的Z 表示UTC,发音为“Zulu”。到了今天,各种信息系统使用了几十个其他纪元参考。

    所以说“时区中的纪元毫”是没有意义的。

    如果您有自 1970 年第一刻 UTC 以来的毫秒数,则解析为 Instant

    Instant instant = Instant.ofEpochMilli( milliseconds ) ;
    

    要通过特定地区的人们使用的挂钟时间查看同一时刻,请调整到时区以获取ZonedDateTime

    ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
    ZonedDateTime zdt = instant.atZone( z ) ;
    

    InstantZonedDateTime 都表示同一时刻,时间轴上的同一点,自纪元引用以来的相同毫秒数。

    您可以从ZonedDateTime 中提取Instant 以返回到原来的count-from-epoch。

    long millisecondsSinceEpoch = zdt.toInstant().toEpochMilli() ;  
    

    你会发现millisecondsmillisecondsSinceEpoch长整数是同一个数字。

    您的代码instant.atZone(zoneId).toInstant() 没有意义。您从Instant 开始,转换为ZonedDateTime,然后转换回Instant。所有三个对象都代表同一个时刻,自 epoch 引用以来的相同毫秒数。你的那些电话没有完成任何有用的工作。

    德国时间到 UTC

    进一步澄清,你说:

    我需要 UTC 时间戳中的德国当地时间

    定义您的特定时区。

    ZoneId z = ZoneId.of( "Europe/Berlin" ) ;
    

    捕捉那里看到的当前时刻。

    ZonedDateTime zdt = ZonedDateTime.now( z ) ;
    

    通过提取 Instant 来调整到 UTC。

    Instant instant = zdt.toInstant() ;
    

    如果绝对需要,询问毫秒数。

    long milliseconds = instant.toEpochMilli() ;  // Beware of data loss, as any microseconds/nanoseconds are ignored. 
    

    我确实建议将时刻作为从纪元开始的计数来传达,因为分辨率(毫秒与整秒与微秒与纳秒与其他东西)并不明显,纪元参考也不明显。取而代之的是,以标准ISO 8601 格式以文本形式传达时刻。 java.time 类在生成/解析文本时默认使用 ISO 8601 格式。所以不需要指定格式模式。

    如果您只需要毫秒,请截断任何现有的微秒或纳秒。

        String output = instant.truncatedTo( ChronoUnit.MILLIS ).toString() ;  // Generate text in standard ISO 8601 format.
    

    看到这个code run live at IdeOne.com

    zdt.toString(): 2020-05-09T23:57:35.363701+02:00[欧洲/柏林]

    instant.toString(): 2020-05-09T21:57:35.363701Z

    毫秒:1589061455363

    输出:2020-05-09T21:57:35.363Z


    【讨论】:

    • 0 抱歉,可能是我的问题不正确......我正在将 UTC 时间戳转换为 Java(Kotlin)f 中的本地时间戳。出口。 UTC 时间 18:00 德国当地时间是 20:00 我需要 UTC 时间戳中的德国当地时间.....
    • @DimitriRubinsteinTSS 小心“本地”这个词。在java.time 中,类名中的“local”一词表示anyall 位置,而不是任何一个特定位置。 LocalDateLocalTimeLocalDateTime 类故意缺少任何时区概念或与 UTC 的偏移量。
    • @DimitriRubinsteinTSS 请编辑您的问题以更清楚地说明您的问题和目标。在未来的几年里,这个页面可能会被成千上万的人阅读。
    • @DimitriRubinsteinTSS 将来,请在发布之前彻底搜索 Stack Overflow。所有这一切都已经讲过很多次了。
    猜你喜欢
    • 2020-03-21
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 2014-08-12
    • 2022-11-30
    • 2020-06-16
    • 2021-07-13
    • 2018-03-24
    相关资源
    最近更新 更多