swift - Swift DateComponents 包含错误的小时值
问题描述
我在 StackOverflow 上搜索了答案,但找不到与我的完全匹配的问题。
我在 GMT+2 时区。
我的 Mac 的时间和时区已正确设置并以 24 小时格式正确显示。
我的 iPhone 模拟器的时间与我的 Mac 的时间相匹配,但采用 12 小时格式,但这不是问题。
这是我的 Swift 代码。代码中的注释是从调试控制台的打印输出中复制而来的:
let tzSecsFromGMT = TimeZone.current.secondsFromGMT() print(tzSecsFromGMT) // 7200 let nowDate = Date(timeIntervalSinceNow: TimeInterval(tzSecsFromGMT)) print(nowDate) // 2021-02-27 21:33:19 +0000 (21:33 matches my Mac's time) let triggerDate = nowDate + 30 // seconds print(triggerDate) // 2021-02-27 21:33:49 +0000 (30 seconds after nowDate, it's correct) let dateComponents = Calendar.current.dateComponents([.timeZone, .year, .month, .day, .hour, .minute, .second], from: triggerDate) print(dateComponents) // timeZone: Europe/Bucharest (current) year: 2021 month: 2 day: 27 hour: 23 minute: 33 second: 49 isLeapMonth: false // (NOTE THE HOUR is 23 instead of 21 !)
现在日期的时间是 21。
triggerDate 的小时是 21。
但是 dateComponent 的小时数是 23 而不是 21。
我究竟做错了什么?
解决方案
那里的问题是您将 secondsFromGMT 添加到当前时区。日期只是一个时间点。日期(现在)在世界任何地方都是一样的。
let nowDate = Date()
print(nowDate.description(with: .current)) // Saturday, February 27, 2021 at 4:51:10 PM Brasilia Standard Time
print(nowDate) // 2021-02-27 19:51:10 +0000 (+0000 means UTC time / zero seconds offset from GMT)
let triggerDate = nowDate + 30 // seconds
print(triggerDate) // 2021-02-27 19:51:40 +0000 (30 seconds after nowDate at UTC (GMT)
let dateFromTriggerDate = Calendar.current.dateComponents([.calendar, .year, .month, .day, .hour, .minute, .second], from: triggerDate).date!
print(dateFromTriggerDate.description(with: .current)) // Saturday, February 27, 2021 at 4:51:40 PM Brasilia Standard Time
推荐阅读
- sqlite - BLOB 数据库文件转换为八进制
- swiftui - SwiftUI 按钮图像插图
- promise - 与 ES6 承诺链的编写方式相比,以下是如何编写 jQuery 承诺链的?
- excel - 如何在指定单元格中输出公式的范围(或行号)?
- python - 为什么我的“else”语句在 python 中不起作用?
- javascript - JavaScript 文本框添加
- r - 更改 ggplot 颜色并增加文本的大小(在绘图区域内)
- css - WebStorm 找不到 Sass 文件
- flutter - 如何在 Flutter 中从另一个 pageview 类调用另一个函数?
- sql - 查找正确的 SQL 查询