【问题标题】:Date formatter from string swift [duplicate]来自字符串 swift 的日期格式化程序 [重复]
【发布时间】:2020-08-02 11:52:28
【问题描述】:

我需要将这个字符串 2020-03-18T00:00:00 转换成这样的日期 2020.03.18 00:00 当我尝试像这样转换时,我的应用程序崩溃了。

public extension String {

    var dateValue: Date {
        let formatter = DateFormatter()
        formatter.timeZone = .none
        formatter.dateFormat = "yyyy-MM-dd HH:mm"
        return formatter.date(from: self)!
    }

}

有什么想法吗?

【问题讨论】:

    标签: swift string date swift5 formatter


    【解决方案1】:

    您的日期格式化程序需要包含“T”

    dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'"
    

    【讨论】:

    • 这个解决方案给我2020-03-17 17:00:00 +0000,但我需要2020-03-17 17:00。其中输入字符串为2020-03-18T00:00:00
    【解决方案2】:

    问题在于这段代码使用了yyyy-MM-dd HH:mmdateFormat 字符串,但这不是实际的输入字符串。它是yyyy-MM-dd'T'HH:mm:ss。因此到Date 对象的转换失败,强制解包会导致它崩溃。

    相反,我建议使用一种格式化程序将2020-03-18T00:00:00 的ISO8601 格式转换为Date 对象。然后,如果您想要2020.03.18 00:00 格式的字符串,您将有一个单独的格式化程序。

    如果 ISO8601 日期字符串中没有明确的时区,则假定为本地时区。所以根本不要指定timeZone 属性。 (您通常会指定它的唯一时间是 Zulu/GMT/UTC,即TimeZone(secondsFromGMT: 0)。)

    例如

    let iso8601Formatter = DateFormatter()
    iso8601Formatter.locale = Locale(identifier: "en_US_POSIX")
    iso8601Formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "yyyy.MM.dd HH:mm"
    
    func convert(input: String) -> String? {
        guard let date = iso8601Formatter.date(from: input) else { return nil }
        return formatter.string(from: date)
    }
    
    let result = convert(input: "2020-03-18T00:00:00") // "2020.03.18 00:00"
    

    注意,格式化程序的实例化(以及 dateFormat 字符串的更改)是一个众所周知的计算密集型过程,这就是为什么我使用这些格式化程序属性而不是局部变量的原因。显然,您可以随意命名它们并将它们放在您想要的任何位置,但请确保避免重复实例化这些格式化程序或更改 dateFormat 字符串。

    【讨论】:

    • 是的!这解决了我的问题!
    猜你喜欢
    • 2020-11-07
    • 1970-01-01
    • 2012-01-07
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多