我可以使用DateComponentsFormatter来呈现一天中的时间吗



我想用一种简单的方式存储一天中的时间。就我的应用程序而言,我只关心一天中的特定时间,比如下午2:30或凌晨1:10。

使用DateComponentsFormatter,我可以非常接近。

import Foundation
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
formatter.allowedUnits = [
.hour,
.minute
]

// Use the configured formatter to generate the string.
let timeAmount = 9000.0
let outputString = formatter.string(from: timeAmount)
let desiredString = "2:30 pm"import Foundation
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
formatter.allowedUnits = [
.hour,
.minute
]

// Use the configured formatter to generate the string.
let timeAmount = 9000.0
let outputString = formatter.string(from: timeAmount) // yields "2:30"
let desiredString = "2:30 pm"

现在,格式化程序似乎真的只是在说"两小时三十分钟;所以也许我找错树了。DateComponentsFormatter支持我的用例吗?

DateComponentsFormatter用于表示两个日期之间的时间量。DateFormatter用于格式化日期或时间。使用DateFormatter

如果您想在UI中显示时间,请使用DateFormatter,但使用

  • 不要使用dateFormat,而是使用timeStyle
  • 不要覆盖locale
  • 不设置timeZone

例如,在UI中显示当前时间:

let date = Date()
let formatter = DateFormatter()
formatter.timeStyle = .short
let string = formatter.string(from: date)

顺便说一句,这将根据用户的喜好格式化时间串(例如,对于我们中的一些人来说,AM/PM,但在其他地区,用户可能更喜欢24小时时钟表示(。在UI中显示信息时,我们应该始终尊重用户的偏好。


如果您试图将9000秒转换为凌晨2:30:

let startOfDay = Calendar.current.startOfDay(for: Date())
let date = startOfDay.addingTimeInterval(9000)
let formatter = DateFormatter()
formatter.timeStyle = .short
let string = formatter.string(from: date)    // 2:30 AM

显然,如果你碰巧在一个换夏令时或换夏令时的日期,你的结果可能会有所不同。

来自文档:

DateComponentsFormatter对象占用大量时间,并将其格式化为用户可读的字符串。

关键是DateComponentsFormatter的时间量上运行(例如2小时10分钟(,而您需要一个时间点。这些都是非常不同的东西。如果你足够努力,尝试使用DateComponentsFormatter来产生一天中的某个时间可能会奏效,只是你滥用了它

你似乎在把一天中的时间存储为自午夜以来的秒数。要用DateComponentsFormatter格式化,您需要对存储的数字进行大量检查和计算:

  • 您需要自己添加am/pm字符串
  • 任何低于1小时的时间都需要增加12小时
  • 如果存储的时间大于12小时,则需要减去12小时
  • 你可能还需要考虑我错过了更多

此外,上午/下午是不可本地化的。世界上可能也有一些文化使用不同的格式来显示一天中不同时间的时间量(我不知道!(,这将导致这种方法彻底崩溃。


DateFormatter应用于格式化一天中的时间。只需将存储的时间添加到UNIX epoch时间(或任何其他午夜(,并使用UTC时区格式化:

let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "hh:mm a"
// or you can replace the above 2 lines with something more localised:
// formatter.timeStyle = .short
formatter.timeZone = TimeZone(identifier: "UTC")
let output = formatter.string(from: Date(timeIntervalSince1970: storedTime))

最新更新