将 UTC 时间转换为本地当前时间

Convert a UTC time to a local current time

提问人:ant2009 提问时间:9/19/2023 最后编辑:ant2009 更新时间:9/19/2023 访问量:53

问:

我正在使用以下库threetenbp

我正在从我们的 API 响应中获取字符串格式的日期/时间 我被派去的时间是这样的Sep 30, 2023, 4:59:00 PM

所以我需要将其转换为本地时区。对我来说,这是亚洲/曼谷。

但是,如果时间是 UTC 和亚洲/曼谷,我们比 7 小时提前。转换时间后,时间没有变化

即 API 响应时间:Sep 30, 2023, 4:59:00 PM

因此,在转换为曼谷当地时间后,我认为它会加上 7 小时。但我得到的结果是完全相同的时间。2023-09-30 16:59:00

下面是代码片段

    val utcFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy, h:mm:ss a")

    // Parse the UTC time string to a LocalDateTime object.
    val utcDateTime = utcFormatter.parse("Sep 30, 2023, 4:59:00 PM")

    // Create a DateTimeFormatter object with the desired local time zone.
    val localFormatter = DateTimeFormatter
        .ofPattern("yyyy-MM-dd HH:mm:ss")
        .withZone(ZoneId.of("Asia/Bangkok"))
    val result = localFormatter.format(utcDateTime)


    // The result is the following: 2023-09-30 16:59:00

======

val utcFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy, h:mm:ss a")
    .withZone(ZoneOffset.UTC)

val utcDateTime = LocalDateTime.parse("Sep 30, 2023, 4:59:00 PM", utcFormatter)
    .atZone(ZoneId.of("Asia/Bangkok"))

println(utcDateTime)

输出如下:

2023-09-30T16:59+07:00[Asia/Bangkok]

但是,我认为输出的时间会提前调整为 7 小时。基本上,时间还是一样的。

例如,如果 UTC 时间是 12:00 PM,那么曼谷的时间将是晚上 7 点。

Android Kotlin ThreeTenBP

评论

0赞 Marcin Orlowski 9/19/2023
您送达的时间缺少时区信息,因此我猜它假设它位于同一个本地 TZ 中,因此不会发生任何变化。
0赞 ant2009 9/19/2023
@MarcinOrlowski我也是这么想的。如何更改此设置以添加英国/英格兰的时区?Sep 30, 2023, 4:59:00 PM
0赞 Marcin Orlowski 9/19/2023
请参阅 stackoverflow.com/questions/49458878/...

答:

2赞 broot 9/19/2023 #1

你的代码几乎是正确的,但你并不是真正的 UTC 格式化程序,因为你没有在任何地方指定时区。您可以使用以下代码修复您的问题:utcFormatter

val utcFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy, h:mm:ss a")
    .withZone(ZoneOffset.UTC)

或者,将格式化程序保留原样,然后在解析时指定区域:

val utcDateTime = LocalDateTime.parse("Sep 30, 2023, 4:59:00 PM", utcFormatter)
    .atZone(ZoneOffset.UTC)

使用分区格式化程序的完整示例:

val utcFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy, h:mm:ss a")
    .withZone(ZoneOffset.UTC)
val localFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
    .withZone(ZoneId.of("Asia/Bangkok"))

OffsetDateTime.parse("Sep 30, 2023, 4:59:00 PM", utcFormatter)
    .format(localFormatter)

手动操作区域的完整示例:

val inputFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy, h:mm:ss a")
val outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")

LocalDateTime.parse("Sep 30, 2023, 4:59:00 PM", inputFormatter)
    .atOffset(ZoneOffset.UTC)
    .atZoneSameInstant(ZoneId.of("Asia/Bangkok"))
    .format(outputFormatter)

评论

0赞 ant2009 9/19/2023
我尝试了你的例子,但我认为它没有按预期工作。我已经用你的一些代码更新了我的问题。随着输出
1赞 broot 9/19/2023
你并没有真正使用我提供的代码,而是你自己对它的混音。首先,你似乎将我的两个解决方案合二为一。其次,你完全放弃了这里实际需要的东西。如果您只应用我建议的小更改并保持其他代码不变,它应该可以工作。请参阅更新的答案。localFormatter
1赞 broot 9/19/2023
我认为(希望)没有。日期时间 API 非常灵活,我们可以通过多种方式做同样的事情。,就像你最初的问题一样,是另一种方式。无论我们选择什么,我们都需要做基本上相同的事情:首先将日期解析为 UTC 日期时间,然后将其格式化为曼谷日期时间。formatter.parse()
1赞 broot 9/19/2023
如果我们有某种 API 总是以相同的格式/TZ 返回日期,那么对我来说,创建一个分区格式化程序来解析其输出然后重用这个格式化程序是有意义的。如果是一次性使用,也许直接操作区域更容易阅读。我们可以选择对我们的情况更有意义的任何内容。
1赞 broot 9/19/2023
此外,这一切可能看起来非常复杂,但请注意,解析和格式化是单独的操作。我们可以以多种方式解析,也可以以多种方式格式化。但是我回答中的两个完整示例都是一样的:它们首先以UTC格式获取,然后将其格式化为曼谷。OffsetDateTime