如何将“2021-05-23T12:09:18Z”转换为 6 月 23 日下午 12:09 的日期格式

时间:2021-04-02 16:40:24

标签: ios swift

这是下面的代码。我感谢任何帮助。谢谢!

let dateFormatter = DateFormatter()

dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
               
let convertedDate = dateFormatter.date(from: "2021-05-23T12:09:18Z")
             
print("Converted Date -- \(convertedDate)")

2 个答案:

答案 0 :(得分:0)

您已经正确定义了输入格式化程序,但您还需要另外两个格式化程序,一个用于输出的日期格式化程序和一个用于获取正确日期的格式化程序

let outputFormatter = DateFormatter()
outputFormatter.locale = .current
outputFormatter.timeZone = TimeZone(secondsFromGMT: 0)
outputFormatter.dateFormat = "MMMM hh:mm a"

let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .ordinal
numberFormatter.locale = .current

请注意,您需要为第二个日期格式化程序设置时区,并且它和数字格式化程序需要设置区域设置,我在这里使用用户当前的区域设置,因为这应该得到尊重。

有了这个设置,整个转换就变成了

if let convertedDate = dateFormatter.date(from: "2021-05-23T12:09:18Z") {
    let day = Calendar.current.component(.day, from: convertedDate)

    if let dayString = numberFormatter.string(from: day as NSNumber) {
        let output = "\(dayString) \(outputFormatter.string(from: convertedDate))"
        print(output)
    }
}

格式化月份的日期的解决方案取自this answer

使用英语语言环境的输出是

<块引用>

5 月 23 日下午 12:09

以及瑞典语语言环境的示例

<块引用>

23:e 少校 12:09 em

在@LeoDabus 发表评论后,我决定制作一个更本地化的版本,该版本尊重应该在月份之前还是之后打印日期。假设格式化程序和之前一样,并且已经声明了这个函数就可以使用

func formatDate(_ date: String, locale: Locale = .current) -> String? {
    outputFormatter.locale = locale
    numberFormatter.locale = locale
    guard let inputDate = dateFormatter.date(from: date) else {
        return nil }
    let dayOfMonth = Calendar.current.component(.day, from: inputDate)
    
    guard let ordinalDay = numberFormatter.string(for: dayOfMonth),
          let output = outputFormatter.string(for: inputDate) else {
        return nil }
    
    return output.replacingOccurrences(of: "\\b\(dayOfMonth)\\b",
                                       with: ordinalDay,
                                       options: .regularExpression)
}

简单的测试

for locale in [Locale(identifier: "en_US"), Locale(identifier: "sv_SE"),Locale(identifier: "pt_BR")] {
    if let date = formatDate("2021-05-23T12:09:18Z", locale: locale) {
        print("\(locale): \(date)")
    }
}
<块引用>

en_US(固定):2021 年 5 月 23 日
sv_SE(固定):23:e maj 2021
pt_BR(固定):23º de maio de 2021

如果我们要尊重用户完全选择的语言/格式等,那么我们将忽略序数处理

func formatDate(_ date: String, locale: Locale = .current) -> String? {
    outputFormatter.locale = locale
    numberFormatter.locale = locale
    guard let inputDate = dateFormatter.date(from: date) else {
        return nil }

    return outputFormatter.string(for: inputDate)
}

同样的测试会产生

<块引用>

en_US(固定):2021 年 5 月 23 日
sv_SE(固定):23 maj 2021
pt_BR(固定):23 de maio de 2021

答案 1 :(得分:-2)

这很简单,您需要第二个格式化程序,将您的 Date 格式化为字符串。示例代码

extension Date {
        func dateFormatWithSuffix() -> String {
            return "'\(self.daySuffix())' MMMM, h:mm a"
        }
    
        func daySuffix() -> String {
            let calendar = Calendar.current
            let components = (calendar as NSCalendar).components(.day, from: self)
            let dayOfMonth = components.day
            let numberFormatter = NumberFormatter()
            numberFormatter.numberStyle = .ordinal
            return numberFormatter.string(from: dayOfMonth as! NSNumber)!
        }
    }
    
    let dateFormatter = DateFormatter()
    
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
                   
    let convertedDate = dateFormatter.date(from: "2021-05-23T12:09:18Z")
    
    let dateFormatterNormal = DateFormatter()
    dateFormatterNormal.dateFormat = convertedDate?.dateFormatWithSuffix()
    dateFormatterNormal.locale = Locale(identifier: "en_US_POSIX")
    dateFormatterNormal.timeZone = TimeZone.current
    let endDate = dateFormatterNormal.string(from: convertedDate ?? Date())
    
    print("Converted Date -- \(endDate)")

Result
有关 dateFormat 的详细信息,请访问此 site 并转到参考
要添加 rd,您需要在 dateFormat 中的引号中添加 rd