【问题标题】:Why date formatter crashes?为什么日期格式化程序崩溃?
【发布时间】:2018-09-05 06:19:41
【问题描述】:

我下面的代码工作正常。 我不知道为什么它有时会崩溃(主要是在应用程序启动时。大约 100 例中有 1 例)。

extension Formatter {
    static let enUSPOSIX: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")//
        return formatter
    }()
}


let dateFormatter = Formatter.enUSPOSIX
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss+hh:mm"
let date = dateFormatter.date(from: "2018-05-13T00:00:00+05:30")
dateFormatter.timeZone = TimeZone(identifier: "UTC")
let calendar = Calendar.current
let dayComponent = calendar.component(.year, from: date!)//crashes here sometime
print(dayComponent)

【问题讨论】:

  • 我建议查找unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns+hh:mm 不是时区的正确模式。
  • @MartinR:很好,但你能解释一下为什么它只是偶尔崩溃,而不是所有时间。
  • @QuocNguyen:实际上提供的示例在我的测试中 not 崩溃,因为 +05:30 匹配 +hh:mm(05 恰好是 1-12 中的有效小时小时格式)。例如,-05:30+13:00 会崩溃,因为它们与模式不匹配。
  • @MartinR 感谢您的解释。提供的示例在我的测试中也没有崩溃:D
  • @MartinR 谢谢。是TimeZone(identifier 应该是TimeZone(abbreviation 吗?

标签: ios swift nsdate nsdateformatter


【解决方案1】:

基本上你的日期格式是错误的。时区+05:30ZZZZZ不是+hh:mm,请阅读unicode.org Date Format Patterns

 dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"

编辑:

对于这种标准的 ISO8601 格式,我更喜欢ISO8601DateFormatter

let dateFormatter = ISO8601DateFormatter()
let date = dateFormatter.date(from: "2018-05-13T00:00:00+05:30")

【讨论】:

  • 对不起请解释如何决定ZZZZZ
  • @ameyrane 来自上述文档:具有小时、分钟和可选秒字段的 ISO8601 扩展格式。本地时间偏移量为 0 时使用 ISO8601 UTC 指示符“Z”
  • @Rob 我认为+0530 是为X 而不是+05:30
  • 当我使用 "yyyy-MM-dd'T'HH:mm:ssZZZZZ" 时它会崩溃(有时)请帮忙 :(
  • 什么日期会崩溃?
【解决方案2】:

在我的一个应用程序上进行测试时遇到了同样的问题

let dateFormatter = Formatter.enUSPOSIX
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss+hh:mm"
let date = dateFormatter.date(from: "2018-05-13T00:00:00+05:30")
dateFormatter.timeZone = TimeZone(identifier: "UTC")
let calendar = Calendar.current
let dayComponent = calendar.component(.year, from: date!)

这是崩溃,因为日期对象是 nil,所以当在 dayComponent 行中展开日期时,这会崩溃。试试这个

let dateFormatter = Formatter.enUSPOSIX
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss+hh:mm"
if let date = dateFormatter.date(from: "2018-05-13T00:00:00+05:30"){
   dateFormatter.timeZone = TimeZone(identifier: "UTC")
   let calendar = Calendar.current
   let dayComponent = calendar.component(.year, from: date!)
}else{
  dateFormatter.dateFormat = "yyyy-MM-dd'T'hh:mm:ss+hh:mm" // Date as 12 hour  
 if let date = dateFormatter.date(from: "2018-05-13T00:00:00+05:30"){
   dateFormatter.timeZone = TimeZone(identifier: "UTC")
  let calendar = Calendar.current
  let dayComponent = calendar.component(.year, from: date!)
} else{
   print("Cannot format Date")
 }
}

【讨论】:

    【解决方案3】:

    今天我遇到了完全相同的问题。由于open func date(from string: String) -> Date? 上的强制解包,应用程序在生产中随机崩溃

    我的代码如下所示:

    let creationDate: Date = {
        let dateFormatter = DateFormatter()
        return dateFormatter.date(from: "19-06-2018 14:00")!
    }()
    

    经过调查,我意识到只有在设备设置中设置了 12 小时日期格式的设备才会出现崩溃。在这些情况下,14:00 不存在,因为它应该是“2:00PM”。

    只需更改代码即可解决该问题:

    let creationDate: Date = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "dd-MM-yyyy HH:mm"
        dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    
        return dateFormatter.date(from: "19-06-2018 14:00")!
    }()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-10
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多