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.Date
、java.util.Calendar
和java.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
我的手机时区是 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.Date
、java.util.Calendar
和java.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