2017-10-12 46 views
0

我需要将日期初始化为已知的固定时间点。斯威夫特缺乏日期文字,我想:Swift日期文字/字符串日期初始化

extension DateFormatter 
{ 
    convenience init(_ format: String) 
    { 
     self.init() 
     self.dateFormat = format 
    } 
} 

extension Date 
{ 
    init?(_ yyyyMMdd: String) 
    { 
     let formatter = DateFormatter("yyyyMMdd") 
     self = formatter.date(from: yyyyMMdd) 
    } 
} 

不幸的是,我不能写self = ...return formatter.date...作为初始化的一部分。

不过,我很想写:

let date = Date("20120721") 

我怎样才能做到这一点?

+0

注意,它应该是'MM'为一个月的日期格式字符串 –

回答

3

可以通过为self赋值来初始化struct。 你的情况的问题是,formatter.date(from:) 返回一个可选的,所以你必须打开那首:

extension Date { 
    init?(yyMMdd: String) { 
     let formatter = DateFormatter("yyyyMMdd") 
     guard let date = formatter.date(from: yyMMdd) else { 
      return nil 
     } 
     self = date 
    } 
} 

,你甚至可以通过 初始化从一个字符串的日期采用ExpressibleByStringLiteral协议:

extension Date: ExpressibleByStringLiteral { 
    public init(stringLiteral value: String) { 
     let formatter = DateFormatter("yyyyMMdd") 
     self = formatter.date(from: value)! 
    } 
    public init(extendedGraphemeClusterLiteral value: String) { 
     self.init(stringLiteral: value) 
    } 
    public init(unicodeScalarLiteral value: String) { 
     self.init(stringLiteral: value) 
    } 

} 

let date: Date = "20120721" 

但请注意,这将在运行时崩溃无效的日期。

两个以上的评论:

  • 您应该设置格式化语言环境Locale(identifier: "en_US_POSIX")允许解析日期字符串独立的 用户的区域设置。
  • 结果取决于当前的时区,除非你也 设置格式化时区为固定值(如TimeZone(secondsFromGMT: 0)
+0

嗯,那太棒了!我知道我实际上可以为结构赋值自己(不会改变指针吗?),并且有一个ExpressibleByStringLiteral协议,超出了我的期望。谢谢!!!! – Adeline

+0

@Adeline:有没有指针结构是一个*值*类型 –

+0

我想进一步强调Martin的最后一点 - 那些至少需要用粗体,下划线,斜体,至少为42pt的字体,因为你会看到失败在语言环境中解析/时区,您在运行时没有考虑过。日期格式是高度区域设置/日历/时区敏感的,默认情况下使用用户当前的值。 –