Kotlin SimpleDateFormat 解析错误的时区

Kotlin SimpleDateFormat parse wrong timezone

我的手机时区是 GMT+7,我有一个代码可以将特定日期时间 (GMT+0) 转换为特定时区 (GMT+3):

var strDate = "2020-07-10 04:00:00+0000"
var result: Date?
var dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ")
dateFormatter.timeZone = TimeZone.getTimeZone("Asia/Jerusalem")
result = dateFormatter.parse(strDate)

问题总是结果 return "Fri Jul 10 11:00:00 GMT+07:00 2020"
但我预计它将 return 日期对象“Fri Jul 10 07:00:00 GMT+03:00 2020”,知道我的代码有什么问题吗?

建议使用java.time,停止使用java.util.Datejava.util.Calendarjava.text.SimpleDateFormat,因为有这样的问题。

在您的代码中,目标时区显然没有应用到日期,但不清楚为什么不应用。

另一个问题可能是您使用的模式,因为您的示例 String 不包含任何小于秒的时间单位,但模式试图考虑 .SSS(这使得代码在Kotlin 游乐场)。

切换到java.time并用现代类处理这个问题,例如OffsetDateTime解析这个String(它不包含有关特定时区的信息,只是零小时的偏移量)和 ZonedDateTime 作为目标对象(这考虑了一个实时区域,它可能有不同的偏移量,具体取决于夏令时)。

你可以这样做:

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

fun main() {
    // this example is in UTC (+0000 --> no offset / offset of 0 hours)
    var strDate = "2020-07-10 04:00:00+0000"
    // create a formatter that can parse Strings of this pattern
    // ([] represents optional units to be parsed)
    var dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss[.SSS]Z")
    // and parse the String to an OffsetDateTime using this formatter
    var resultOfParsing = OffsetDateTime.parse(strDate, dateFormatter)
    // then print the parsed result
    println(resultOfParsing)
    
    // create the target time zone
    var timeZone = ZoneId.of("Asia/Jerusalem")
    // then use the target zone for a zone shift
    var jerusalemTime: ZonedDateTime = resultOfParsing.atZoneSameInstant(timeZone)
    // and print the result
    println(jerusalemTime)
    // you could use your formatter defined above for a differently formatted output, too
    println(jerusalemTime.format(dateFormatter))
}

哪个输出(包括所有中间结果):

2020-07-10T04:00Z
2020-07-10T07:00+03:00[Asia/Jerusalem]
2020-07-10 07:00:00.000+0300