Ios 如何创建Swift日期对象?

Ios 如何创建Swift日期对象?,ios,iphone,swift,nsdate,Ios,Iphone,Swift,Nsdate,如何从swift xcode中的日期创建日期对象 例如,在javascript中,您可以执行以下操作: var日=新日期('2014-05-20')根据 例如: var myObject = NSDate() let futureDate = myObject.dateByAddingTimeInterval(10) let timeSinceNow = myObject.timeIntervalSinceNow Swift没有自己的日期类型,但您需要使用现有的CocoaNSDate类型,例如

如何从swift xcode中的日期创建日期对象

例如,在javascript中,您可以执行以下操作:
var日=新日期('2014-05-20')

根据

例如:

var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow

Swift没有自己的日期类型,但您需要使用现有的Cocoa
NSDate
类型,例如:

class Date {

    class func from(year: Int, month: Int, day: Int) -> Date {
        let gregorianCalendar = NSCalendar(calendarIdentifier: .gregorian)!

        var dateComponents = DateComponents()
        dateComponents.year = year
        dateComponents.month = month
        dateComponents.day = day

        let date = gregorianCalendar.date(from: dateComponents)!
        return date
    }

    class func parse(_ string: String, format: String = "yyyy-MM-dd") -> Date {
        let dateFormatter = DateFormatter()
        dateFormatter.timeZone = NSTimeZone.default
        dateFormatter.dateFormat = format

        let date = dateFormatter.date(from: string)!
        return date
    }
}
您可以像这样使用:

var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)

这最好使用现有的
NSDate
类的扩展来完成

以下扩展添加了一个新的初始值设定项,该初始值设定项将使用指定格式的日期字符串在当前区域设置中创建日期

extension NSDate
{
    convenience
      init(dateString:String) {
      let dateStringFormatter = NSDateFormatter()
      dateStringFormatter.dateFormat = "yyyy-MM-dd"
      dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
      let d = dateStringFormatter.dateFromString(dateString)!
      self.init(timeInterval:0, sinceDate:d)
    }
 }
现在,您只需执行以下操作即可从Swift创建NSDate:

NSDate(dateString:"2014-06-06")
请注意,此实现不缓存NSDateFormatter,如果希望以这种方式创建多个
NSDate
s,出于性能原因,您可能希望这样做

extension Date
{
    init(dateString:String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        dateStringFormatter.locale = Locale(identifier: "en_US_POSIX")
        let d = dateStringFormatter.date(from: dateString)!
        self(timeInterval:0, since:d)
    }
}
还请注意,如果您试图通过传入无法正确解析的字符串来初始化
NSDate
,则此实现将崩溃。这是因为强制展开了由
dateFromString
返回的可选值。如果你想在错误的解析中返回一个
nil
,你最好使用一个容易出错的初始值设定项;但由于Swift 1.2的限制,现在(2015年6月)不能这样做,所以接下来最好的选择是使用类工厂方法

下面是一个更详细的示例,它解决了这两个问题:


Swift 5的更新
延期日期{
init(uDateString:String){
让dateStringFormatter=DateFormatter()
dateStringFormatter.dateFormat=“yyyy-MM-dd”
dateStringFormatter.locale=NSLocale(localeIdentifier:“en_US_POSIX”)作为区域设置
让date=dateStringFormatter.date(from:dateString)!
self.init(时间间隔:0,自:日期)
}
}

我经常需要将一个地方的日期值与另一个地方的时间值结合起来。我编写了一个助手函数来实现这一点

let startDateTimeComponents = NSDateComponents()
startDateTimeComponents.year = NSCalendar.currentCalendar().components(NSCalendarUnit.Year, fromDate: date).year
startDateTimeComponents.month = NSCalendar.currentCalendar().components(NSCalendarUnit.Month, fromDate: date).month
startDateTimeComponents.day = NSCalendar.currentCalendar().components(NSCalendarUnit.Day, fromDate: date).day
startDateTimeComponents.hour = NSCalendar.currentCalendar().components(NSCalendarUnit.Hour, fromDate: time).hour
startDateTimeComponents.minute = NSCalendar.currentCalendar().components(NSCalendarUnit.Minute, fromDate: time).minute
let startDateCalendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
combinedDateTime = startDateCalendar!.dateFromComponents(startDateTimeComponents)!
Swift有自己的日期类型。无需使用
NSDate

在Swift中创建日期和时间 在Swift中,日期和时间存储在一个64位浮点数中,用于测量自参考日期2001年1月1日00:00:00以来的秒数。这一点可以用以下方式表达:。以下内容将为您提供当前日期和时间:

let currentDateTime = Date()
要创建其他日期时间,可以使用以下方法之一

方法1

如果您知道2001年参考日期之前或之后的秒数,您可以使用它

let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
方法2

当然,使用年、月、日和小时(而不是相对秒)来创建
日期将更容易。为此,您可以使用
DateComponents
指定组件,然后使用
Calendar
创建日期。
日历
提供了
日期
上下文。否则,它怎么知道用什么时区或日历来表达呢

// Specify date components
var dateComponents = DateComponents()
dateComponents.year = 1980
dateComponents.month = 7
dateComponents.day = 11
dateComponents.timeZone = TimeZone(abbreviation: "JST") // Japan Standard Time
dateComponents.hour = 8
dateComponents.minute = 34

// Create date from components
let userCalendar = Calendar(identifier: .gregorian) // since the components above (like year 1980) are for Gregorian
let someDateTime = userCalendar.date(from: dateComponents)
还可以找到其他时区缩写。如果将该选项留空,则默认设置为使用用户的时区

方法3

最简洁的方法(但不一定是最好的)是使用
DateFormatter

let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
DateFormatter
支持的

笔记 有关如何以可读格式显示日期和时间的信息,请参见。请阅读以下优秀文章:


在Swift 3.0中,您已经用这种方式设置了日期对象

extension Date
{
    init(dateString:String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        dateStringFormatter.locale = Locale(identifier: "en_US_POSIX")
        let d = dateStringFormatter.date(from: dateString)!
        self(timeInterval:0, since:d)
    }
}

我个人认为它应该是一个失败的初始化器:

extension Date {

    init?(dateString: String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        if let d = dateStringFormatter.date(from: dateString) {
            self.init(timeInterval: 0, since: d)
        } else {
            return nil
        }
    }
}

否则,格式无效的字符串将引发异常。

根据@mythz answer,我决定使用
swift3
语法发布其扩展名的更新版本

extension Date {
    static func from(_ year: Int, _ month: Int, _ day: Int) -> Date?
    {
        let gregorianCalendar = Calendar(identifier: .gregorian)
        let dateComponents = DateComponents(calendar: gregorianCalendar, year: year, month: month, day: day)
        return gregorianCalendar.date(from: dateComponents)
    }
}

我不使用
parse
方法,但如果有人需要,我会更新这篇文章。

以下是我在Swift 4.2中如何做到的:

extension Date {

    /// Create a date from specified parameters
    ///
    /// - Parameters:
    ///   - year: The desired year
    ///   - month: The desired month
    ///   - day: The desired day
    /// - Returns: A `Date` object
    static func from(year: Int, month: Int, day: Int) -> Date? {
        let calendar = Calendar(identifier: .gregorian)
        var dateComponents = DateComponents()
        dateComponents.year = year
        dateComponents.month = month
        dateComponents.day = day
        return calendar.date(from: dateComponents) ?? nil
    }
}
用法:

let marsOpportunityLaunchDate = Date.from(year: 2003, month: 07, day: 07)
根据苹果公司的

创建日期格式化程序不是一个便宜的操作。如果你有可能 要经常使用格式化程序,缓存通常更有效 一个实例,而不是创建和处置多个实例。 一种方法是使用静态变量

虽然我同意@Leon的观点,这最好是一个可失败的初始值设定项,但它并不总是必须如此(就像有
UIImage(imageLiteralResourceName:)
如果资源不存在就会崩溃)

因此,我的方法如下:

extension DateFormatter {
  static let yyyyMMdd: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    formatter.calendar = Calendar(identifier: .iso8601)
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.locale = Locale(identifier: "en_US_POSIX")
    return formatter
  }()
}

extension Date {
    init?(yyyyMMdd: String) {
        guard let date = DateFormatter.yyyyMMdd.date(from: yyyyMMdd) else { return nil }
        self.init(timeInterval: 0, since: date)
    }

    init(dateLiteralString yyyyMMdd: String) {
        let date = DateFormatter.yyyyMMdd.date(from: yyyyMMdd)!
        self.init(timeInterval: 0, since: date)
    }
}
现在,请享受简单的呼叫:

// For cases where the date exists for sure (eg. seed data)
Date(dateLiteralString: "2020-03-30")

// The rest of the time (eg. parsing unknown data)
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }

使用
NSDate
就像在Objective-C中一样?很好,但不回答问题,问题不是关于时间间隔。那么“方便”一词在这里是什么意思?它表示扩展提供了一个初始值设定项,该初始值设定项实际上将初始化委托给已经存在的指定初始值设定项,在本例中,它是NSDate.init(时间间隔:,sinceDate:)初始值设定项。Swift编程语言手册第275页对此进行了描述。我在上面代码中看到的一个缺陷是每次访问函数时都重新创建
NSDateFormatter
。正如各州所说,创建日期格式化程序并不是一项廉价的操作。此外,自iOS7以来,该类是线程安全的,因此可以安全地将其用于所有
NSDate
扩展。@eugenedubinin正确。这就是为什么我说“此实现不缓存NSDateFormatter,这可能是出于性能原因。”Swift 1.2中的限制是什么?“failable initializer”功能已经失效。我不得不更改行:var date=gregorian?.dateFromComponents(c),但我不明白为什么,解析返回日期fmt.dateFromString也在抱怨。有什么线索吗?啊,我已经将函数的返回类型从NSDate更改为NSDate了?这让它可以编译。但我不确定为什么它需要为null。@senator NSCalendar init返回可选(?)因此gregorian是可选(?)。访问一个可选的需要到可选的链接来访问它所以grego