joda DateTimeFormat本地时区格式问题

问题描述 投票:1回答:1

我从org.joda.time.DateTime开始,我想以与本地时区相等的时区偏移量输出它。确实是为了方便用户用眼睛看时间(而不是使用适当的ISO8601解析器进行解析)。

val tz = DateTimeZone.getDefault()
val formatter = JacksonJodaDateFormat(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ").withZone(tz))

我得到的是这个:

2020-02-01T05:00:00+0000

我想要的是:

2020-02-01T00:00:00-0500

输出的内容实际上对我的时区是正确的,但是我告诉了它.withZone(tz),并且我(通过调试器确认了tz实际上是America / New_York。

我正在使用jodatime 2.10.2。我在这里还混入了jackson-format-jodatime,但是我在循环之外尝试了jackson,它的表现也一样。

[The Documents说这:

When printing, this zone will be used in preference to the zone from the datetime that would otherwise be used. 

否则将要打印的是UTC,但这不是我想要的。

我是不是解释了javadocs所说的错误?

jodatime
1个回答
1
投票

如果您不反对Java答案(也许您的代码段是Kotlin?),则下面的代码将根据需要设置日期字符串的格式,并处理时区偏移。

为了简单起见,正如您提到的,我也没有使用Jackson库。

您显然可以用起点所需的任何内容替换下面的时区ID,例如"UTC"。对于系统默认值,请使用Joda-Time:

DateTimeZone defaultZone = DateTimeZone.getDefault();

Joda-Time

//
// Using Joda-Time 2.10.2:
//

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormat;

...

String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
String dateString;

DateTime dtOne = new DateTime("2020-02-21T09:30:45.678+00:00");
DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);

DateTime dtTwo = dtOne.withZone(DateTimeZone.forID("America/New_York"));
dateString = fmt.print(dtTwo);   // "2020-02-21T04:30:45-0500":

DateTime dtThree = dtOne.withZone(DateTimeZone.forID("Europe/Paris"));
dateString = fmt.print(dtThree); // "2020-02-21T10:30:45+0100"

java.time

对于Java 8及更高版本,如果可以使用java.time,则withZoneSameInstant()会相应地改变日期和时间:

//
// Using java.time (Java 8 onwards):
//

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

...
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
String dateString;

DateTimeFormatter format = DateTimeFormatter.ofPattern(pattern);
LocalDateTime localDateTime = LocalDateTime.parse("2020-02-21T09:30:45.123");
ZonedDateTime zonedDateTimeA = localDateTime.atZone(ZoneId.of("Europe/Paris"));

dateString = zonedDateTimeA.format(format); // "2020-02-21T09:30:45+0100"

ZonedDateTime zonedDateTimeB = zonedDateTimeA
        .withZoneSameInstant(ZoneId.of("America/New_York"));    
dateString = zonedDateTimeB.format(format); // "2020-02-21T03:30:45-0500"

对于使用java.time的默认时区,为ZoneId.systemDefault()

此外,this是令人惊叹的概述。

编辑:使用java.time代替Joda Time

问题的注释中提到了以下内容,但也需要在此答案中说明:

如果可以的话,绝对应该在Joda Time上使用java.time

从Joda时间homepage

请注意,从Java SE 8开始,要求用户迁移到java.time(JSR-310),这是JDK的核心部分,它代替了此项目。

[摘自Stephen Colebourne,Joda Time的创建者之一:

我使用的措辞是java.time是“受Joda-Time启发的”,而不是确切的推导,但是许多概念将是熟悉的。

© www.soinside.com 2019 - 2024. All rights reserved.