时间不仅仅是数字:为什么即使是经验丰富的开发者也会犯错
\n\n每个 iOS 开发者都至少遇到过这样的任务:“只需获取当前时间”。看起来再简单不过了?但正是在这个看似简单的地方,新手(甚至老手)会犯下错误,这些错误最终会导致 bug、应用崩溃和用户不满。
\n\n在本文中,我们将分析 在 Swift 中处理当前时间时最常见的五个错误,这些错误在 Stack Overflow 上获得了数千次浏览。您将学习如何避免这些错误,并编写干净、可靠的代码。
\n\n“我只想在 Swift 中获取当前时间作为 datetime,但得到的结果要么是 nil,要么不是我所期望的。帮帮我!”——这是论坛上典型的求助呼声。\n\n
让我们来看看问题出在哪里。
\n\n1. DateFormatter 错误:区域设置是主要敌人
\n\n问题
\n最常见的请求:“Swift get current time as datetime string”。开发者编写:
\n\nlet dateFormatter = DateFormatter()\ndateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"\nlet currentTime = dateFormatter.string(from: Date())\nprint(currentTime) // 一切正常?并不完全如此\n\n在模拟器或使用英语区域设置的设备上,一切正常。但是,一旦用户在设置中选择,例如,德语或俄语,您就会得到 nil 或意外的格式。
为什么会这样?
\n默认情况下,DateFormatter 使用设备的当前区域设置。对于在 API 中解析或显示的固定日期格式来说,这简直是灾难。
解决方案
\n对于不打算显示给用户的格式,始终设置 en_US_POSIX 区域设置:
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 时,就会出现错误。
错误示例:
\nlet 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\n3. 使用 Date() 进行比较:隐藏的陷阱
\n\n问题
\n许多人认为在单次调用中 Date() 返回相同的值。但事实并非如此。Swift Date 是时间的一个快照。如果您在代码中两次调用 Date(),这些值可能会相差几微秒。
博客
书籍推荐
推荐阅读