如何在不指定年月日的情况下将 DateComponents 对象转换为本地化字符串,例如“08:40 PM”?

How to convert a DateComponents-object to a localized string, such as "08:40 PM", without specifying year, month, and day?

我有一个 "time"(小时和分钟)存储在 DateComponents 对象中,我想将其转换为本地化的字符串格式,这样 08:40 PM,och 20:40, 等等

我现在知道如何以这种方式显示日期对象 (NSDAte),但是要将 20:40 转换为日期,我必须假装我知道年月日。

问题:是否可以使用 TimeZone- 和 Locale- 将 DateComponents 对象转换为本地化字符串,例如“08:40 PM”对象,但未指定年月日?

获得本地化日期字符串的唯一方法是使用 DateDateFormatter。所以你要做的就是从日期组件创建一个日期。我们可以使用用户当前的日历来执行此操作。一旦我们有了日期,只需将日期格式化程序设置为您想要显示的样式即可;它应该默认使用用户的语言环境。

var dateComponents = DateComponents()
dateComponents.hour = 20
dateComponents.minute = 40

let date = Calendar.current.date(from: dateComponents)

let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .short
print(dateFormatter.string(from: date!))  // 8:40 PM

您可以只获取今天的组件并向其中添加所需的时间。您还需要指定一个日历:

extension Date {
    var year: Int { Calendar.current.component(.year, from: self) }
    var month: Int { Calendar.current.component(.month, from: self) }
    var day: Int { Calendar.current.component(.day, from: self) }
}

extension DateComponents {
    var todaysDateFromTimeComponents: Date? {
        let today =  Date()
        return DateComponents(calendar: .current,
                              year: today.year,
                              month: today.month,
                              day: today.day,
                              hour: hour,
                              minute: minute)
        .date
    }
}

let date = DateComponents(hour: 20, minute: 40).todaysDateFromTimeComponents // "Feb 1, 2017, 8:40 PM"


如果你想显示“给定时区的日期信息”,你应该使用 DateFormatter 来格式化你的日期。

extension DateFormatter {
    convenience init(timeStyle: DateFormatter.Style) {
        self.init()
        self.timeStyle = timeStyle
    }
}

extension Date {
    static let shortTimeFormatter = DateFormatter(timeStyle: .short)
    func shortTime(with timeZone: TimeZone) -> String {
        Date.shortTimeFormatter.timeZone = timeZone
        return Date.shortTimeFormatter.string(from: self)
    }
}

date?.shortTime(with: TimeZone(identifier: "GMT")!)   // 10:40 PM +2hs