在 DateFormatter 扩展中包含日期转换器功能

Posted

技术标签:

【中文标题】在 DateFormatter 扩展中包含日期转换器功能【英文标题】:Include a date converter function inside of a DateFormatter extension 【发布时间】:2019-03-23 20:40:28 【问题描述】:

扩展格式化 API 日期,然后转换器函数将其转换为我喜欢的格式。

代码有效,但调用似乎很冗长。这是可以重构的东西吗?我可以将两者结合起来吗?

convertDateFormater 函数的DateFormatter 设为iso8601Full 属性似乎是合乎逻辑的。没有错误,但尝试调用无效。

请用代码发布答案,以便我将其标记为正确。

extension DateFormatter 
    static let iso8601Full: DateFormatter = 
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        return formatter
    ()


    func convertDateFormater(date: String) -> String 
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let date = dateFormatter.date(from: date)
        dateFormatter.dateFormat = "dd/MM/yyyy"
        return  dateFormatter.string(from: date!)
    

打电话

row.creationDateLabel.setText("\(convertDateFormater(date: DateFormatter.iso8601Full.string(from: value.creationDate)))")

【问题讨论】:

【参考方案1】:

您正在方法中创建日期格式化程序,这可能很昂贵。您可能希望将两者都保存在静态文件中:

extension DateFormatter 
    static let iso8601Full: DateFormatter = 
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        return formatter
    ()

    static let dateOnly: DateFormatter = 
         let formatter = DateFormatter()
         formatter.dateFormat = "dd/MM/yyyy"
         return formatter
    ()

    static func string(iso string: String) -> String 
        let date = DateFormatter.iso8601Full.date(from: string)!
        return  DateFormatter.dateOnly.string(from: date)
    

然后你可以这样做:

row.creationDateLabel.setText(DateFormatter.string(iso: value.creationDate))

这既更简洁又避免了格式化程序的冗余实例化。

就个人而言,我会使用dateStyle,而不是在dateOnly 中使用dateFormat,这样日期字符串(大概显示在UI 中)已正确本地化,但您可以为所欲为。

(顺便说一句,这是我在手机上输入的,如果有任何语法错误,我深表歉意,但希望这能说明基本思想。)


如果creationDate 已经是Date,那么您不需要任何特定于iso 的东西。我的答案基于您将String 作为参数的方法。如果它已经是Date,那么它只是:

row.creationDateLabel.setText(DateFormatter.dateOnly.string(from: value.creationDate))

【讨论】:

谢谢。我在标签电话中收到Cannot convert value of type 'Date' to expected argument type 'String'。我不确定,但我不认为这是因为我的模型中的 creationDate 是 Date 类型。 如果它已经是 Date,那么你就不需要任何特定于 iso 的东西。我的答案基于您将String 作为参数的方法。如果它已经是Date,请参阅上面的修订答案。 我正在使用formatter.dateStyle = .short,就像你建议的那样。挺好的。

以上是关于在 DateFormatter 扩展中包含日期转换器功能的主要内容,如果未能解决你的问题,请参考以下文章

字符串到日期的转换有时会使用 DateFormatter 返回 nil

Swift DateFormatter 不会根据预设的 Dateformat 转换日期

Swift DateFormatter 错误地转换字符串日期/时间

当我在英国地区将字符串转换为日期并且时区是马斯喀特时,DateFormatter 给了我不正确的结果

Dateformatter 返回零日期

快速从字符串转换为日期返回 nil