Swift DateComponents 包含错误的小时值

Posted

技术标签:

【中文标题】Swift DateComponents 包含错误的小时值【英文标题】:Swift DateComponents contains wrong hour value 【发布时间】:2021-05-29 20:06:40 【问题描述】:

我已经在 *** 上搜索了答案,但找不到与我完全匹配的问题。

我在 GMT+2 时区。

我的 Mac 的时间和时区设置正确,并以 24 小时格式正确显示。

我的 iPhone 模拟器的时间与我的 Mac 的时间相匹配,但采用 12 小时格式,但这不是问题。

这是我的 Swift 代码。代码中的注释是从 Debug 控制台的打印输出中复制而来的:

  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。

我做错了什么?

【问题讨论】:

你确定你在你的mac中设置了正确的时区吗?因为在我看来你还没有在那里设置 GMT+2。 是的,我的 Mac 首选项已设置正确的时区(布加勒斯特),并且我的 Mac 右上角的时间/时钟显示的是正确的本地(布加勒斯特)时间。 【参考方案1】:

问题在于您将 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

【讨论】:

谢谢。我更改了代码,看起来我现在正在为本地通知 triggerDate 设置正确的日期时间,这意味着它正在打印正确的 local 日期和时间(布加勒斯特时间)。我打印出 notificationCenter 的待处理请求,它还显示了正确的、预期的本地日期时间。但是,通知不会触发。 @Kaplan 你确定你的应用程序在后台吗?从现在开始的 30 秒没有任何意义。检查这个post 天啊!!!就是这样......我在前台盯着我的应用程序等待通知出现。啊!你说得对。在我将应用程序后台化后,通知出现在主屏幕上。从现在开始的 30 秒只是为了测试。现在我知道它有效,我将处理当应用程序在前台时发生通知时的情况。我知道我在文档中读到有一种方法可以处理它,如果需要的话。再次感谢!!

以上是关于Swift DateComponents 包含错误的小时值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中将 NSDateComponents 转换为 DateComponents

swift DateComponents

swift DateComponents

swift DateComponents

swift DateComponents

DateComponents 给出错误的时间