我在Android中使用Joda-TimeDateTime
。
似乎DateTimeZone
无法正常工作。也许它与夏令时有关?
目前,我们有GMT +2。这将在几周内改变,对于冬天。然后将是格林威治标准时间+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:112017-10-26T13:11:54.000+01:00
LocalDateTime
构造函数获取epochTime
值并转换为默认时区以获取日期和时间值 - 检查DateTimeZone.getDefault()
的值,它可能是当前使用+01:00
偏移量的时区。
然后,toDateTime
方法创建一个DateTime
,该对应于LocalDateTime
表示的相同日期和时间,但在指定的时区(它只是将时区"附加"到日期/时间值,并且不进行转换)。
如果要获取与特定时区中epochTime
对应的日期和时间,只需直接创建DateTime
:
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 日的偏移量-02:00
(比 UTC 晚 2 小时)。
该epochTime
1509019914对应于 UTC2017-10-26T12:11:54Z
。
当我做LocalDateTime(epochTime * 1000)
时,它会获取相应的 UTC 值 (12:11) 并转换为默认时区:在我的例子中,转换为 10:11,因此LocalDateTime
的值将2017-10-26T10:11:54
。
然后,toDateTime
方法只是在指定的时区创建一个对应于相同日期和时间(2017-10-26T10:11:54
)的DateTime
。所以它在阿姆斯特丹创造了2017-10-26T10:11:54
(+02:00
)。
您的默认时区可能是使用+01:00
偏移量时区的时区,这可以解释您获得的差异(12:11 UTC 首先转换为 13:11 的LocalDateTime
,然后toDateTime
阿姆斯特丹创建 13:11)。
JSR310 - 新的日期/时间 API
Joda-Time 处于维护模式,并且正在被新的 API 取代,所以我不建议使用它启动一个新项目。即使在Joda的网站上也说:">请注意,Joda-Time被认为是一个基本上"完成"的项目。没有计划进行重大改进。如果使用Java SE 8,请迁移到java.time (JSR-310)。
如果您不能(或不想)从 Joda-Time 迁移到新的 API,则可以忽略此部分。
在Android中,你可以使用ThreeTen Backport,这是Java 8新的日期/时间类的一个很好的反向移植。要使其正常工作,您还需要ThreeTenABP(有关如何使用它的更多信息) 这里).
要从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]
。