如何从swift xcode中的日期创建日期对象。
例如在javascript中你会这样做:
var day = new Date('2014-05-20');
答案 0 :(得分:188)
Swift有自己的Date
类型。无需使用NSDate
。
在Swift中,日期和时间存储在一个64位浮点数中,用于衡量自2001年1月1日00:00:00 UTC的参考日期以来的秒数。这在Date
structure中表示。以下内容将为您提供当前日期和时间:
let currentDateTime = Date()
要创建其他日期时间,您可以使用以下方法之一。
方法1
如果你知道2001年参考日期之前或之后的秒数,你可以使用它。
let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
方法2
当然,使用诸如年,月,日和小时(而不是相对秒)之类的东西来制作Date
会更容易。为此,您可以使用DateComponents
指定组件,然后使用Calendar
创建日期。 Calendar
提供Date
上下文。否则,它将如何知道在哪个时区或日历中表达?
// 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.current // user calendar
let someDateTime = userCalendar.date(from: dateComponents)
可以找到其他时区缩写here。如果将其留空,则默认为使用用户的时区。
方法3
最简洁的方式(但不一定是最好的)可能是DateFormatter
。
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
DateFormatter
支持的Unicode technical standards show other formats。
有关如何以可读格式显示日期和时间的信息,请参阅my full answer。另请阅读这些优秀的文章:
答案 1 :(得分:108)
最好使用现有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
,那么出于性能原因,您可能希望这样做。
请注意,如果您尝试通过传入无法正确解析的字符串来初始化NSDate
,则此实现将会崩溃。这是因为强制解包dateFromString
返回的可选值。如果你想在错误的解析上返回nil
,理想情况下你会使用一个失败的初始化器;但是你现在不能这样做(2015年6月),因为Swift 1.2的限制,所以接下来最好的选择是使用类工厂方法。
解决这两个问题的更详细的例子是:https://gist.github.com/algal/09b08515460b7bd229fa。
答案 2 :(得分:44)
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)
答案 3 :(得分:7)
这是我在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)
答案 4 :(得分:4)
示例:
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
答案 5 :(得分:4)
在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)
}
}
答案 6 :(得分:2)
我个人认为它应该是一个可用的初始化者:
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
}
}
}
否则格式无效的字符串将引发异常。
答案 7 :(得分:2)
根据@mythz的回答,我决定使用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
方法,但如果有人需要,我会更新此帖子。
答案 8 :(得分:1)
我经常需要将来自一个地方的日期值与另一个地方的时间值相结合。我写了一个辅助函数来完成这个。
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)!
答案 9 :(得分:0)
根据苹果公司的Data Formatting Guide
创建日期格式器并不便宜。如果你有可能 要经常使用格式化程序,通常更有效地进行缓存 一个实例比创建和处置多个实例要好。 一种方法是使用静态变量
虽然我同意@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 seed data
Date(dateLiteralString: "2020-03-30")
// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }