【问题标题】:Joda DateTime Timezone doesn't show up correctlyJoda DateTime 时区未正确显示
【发布时间】:2018-04-07 20:25:15
【问题描述】:

我在 Android 中使用 Joda-Time DateTime

DateTimeZone 似乎无法正常工作。也许它与夏令时有关?

此时,我们有 GMT +2。这将在几周内改变,对于冬天。然后将是 GMT +1。但现在不正确。

import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.joda.time.LocalDateTime

// GMT: Thursday 26 October 2017 12:11:54
val epochTime: Long = 1509019914 

var dateServer = LocalDateTime(epochTime * 1000).toDateTime(DateTimeZone.forID("Europe/Amsterdam"))

预计(阿姆斯特丹的正确时间):

14:11:54 GMT+02:00 DST

实际:

13:11 2017-10-26T13:11:54.000+01:00

【问题讨论】:

  • DateTimeZone.getDefault() 的值是多少?

标签: android datetime timezone kotlin jodatime


【解决方案1】:

LocalDateTime 构造函数获取 epochTime 值和 converts to the default timezone 以获取日期和时间值 - 检查 DateTimeZone.getDefault() 的值,它可能是当前使用 +01:00 偏移量的时区。

然后toDateTime 方法创建一个DateTime,它对应于LocalDateTime 表示的相同日期和时间,但在指定的时区(它只是将时区“附加”到日期/时间值,并且没有进行转换)。

如果要获取特定时区中epochTime 对应的日期和时间,只需create the DateTime directly

val dateServer = DateTime(epochTime * 1000, DateTimeZone.forID("Europe/Amsterdam"));

这样,dateServer 将是:

2017-10-26T14:11:54.000+02:00


我的默认时区的一个例子,只是为了更清楚。我的默认时区(由DateTimeZone.getDefault() 返回)是America/Sao_Paulo,它使用2017 年10 月26 日th 的偏移量-02:00(比UTC 晚2 小时)。

epochTime 1509019914 对应于 UTC 2017-10-26T12:11:54Z

当我执行LocalDateTime(epochTime * 1000) 时,它会获取相应的 UTC 值 (12:11) 并转换为默认时区:在我的情况下,转换为 10:11,因此 LocalDateTime 将具有值 2017-10-26T10:11:54

然后toDateTime 方法只创建一个DateTime,它对应于指定时区的相同日期和时间(2017-10-26T10:11:54)。所以它在阿姆斯特丹创建了2017-10-26T10:11:54 (+02:00)。

您的默认时区可能是使用 +01:00 偏移量的时区,这可以解释您得到的差异(12:11 UTC 首先转换为 LocalDateTime 与 13:11,然后 toDateTime 创建 13 :11 在阿姆斯特丹)。


JSR310 - 新的日期/时间 API

Joda-Time 处于维护模式,正在被新的 API 取代,因此我不建议使用它来启动新项目。即使在joda's website 中它说:“请注意,Joda-Time 被认为是一个基本上“完成”的项目。没有计划进行重大改进。如果使用 Java SE 8,请迁移到 java.time (JSR-310 )。”

如果您不能(或不想)从 Joda-Time 迁移到新的 API,您可以忽略此部分。

在 Android 中,您可以使用 ThreeTen Backport,这是 Java 8's new date/time classes 的一个很好的反向移植。为了让它工作,你还需要ThreeTenABP(更多关于如何使用它here)。

要从epochTime 获取相应的UTC 时刻,您可以使用org.threeten.bp.Instant 类。然后使用org.threeten.bp.ZoneId 将其转换为时区,得到org.threeten.bp.ZonedDateTime

val dateServer = Instant.ofEpochSecond(epochTime).atZone(ZoneId.of("Europe/Amsterdam"));

dateServer 将是一个org.threeten.bp.ZonedDateTime,其值对应于2017-10-26T14:11:54+02:00[Europe/Amsterdam]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-26
    • 2011-08-07
    • 1970-01-01
    • 2015-12-23
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    相关资源
    最近更新 更多