如果给定的日期格式发生变化,如何格式化日期字符串

How to format date string if the given date format changes

我从 api 收到了日期字符串的回复,它的格式有时会发生变化,所以我需要对其进行动态格式化,

这是我的代码

import Foundation

func format(from: String?, fromFormat: String, to: String) -> String {
    if from == nil { return "" }
    let inputDateFormatter = DateFormatter()
    inputDateFormatter.dateFormat = fromFormat
    let date = inputDateFormatter.date(from: from ?? "")
    
    let outputDateFormatter = DateFormatter()
    outputDateFormatter.dateFormat = to
    if let date = date {
        return outputDateFormatter.string(from: date)
    }
    return "not formatted"
}

let strFromApi = "2020-12-22"

print(format(from: strFromApi, fromFormat: "yyyy-MM-dd", to: "d MMM yyyy"))

如你所见,我那里有一个代码可以成功格式化,这里的问题是 strFromApi 变量来自 api,并且在 2020-12-222020-12-22 之间变化2020-12-22 00:00:00,当变成2020-12-22 00:00:00的时候,我现在的代码已经格式化不了了

问题:即使服务器给定的格式有时间,我如何格式化它?

您可以创建两个日期格式化程序,一个有时间,另一个没有时间,并使用 nil 合并运算符提供后备,以防第一个失败。关于返回最终字符串时的日期格式,您应该尊重用户的设备区域设置和设置。向用户显示日期时只需使用 dateStyle 和 timeStyle:

extension Formatter {
    static let date: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()
    static let dateAndTime: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter
    }()
    static let localizedDate: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .none
        return formatter
    }()
}

extension Date {
    var localizedDate: String { Formatter.localizedDate.string(from: self) }
}

func formatted(from string: String?) -> String {
    guard 
        let string = string,
        let date = Formatter.dateAndTime.date(from: string) ??
                   Formatter.date.date(from: string)
    else { return "" }
    
    return date.localizedDate
}

let strFromApi = "2020-12-22 00:00:00" // "2020-12-22" //
formatted(from: strFromApi)  // "Dec 22, 2020"