如何使用 kotlin 将服务器时间转换为本地时间?

Lin*_*ina 2 timezone android kotlin

我从服务器获取时间,我想将其更改为本地区域,如何使用 Kotlin 做到这一点?
来自服务器的时间就像“2020-09-01T13:16:33.114Z”
这是我的代码:

  

val dateStr = order.creationDate
val df = SimpleDateFormat("dd-MM-yyyy HH:mm aa", Locale.getDefault())
df.timeZone = TimeZone.getDefault()
val date = df.parse(dateStr)
val formattedDate = df.format(date)
textViewDateOrderDetail.text = formattedDate

Run Code Online (Sandbox Code Playgroud)

order.creationDate : 来自服务器的时间

deH*_*aar 5

太长了;博士

这会将示例转换String为系统默认时区:

import java.time.ZonedDateTime
import java.time.ZoneId

fun main() {
    // example String
    val orderCreationDate = "2020-09-01T13:16:33.114Z"
    // parse it to a ZonedDateTime and adjust the zone to the system default
    val localZonedDateTime = ZonedDateTime.parse(orderCreationDate)
                                        .withZoneSameInstant(ZoneId.systemDefault())
    // print the adjusted values
    println(localZonedDateTime)
}
Run Code Online (Sandbox Code Playgroud)

输出取决于系统默认时区,在 Kotlin Playground 中,它会生成以下行:

2020-09-01T13:16:33.114Z[UTC]
Run Code Online (Sandbox Code Playgroud)

这显然意味着 Kotlin Playground 正在以 UTC 时间进行游戏。


再来一点...

强烈建议java.time立即使用并停止使用过时的库进行日期时间操作(java.util.Date以及java.util.Calendarjava.text.SimpleDateFormat

如果这样做,您可以解析此示例String而无需指定输入格式,因为它是按照 ISO 标准格式化的。

您可以创建一个偏移感知 ( java.time.OffsetDateTime) 对象或一个区域感知对象 ( java.time.ZonedDateTime),这取决于您。以下示例展示了如何解析您的String、如何调整区域或偏移量以及如何以不同的格式打印:

import java.time.OffsetDateTime
import java.time.ZonedDateTime
import java.time.ZoneId
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter

fun main() {
    // example String
    val orderCreationDate = "2020-09-01T13:16:33.114Z"
    // parse it to an OffsetDateTime (Z == UTC == +00:00 offset)
    val offsetDateTime = OffsetDateTime.parse(orderCreationDate)
    // or parse it to a ZonedDateTime
    val zonedDateTime = ZonedDateTime.parse(orderCreationDate)
    // print the default output format
    println(offsetDateTime)
    println(zonedDateTime)
    // adjust both to a different offset or zone
    val localZonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("Brazil/DeNoronha"))
    val localOffsetDateTime = offsetDateTime.withOffsetSameInstant(ZoneOffset.ofHours(-2))
    // print the adjusted values
    println(localOffsetDateTime)
    println(localZonedDateTime)
    // and print your desired output format (which doesn't show a zone or offset)
    println(localOffsetDateTime.format(
                DateTimeFormatter.ofPattern("dd-MM-uuuu hh:mm a")
            )
    )
    println(localZonedDateTime.format(
                DateTimeFormatter.ofPattern("dd-MM-uuuu hh:mm a")
            )
    )
}
Run Code Online (Sandbox Code Playgroud)

输出是

2020-09-01T13:16:33.114Z
2020-09-01T13:16:33.114Z
2020-09-01T11:16:33.114-02:00
2020-09-01T11:16:33.114-02:00[Brazil/DeNoronha]
01-09-2020 11:16 AM
01-09-2020 11:16 AM
Run Code Online (Sandbox Code Playgroud)

要转换到系统区域或偏移量,请使用ZoneId.systemDefault()ZoneOffset.systemDefault()代替硬编码。请注意,ZoneOffset因为它不一定给出正确的时间,因为只有 aZoneId考虑夏令时。有关更多信息,请参阅此问题及其答案

有关为解析或格式化输出定义的格式的更多、更准确的信息,您应该阅读DateTimeFormatter.