强制转换"1900-01-01T00:00:00"字符串值到日期



我一直在看槽堆栈溢出以找到答案,但找不到它我想将此字符串值"1900-01-01T00:00:00"转换为Date格式,我正在尝试使用一些格式,例如:

"yyyy-MM-dd HH:mm:ss"
"EEE, dd MMM yyyy hh:mm:ss +zzzz"
"YYYY-MM-dd HH:mm:ss.A"
"yyyy-MM-dd HH:mm:ss.S"   

但任何那些它的工作。 我想要这样的日期格式

"dd-mm-yyyy"

希望你能帮助我!

谢谢。

这是一个两步过程,首先将1900-01-01T00:00:00(称为 RFC 3999 或 ISO 8601 日期,指的是定义此格式的规范)转换为Date对象,然后将该Date对象转换回01-01-1900形式的字符串:

  1. 要将1900-01-01T00:00:00形式的字符串转换为Date对象,可以使用ISO8601DateFormatter

    let formatter = ISO8601DateFormatter()
    formatter.formatOptions.remove(.withTimeZone)
    let date = formatter.date(from: string)!
    
    这相当于以下DateFormat,其中必须手动将locale设置为en_US_POSIX

    (因为 RFC 3999/ISO 8601 日期使用公历,无论设备的默认日历类型如何)并将timeZone设置为 GMT/祖鲁语,因为通常 RFC 3999/ISO 8601 日期代表 GMT,除非另有说明:

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    let date = formatter.date(from: string)!
    

    有关时区和区域设置在解析 RFC 3999 和 ISO 8601 日期时的重要性的更多信息,请参阅 Apple 的技术问答 1480。

  2. 然后,要将Date对象转换为字符串01-01-1900(日、月和年),请使用dd-MM-yyyy格式字符串(请注意"月"的大写MM,以区别于"分钟"的mm):

    let formatter2 = DateFormatter()
    formatter2.dateFormat = "dd-MM-yyyy"
    let string = formatter2.string(from: date)
    

    关于dateFormat字符串的两个观察结果:

    • 如果此字符串用于向用户显示,则可以使用 usedateStyle而不是dateFormat,例如:

      formatter2.dateStyle = .short
      

      虽然这将生成略有不同的格式,例如dd/MM/yy,这种方法的优点是字符串将被本地化(例如,英国用户将看到MM/dd/yyyy,他们首选的查看短日期的方式)。

      这仅取决于您dd-MM-yyyy格式的目的。如果用于内部目的,请继续使用dateFormat。但是,如果是为了在UI中显示日期,请改用dateStyle,并享受DateFormatter自动为您执行的本地化。有关详细信息,请参阅DateFormatter参考的"使用日期和时间的用户可见表示形式"部分。

    • 请注意,如果没有为第二个格式化程序指定timeZone,则假定当 ISO 8601 日期为 GMT 时,您希望查看本地时区的日期。例如,(格林威治标准时间1900-01-01T00:00:001899 年 12 月 31 日下午 4 点在加利福尼亚州)。如果您想查看原始 ISO 8601 对象的日期字符串,而不是针对时区进行更正,您只需将第二个格式化程序的timeZone也设置为 GMT,例如

      formatter2.timeZone = TimeZone(secondsFromGMT: 0)
      

正如其他人所指出的,您希望避免不必要地重新实例化DateFormatter对象。因此,您可以将这些格式化程序放在仅实例化一次的属性中,或使用extension

extension DateFormatter {
static let customInputFormatter: ISO8601DateFormatter = {
let formatter = ISO8601DateFormatter()
formatter.formatOptions.remove(.withTimeZone)
return formatter
}()
static let customOutputFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
formatter.timeZone = TimeZone(secondsFromGMT: 0)  // if you want date in your local timezone, remove this line
return formatter
}()
}

然后:

let input = "1900-01-01T00:00:00"
let date = DateFormatter.customInputFormatter.date(from: input)!
let output = DateFormatter.customOutputFormatter.string(from: date)
print(output)

这是我自定义日期格式化程序的方式:

extension DateFormatter {
static let inDateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
return dateFormatter
}()
static let outDateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-mm-yyyy"
return dateFormatter
}()
}

然后像这样使用它:

if let date = DateFormatter.inDateFormatter.date(from: "1900-01-01T00:00:00") {
let newDateString = DateFormatter.outDateFormatter.string(from: date);
print(newDateString) //prints 01-00-1900
}

这避免了任何潜在的性能问题,并且在使用时一目了然,同时仍然简洁明了。

使用我创建的这个扩展,您可以在其中将格式作为参数传递。

extension String
{
func  toDate( dateFormat format  : String) -> Date
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
if let date = dateFormatter.date(from: self)
{
return date
}
print("Invalid arguments ! Returning Current Date . ")
return Date()
}
}
"1900-01-01T00:00:00".toDate(dateFormat: "yyyy-MM-dd'T'HH:mm:ss")  //Plyground call test

最新更新