如何在Scala中将日期格式转换为UTC?

4
如何将日期格式从"2021-02-28 13:38:00.597+0000" 转换为"Mon, Feb 28,2021 15:25:00 UTC" UTC格式的Scala代码?

4
可以使用java.time来实现,但是我们无法更改星期几(事实上,2021年2月28日是星期天)。如果只是格式问题,请展示您的尝试(当然不一定要成功),我会尽力给出答案。 - deHaar
2
关于你的标签:你不想使用 SimpleDateFormat。它是一个出了名的麻烦类,而且现在已经过时了。正如@deHaar所说,你应该使用java.time。 - Ole V.V.
1
在这里提问之前,您也需要先进行搜索。在您的问题中告诉我们您的搜索结果以及为什么它们不能满足您的需求。这样我们就知道您已经做出了努力(有趣的是,这通常会让人们更愿意帮助您),并且可以更精确地了解您仍然需要了解什么。 - Ole V.V.
2
你能接受尾随文本为“GMT”而不是“UTC”吗?这是因为内置的DateTimeFormatter.RFC_1123_DATE_TIME似乎只能提供所需的内容,但存在上述差异。 - Ole V.V.
1
说实话,我想知道为什么有人点赞这个问题。我更倾向于将其视为未经研究和/或需要更多关注的关闭投票而进行反对。请不要把它当成个人攻击。学会在 Stack Overflow 上正确使用需要一些时间,请继续努力。 - Ole V.V.
显示剩余3条评论
2个回答

5
如果您使用的是Java 8之前的旧版本,则最好使用joda-time中的DateTimeFormat。顺便说一下,+0000时区偏移量是UTC,因此我可以省略withZoneUTC(),但我仍然在第一个日期中使用它以确保安全。
  val oldDateString = "2021-02-28 13:38:00.597+0000"
  val OldFormat     = "yyyy-MM-dd HH:mm:ss.SSSZ"
  val NewFormat     = "EEE, MMM dd, yyyy HH:mm:ss z"

  val formatterOld = DateTimeFormat.forPattern(OldFormat)
  val formatterNew = DateTimeFormat.forPattern(NewFormat)

  val dt              = formatterOld.withZoneUTC().parseDateTime(oldDateString)
  val dateStringInUTC = formatterNew.withZoneUTC().print(dt)

  println(dt)              // 2021-02-28T13:38:00.597Z
  println(dateStringInUTC) // Sun, Feb 28, 2021 13:38:00 UTC
更新: 对于Java 8及更高版本,java.time API是您的好朋友。同样,withZoneSameInstant(ZoneOffset.UTC)并不是真正需要的:
  val oldDateString = "2021-02-28 13:38:00.597+0000"
  val OldFormat     = "yyyy-MM-dd HH:mm:ss.SSSZZZ"
  val NewFormat     = "EEE, MMM dd, yyyy HH:mm:ss z"

  val formatterOld = DateTimeFormatter.ofPattern(OldFormat)
  val formatterNew = DateTimeFormatter.ofPattern(NewFormat)

  val zdt             = ZonedDateTime.parse(oldDateString, formatterOld)
  val dateStringInUTC = zdt.withZoneSameInstant(ZoneId.of("UTC")).format(formatterNew)

  println(zdt)             // 2021-02-28T13:38:00.597Z
  println(dateStringInUTC) // Sun, Feb 28, 2021 13:38:00 UTC

更新:由于后者无法在结尾处打印出字符串“UTC”,即使ZoneOffset扩展了ZoneId,因此已切换到使用ZoneId.of("UTC")而不是ZoneOffset.UTC


1
Joda-Time 项目处于维护模式。对于 Java 6 和 Java 7,我建议使用来自 Java 8+ 的大多数 java.time 功能的后移版本:ThreeTen-Backport。后移版本几乎具有与 java.time 相同的 API,因此从后移版本迁移到内置的 java.time 最终可能只涉及更改 import 语句。所有三个项目(Joda-Time、java.time 和 ThreeTen-Backport)均由同一人 Stephen Colebourne 领导。 - Basil Bourque

4
如果您能使用java.time,则需要:
  • 一个DateTimeFormatter来解析具有您输入示例格式的String,这种格式非常接近ISO标准,但缺少日期和时间之间的'T'
  • 另一个DateTimeFormatter将时间内容以所需格式输出,其中包括星期几和月份的英文缩写
  • 一个OffsetDateTime用于使用第一个DateTimeFormatter解析String
  • 一个ZonedDateTime表示UTC的时间值
以下是我在Java中的实现:
public static void main(String[] args) {
    // example String
    String utcDatetimeString = "2021-02-28 13:38:00.597+0000";
    // prepare a formatter that can parse a String of this format
    DateTimeFormatter dtfIn = DateTimeFormatter.ofPattern(
                                        "uuuu-MM-dd HH:mm:ss.SSSxxxx",
                                        Locale.ENGLISH
                                    );
    // parse it to an OffsetDateTime
    OffsetDateTime odt = OffsetDateTime.parse(utcDatetimeString, dtfIn);
    // then convert it to a ZonedDateTime applying UTC zone
    ZonedDateTime zdt = odt.atZoneSameInstant(ZoneId.of("UTC"));
    // prepare a formatter that produces the desired output
    DateTimeFormatter dtfOut = DateTimeFormatter.ofPattern(
                                        "EEE, MMM dd, uuuu HH:mm:ss zzz",
                                        Locale.ENGLISH
                                    );
    // and print the ZonedDateTime using the formatter
    System.out.println(zdt.format(dtfOut));
}

输出:

Sun, Feb 28, 2021 13:38:00 UTC

2
不错!在这里使用ZoneId.of("UTC")非常重要。我之前使用的是ZoneOffset.UTC,导致使用OffsetDateTime时抛出DateTimeException: Unable to extract ZoneId from temporal ...异常,因此我改用了ZonedDateTime,但最终无法打印出UTC的字符串,所以不得不手动插入它。 - Alin Gabriel Arhip
2
我之前也遇到过这个问题,所以我决定始终使用ZoneId来代替ZonedDateTime,即使ZoneOffset扩展了ZoneId。我认为我们两个的答案都有价值!是的,必须有一个带有ID的区域,仅有偏移量是不够的(尽管+0000在所有情况下都表示UTC)。 - deHaar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接