swift 中的日期格式化程序崩溃
Date formatter crash in swift
请帮我修改这部分代码,
if let dateVaule = UserDefaults().value(forKey: SplashSeenDate){
let dateStr = dateVaule as! String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.ReferenceType.local
let date = dateFormatter.date(from:dateStr)
if Global.sharedInstance.Splashs != nil && Global.sharedInstance.Splashs?.count != 0{
for (i,splash) in (Global.sharedInstance.Splashs?.enumerated().reversed())!{
if !checkTimeStamp(date: splash.create_timestamp,StoredDate: date!){
Global.sharedInstance.Splashs?.remove(at: i)
}
}
print(Global.sharedInstance.Splashs?.count ?? "-1")
}
}
老实说,我对日期格式化程序很困惑。
当这个项目启动时,它在
发生崩溃
if !checkTimeStamp(date: splash.create_timestamp,StoredDate: date!){
但是,我无法重现此崩溃...**只有 iOS10 的少数用户发生此崩溃。**请指教,非常感谢!
func checkTimeStamp(date: String!,StoredDate: Date) -> Bool {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.locale = Locale(identifier:"en_US_POSIX")
let datecomponents = dateFormatter.date(from: date)
if (datecomponents! >= StoredDate) {
return true
} else {
return false
}
}
似乎 splash.create_timestamp
变为 nil,当您传入此函数时 checkTimeStamp
。它正在崩溃。您可以通过将 checkTimeStamp 函数内的日期参数更改为可选参数并在函数内部传递之前使用 guard 语句来防止崩溃。
您正在以两种不同的方式将 String
转换为 Date
:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.ReferenceType.local //###Why don't you use `TimeZone.current`?
let date = dateFormatter.date(from:dateStr)
在checkTimeStamp(date: String!,StoredDate: Date) -> Bool
中:
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.locale = Locale(identifier:"en_US_POSIX")
let datecomponents = dateFormatter.date(from: date)
在您的情况下,缺少此行对于您的首次转换至关重要:
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
您可以找到许多讨论 DateFormatter
(或旧文章中的 NSDateFormatter
)返回 nil
的文章。
当您使用 DateFormatter
和 "yyyy-MM-dd HH:mm:ss"
等固定格式时,您必须将 locale
设置为 Locale(identifier: "en_US_POSIX")
。
也许您最好定义一种转换方法(或计算 属性)以将 String
转换为适合您应用要求的 Date
,并在您需要的任何地方使用它 String
到 Date
转换:
extension String {
var toAppDate: Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.current
dateFormatter.locale = Locale(identifier: "en_US_POSIX") //### <- Do not miss.
return dateFormatter.date(from: self)
}
}
通常,您的代码使用了过多的强制解包或强制转换。你可以在不使用任何强制的东西的情况下重写它:
if
let dateStr = UserDefaults().string(forKey: SplashSeenDate),
let date = dateStr.toAppDate,
let splashes = Global.sharedInstance.Splashs, !splashes.isEmpty
{
//### In most cases, `filter` is faster than repeated `remove`.
Global.sharedInstance.Splashs = splashes.filter {
checkTimeStamp(date: [=14=].create_timestamp, storedDate: date)
}
print(Global.sharedInstance.Splashs?.count ?? "-1")
}
(假设 create_timestamp
不是可选的,并将参数标签 StoredDate:
重命名为 storedDate:
。)
请帮我修改这部分代码,
if let dateVaule = UserDefaults().value(forKey: SplashSeenDate){
let dateStr = dateVaule as! String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.ReferenceType.local
let date = dateFormatter.date(from:dateStr)
if Global.sharedInstance.Splashs != nil && Global.sharedInstance.Splashs?.count != 0{
for (i,splash) in (Global.sharedInstance.Splashs?.enumerated().reversed())!{
if !checkTimeStamp(date: splash.create_timestamp,StoredDate: date!){
Global.sharedInstance.Splashs?.remove(at: i)
}
}
print(Global.sharedInstance.Splashs?.count ?? "-1")
}
}
老实说,我对日期格式化程序很困惑。 当这个项目启动时,它在
发生崩溃if !checkTimeStamp(date: splash.create_timestamp,StoredDate: date!){
但是,我无法重现此崩溃...**只有 iOS10 的少数用户发生此崩溃。**请指教,非常感谢!
func checkTimeStamp(date: String!,StoredDate: Date) -> Bool {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.locale = Locale(identifier:"en_US_POSIX")
let datecomponents = dateFormatter.date(from: date)
if (datecomponents! >= StoredDate) {
return true
} else {
return false
}
}
似乎 splash.create_timestamp
变为 nil,当您传入此函数时 checkTimeStamp
。它正在崩溃。您可以通过将 checkTimeStamp 函数内的日期参数更改为可选参数并在函数内部传递之前使用 guard 语句来防止崩溃。
您正在以两种不同的方式将 String
转换为 Date
:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.ReferenceType.local //###Why don't you use `TimeZone.current`?
let date = dateFormatter.date(from:dateStr)
在checkTimeStamp(date: String!,StoredDate: Date) -> Bool
中:
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.locale = Locale(identifier:"en_US_POSIX")
let datecomponents = dateFormatter.date(from: date)
在您的情况下,缺少此行对于您的首次转换至关重要:
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
您可以找到许多讨论 DateFormatter
(或旧文章中的 NSDateFormatter
)返回 nil
的文章。
当您使用 DateFormatter
和 "yyyy-MM-dd HH:mm:ss"
等固定格式时,您必须将 locale
设置为 Locale(identifier: "en_US_POSIX")
。
也许您最好定义一种转换方法(或计算 属性)以将 String
转换为适合您应用要求的 Date
,并在您需要的任何地方使用它 String
到 Date
转换:
extension String {
var toAppDate: Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.current
dateFormatter.locale = Locale(identifier: "en_US_POSIX") //### <- Do not miss.
return dateFormatter.date(from: self)
}
}
通常,您的代码使用了过多的强制解包或强制转换。你可以在不使用任何强制的东西的情况下重写它:
if
let dateStr = UserDefaults().string(forKey: SplashSeenDate),
let date = dateStr.toAppDate,
let splashes = Global.sharedInstance.Splashs, !splashes.isEmpty
{
//### In most cases, `filter` is faster than repeated `remove`.
Global.sharedInstance.Splashs = splashes.filter {
checkTimeStamp(date: [=14=].create_timestamp, storedDate: date)
}
print(Global.sharedInstance.Splashs?.count ?? "-1")
}
(假设 create_timestamp
不是可选的,并将参数标签 StoredDate:
重命名为 storedDate:
。)