我有以下内容:
val startWithTZ = new DateTime("2016-10-01T00:00:00", DateTimeZone.UTC)
val endWithTZ = new DateTime("2016-10-01T11:00:00", DateTimeZone.UTC)
val intervalWithTZ = new Interval(startWithTZ, endWithTZ)
val startWithoutTZ = new DateTime("2016-10-01T00:00:00")
val endWithoutTZ = new DateTime("2016-10-01T11:00:00")
val intervalWithoutTZ = new Interval(startWithoutTZ, endWithoutTZ)
有了这个,我现在做以下事情:
val utcInterval = new Interval(intervalWithoutTZ.getStart.toDateTime(DateTimeZone.UTC),
intervalWithoutTZ.getEnd.toDateTime(DateTimeZone.UTC))
我在utcInterval中看到的并不是我所期待的:
2016-09-30T22:00:00.000Z/2016-10-01T09:00:00.000Z
这是为什么?我期待utcInterval:
2016-10-01T00:00:00.000Z/2016-10-01T11:00:00.000Z
这是我使用Scala REPL时得到的结果:
scala> import org.joda.time._
import org.joda.time._
scala> val startWithoutTZ = new DateTime("2016-10-01T00:00:00")
startWithoutTZ: org.joda.time.DateTime = 2016-10-01T00:00:00.000+02:00
scala> val endWithoutTZ = new DateTime("2016-10-01T11:00:00")
endWithoutTZ: org.joda.time.DateTime = 2016-10-01T11:00:00.000+02:00
scala> val intervalWithoutTZ = new Interval(startWithoutTZ, endWithoutTZ)
intervalWithoutTZ: org.joda.time.Interval = 2016-10-01T00:00:00.000+02:00/2016-10-01T11:00:00.000+02:00
scala> val utcInterval = new Interval(intervalWithoutTZ.getStart.toDateTime(DateTimeZone.UTC),
| intervalWithoutTZ.getEnd.toDateTime(DateTimeZone.UTC))
utcInterval: org.joda.time.Interval = 2016-09-30T22:00:00.000Z/2016-10-01T09:00:00.000Z
scala>
为什么不呢?
答案 0 :(得分:1)
从逻辑上讲,我一直觉得Interval
应该在两个Instant
值而不是两个DateTime
值之间。但是,Joda Time API就是它。
从两个Interval
值创建DateTime
时,结束时间将转换为开始时间的时区。在您的情况下,这实际上并不需要做任何事情,因为intervalWithTZ
他们都是UTC,而intervalWithoutTZ
他们都在你的系统默认时区。此处的命名不准确,因为即使您没有指定一个值,时区中的所有值都是。 DateTime
始终有一个时区;对于没有时区的值,您需要LocalDateTime
。
因此,我们可以摆脱您的intervalWithoutTZ
,只需将您的代码编写为:
DateTime startInDefaultZone = new DateTime("2016-10-01T00:00:00")
DateTime endInDefaultZone = new DateTime("2016-10-01T11:00:00")
val utcInterval = new Interval(startInDefaultZone.toDateTime(DateTimeZone.UTC),
endInDefaultZone.toDateTime(DateTimeZone.UTC));
根本不会改变结果...但基本点是你要转换DateTime
" 2016-10-01T00:00:00您的系统默认时区"到UTC ...并且可能你的默认时区比UTC晚了2个小时,所以UTC的上午11点是当地时间早上9点等。
简而言之,我们实际上可以在这里完全摆脱间隔 - 您所看到的内容可以更简单地显示为:
DateTime startInDefaultZone = new DateTime("2016-10-01T00:00:00")
DateTime startInUtc = startInDefaultZone.toDateTime(DateTimeZone.UTC);
您似乎期望2016-10-01T00:00:00Z,但它实际上是startInDefaultZone
代表的时刻,但以UTC"表示。在您的机器上是2016-10-01T02:00:00Z。
如果确实想要更改时区而不更改本地值"您可以使用withZoneRetainFields
,例如
DateTime startInDefaultZone = new DateTime("2016-10-01T00:00:00")
DateTime startInUtc = startInDefaultZone.withZoneRetainFields(DateTimeZone.UTC);
但是,这通常意味着您使用了错误的类型,并且应该使用LocalDateTime
。在精心设计的系统中,它很少是有用的操作。
答案 1 :(得分:0)
我猜你的当地时区目前是UTC-2,因为你没有给"没有TZ"变量,Joda-Time给它默认(本地)时区。
要更改时区 à posteriori ,您必须将DateTime
转换为LocalDateTime
对象,然后将其转换回{{1使用正确的时区,这里是一个在Java中重用代码的示例。
<强> EDIT2:强>
正如@JonSkeet所建议的那样,最好直接在DateTime
对象上使用DateTime.withZoneRetainFields(DateTimeZone)
而不是转换它。
DateTime
输出:
2016-10-01T00:00:00.000Z / 2016-10-01T11:00:00.000Z
修改强>
正如@JonSkeet在评论中提到的那样,你得到了奇怪的结果,请查阅他的评论以纠正你的输出。