Joda 解析 GMT 时区的 ISO8601 日期java.time

2022-09-03 01:15:47

我有一个ISO 8601日期,让我们说:2012-01-19T19:00-05:00

我的机器时区是GMT+1

我正在尝试使用joda来解析它并将其转换为相应的GMT日期和时间:

DateTimeFormatter simpleDateISOFormat = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mmZZ"); 
creationDate = simpleDateISOFormat.withZone(DateTimeZone.UTC)
                                  .parseDateTime(date + "T" + time)
                                  .toDate(); 

现在我期待的结果是Fri Jan 20 00:00:00 CET 2012

相反,我得到:Fri Jan 20 01:00:00 CET 2012

我相信这是因为我在时区。GMT + 1

有没有办法解析伪造的日期位于不同的时区?

编辑:基本上问题是当我调用方法时。该方法根据需要将 转换为 a,但我以本地时间将其转换为 a。toDate()DateTimeDate

有人知道一种不施加此限制的转换方法吗?


答案 1

这是一个工作时髦的测试用例。显示其他时区中的时间的显示方式。

import org.joda.time.*
import org.joda.time.format.*

@Grapes([
    @Grab(group='joda-time', module='joda-time', version='1.6.2')
])

class JodaTimeTest extends GroovyTestCase {

    void testTimeZone() {
        DateTimeFormatter parser    = ISODateTimeFormat.dateTimeParser()
        DateTimeFormatter formatter = ISODateTimeFormat.dateTimeNoMillis()

        DateTime dateTimeHere     = parser.parseDateTime("2012-01-19T19:00:00-05:00")

        DateTime dateTimeInLondon = dateTimeHere.withZone(DateTimeZone.forID("Europe/London"))
        DateTime dateTimeInParis  = dateTimeHere.withZone(DateTimeZone.forID("Europe/Paris"))

        assertEquals("2012-01-20T00:00:00Z", formatter.print(dateTimeHere))
        assertEquals("2012-01-20T00:00:00Z", formatter.print(dateTimeInLondon))
        assertEquals("2012-01-20T01:00:00+01:00", formatter.print(dateTimeInParis))
    }
}

注意:

  • 你必须调整断言,因为我位于伦敦时区:-)
  • “withZone”方法更改 DateTime 对象的元数据以指示其时区。仍然是相同的时间点,只是以不同的偏移量显示。

答案 2

java.time

Joda-Time团队告诉我们迁移到Java 8及更高版本中内置的java.time框架。java.time 框架由 JSR 310 定义。许多java.time功能已经向后移植到Java 6和7,并进一步适应Android

抵消

java.time 类包括 OffsetDateTime,以表示时间轴上的某个时刻,该时刻具有与 UTC 的偏移量,但不是完整的时区。

java.time 类在解析或生成字符串时默认使用标准 ISO 8601 格式。因此,无需定义格式设置模式。

String input = "2012-01-19T19:00-05:00";
OffsetDateTime odt = OffsetDateTime.parse( input );

时区

时区是用于处理异常(如夏令时 (DST))的偏移量规则。正确的时区名称使用格式。您可以将时区 (ZoneId) 分配给 ,以获取 ZonedDateTimecontinent/regionOffsetDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = odt.atZoneSameInstant( zoneId );