如何在 Swift 中获取当前时间:5 个致命错误及其解决方案

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

时间不仅仅是数字:为什么即使是经验丰富的开发者也会犯错

\n\n

每个 iOS 开发者都至少遇到过这样的任务:“只需获取当前时间”。看起来再简单不过了?但正是在这个看似简单的地方,新手(甚至老手)会犯下错误,这些错误最终会导致 bug、应用崩溃和用户不满。

\n\n

在本文中,我们将分析 在 Swift 中处理当前时间时最常见的五个错误,这些错误在 Stack Overflow 上获得了数千次浏览。您将学习如何避免这些错误,并编写干净、可靠的代码。

\n\n
“我只想在 Swift 中获取当前时间作为 datetime,但得到的结果要么是 nil,要么不是我所期望的。帮帮我!”——这是论坛上典型的求助呼声。
\n\n

让我们来看看问题出在哪里。

\n\n

1. DateFormatter 错误:区域设置是主要敌人

\n\n

问题

\n

最常见的请求:“Swift get current time as datetime string”。开发者编写:

\n\n
let dateFormatter = DateFormatter()\ndateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"\nlet currentTime = dateFormatter.string(from: Date())\nprint(currentTime) // 一切正常?并不完全如此
\n\n

在模拟器或使用英语区域设置的设备上,一切正常。但是,一旦用户在设置中选择,例如,德语或俄语,您就会得到 nil 或意外的格式。

\n\n

为什么会这样?

\n

默认情况下,DateFormatter 使用设备的当前区域设置。对于在 API 中解析或显示的固定日期格式来说,这简直是灾难。

\n\n

解决方案

\n

对于不打算显示给用户的格式,始终设置 en_US_POSIX 区域设置:

\n\n
let dateFormatter = DateFormatter()\ndateFormatter.locale = Locale(identifier: "en_US_POSIX")\ndateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"\ndateFormatter.timeZone = TimeZone.current // 不要忘记时区!\nlet currentTime = dateFormatter.string(from: Date())\nprint(currentTime) // "2024-12-25 14:30:00" — 稳定输出
\n\n
请记住:en_US_POSIX 是在 Swift 中处理固定日期格式时您最好的朋友。
\n\n

2. 忽略时区 (TimeZone)

\n\n

问题

\n

您得到了一个包含当前时间的字符串。但您实际得到的是哪个时间?本地时间?UTC?服务器时间?当开发者在 DateFormatter 中没有指定 timeZone 时,就会出现错误。

\n\n

错误示例:

\n
let formatter = DateFormatter()\nformatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"\nlet now = formatter.string(from: Date())\n// 结果:"2024-12-25T14:30:00+0300" — 这是带偏移量的本地时间\n// 但是,如果您总是需要 UTC 呢?
\n\n

解决方案

\n

始终显式指定 TimeZone:

\n\n
// 用于与服务器交互 (UTC)\nlet utcFormatter = DateFormatter()\nutcFormatter.timeZone = TimeZone(abbreviation: "UTC")\nutcFormatter.locale = Locale(identifier: "en_US_POSIX")\nutcFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"\nlet utcTime = utcFormatter.string(from: Date())\nprint(utcTime) // "2024-12-25T11:30:00Z"\n\n// 用于显示给用户(用户的本地时间)\nlet localFormatter = DateFormatter()\nlocalFormatter.timeZone = TimeZone.current\nlocalFormatter.dateStyle = .medium\nlocalFormatter.timeStyle = .short\nlet localTime = localFormatter.string(from: Date())\nprint(localTime) // "2024年12月25日 14:30"
\n\n

3. 使用 Date() 进行比较:隐藏的陷阱

\n\n

问题

\n

许多人认为在单次调用中 Date() 返回相同的值。但事实并非如此。Swift Date 是时间的一个快照。如果您在代码中两次调用 Date(),这些值可能会相差几微秒。

\n\n


                
                

博客

书籍推荐