我从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
它输出的内容实际上对我的时区是正确的,但我告诉了它。with zone(tz(和我(通过调试器(确认了tz实际上是America/New_York。
我用的是约会时间2.10.2。我在这里也有杰克逊格式的jodatime,但我在循环之外尝试了这个,它的表现也是一样的。
文件上写着:
When printing, this zone will be used in preference to the zone from the datetime that would otherwise be used.
否则会打印的是UTC,但这不是我希望它做的。
我是否误解了javadocs所说的内容?
如果您不反对Java答案(也许您的代码片段是Kotlin?(,下面将根据您的需要格式化日期字符串,并处理时区转换。
为了简单起见,我也没有像你提到的那样使用杰克逊图书馆。
很明显,您可以将下面的时区ID替换为起点所需的任何内容,例如"UTC"
。或者对于系统默认值,使用Joda Time:
DateTimeZone defaultZone = DateTimeZone.getDefault();
Joda时间
//
// 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()
。
此外,这是一个惊人的概述。
编辑:使用java.time
而不是Joda Time
问题的评论中提到了以下内容,但需要在这个答案中说明:
如果可以的话,你绝对应该在Joda Time上使用java.time
。
来自Joda Time主页:
注意,从Java SE 8开始,用户被要求迁移到Java.time(JSR-310(,这是JDK的核心部分,它取代了这个项目。
来自《Joda Time:》的创作者之一斯蒂芬·科尔伯恩
我使用的措辞是java.time是"受Joda time启发",而不是确切的推导,尽管许多概念都很熟悉。