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 !)
    
  • nowDate 的小时是 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,2021 at 4:51:40 PM Brasilia Standard Time

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...