DateFormatter 为非常旧的日期提供奇怪的时区
DateFormatter gives weird timezone for very old dates
对于我的一个客户,我正在使用非常旧的日期,例如:
- 0572-06-17
- 1000-06-17
当我将字符串转换为日期时,它有一个奇怪的时区。
示例:
extension String {
func yearMonthDayDate() -> Date? {
return DateFormatter.yearMonthDayFormatter.date(from: self)
}
}
extension DateFormatter {
static let yearMonthDayFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = .current
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.locale = .current
return dateFormatter
}()
}
extension Date {
func zonedDate() -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = .current
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXX"
dateFormatter.locale = .current
return dateFormatter.string(from: self)
}
}
print("1000-06-17".yearMonthDayDate()!.zonedDate())
1000-06-17T00:00:00+00:17
你可以看到时区是+00:17。
为什么会出现这个奇怪的时区?
过去,每个地方都有自己的 local mean time by observing the times of sun sets and sun rises. This meant that the local time at each town/city not be a nice whole number offset from Greenwich, like +17 minutes for example. This wasn't that big of a problem until people invented trains, which had schedules. At around the 19th century, countries around the world standardised 本地时间,这就是为什么我们有很好的整数偏移量,例如 +1 小时(大部分时间)。
所以在 1000 年,就我们所知的历史而言,您的时区 Europe/Brussels
确实比格林威治早 17 分钟。这段历史记录在 IANA tz
数据库中,这是 TimeZone
查询的内容。这就是为什么你得到 +00:17
.
有趣的是,当我问 TimeZone
距格林威治标准时间 1000 秒左右有多少秒时,它说 0:
let date = Date(timeIntervalSinceNow: 86400 * 365 * -1000)
// this is 0
TimeZone(identifier: "Europe/Brussels")!.secondsFromGMT(for: date)
它可能将实际秒数四舍五入了。 Java 可以告诉你实际答案:
// prints +00:17:30
System.out.println(ZoneId.of("Europe/Brussels")
.getRules().getOffset(LocalDate.of(1000, 1, 1).atStartOfDay()));
对于我的一个客户,我正在使用非常旧的日期,例如:
- 0572-06-17
- 1000-06-17
当我将字符串转换为日期时,它有一个奇怪的时区。 示例:
extension String {
func yearMonthDayDate() -> Date? {
return DateFormatter.yearMonthDayFormatter.date(from: self)
}
}
extension DateFormatter {
static let yearMonthDayFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = .current
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.locale = .current
return dateFormatter
}()
}
extension Date {
func zonedDate() -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = .current
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXX"
dateFormatter.locale = .current
return dateFormatter.string(from: self)
}
}
print("1000-06-17".yearMonthDayDate()!.zonedDate())
1000-06-17T00:00:00+00:17
你可以看到时区是+00:17。 为什么会出现这个奇怪的时区?
过去,每个地方都有自己的 local mean time by observing the times of sun sets and sun rises. This meant that the local time at each town/city not be a nice whole number offset from Greenwich, like +17 minutes for example. This wasn't that big of a problem until people invented trains, which had schedules. At around the 19th century, countries around the world standardised 本地时间,这就是为什么我们有很好的整数偏移量,例如 +1 小时(大部分时间)。
所以在 1000 年,就我们所知的历史而言,您的时区 Europe/Brussels
确实比格林威治早 17 分钟。这段历史记录在 IANA tz
数据库中,这是 TimeZone
查询的内容。这就是为什么你得到 +00:17
.
有趣的是,当我问 TimeZone
距格林威治标准时间 1000 秒左右有多少秒时,它说 0:
let date = Date(timeIntervalSinceNow: 86400 * 365 * -1000)
// this is 0
TimeZone(identifier: "Europe/Brussels")!.secondsFromGMT(for: date)
它可能将实际秒数四舍五入了。 Java 可以告诉你实际答案:
// prints +00:17:30
System.out.println(ZoneId.of("Europe/Brussels")
.getRules().getOffset(LocalDate.of(1000, 1, 1).atStartOfDay()));