一尘不染

如何将NSDate对象设置为午夜?

swift

我有一个NSDate对象,我想将它设置为任意时间(比如半夜),这样我可以使用timeIntervalSince1970的功能一致,而不用担心时间来检索数据
创建的对象。

我尝试使用NSCalendar和通过一些Objective-C方法修改其组件,如下所示:

let date: NSDate = NSDate()
let cal: NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!

let components: NSDateComponents = cal.components(NSCalendarUnit./* a unit of time */CalendarUnit, fromDate: date)
let newDate: NSDate = cal.dateFromComponents(components)

上述方法的问题在于,您只能设置一个时间单位(/* a unit of time */),因此您只能精确地选择以下其中一项:

  1. 小时
  2. 分钟

有没有办法同时设置小时,分钟和秒并保留日期(日/月/年)?


阅读 227

收藏
2020-07-07

共1个答案

一尘不染

您的声明

上述方法的问题是您只能设置一个时间单位…

是不正确的。NSCalendarUnit符合RawOptionSetType继承自的协议BitwiseOperationsType。这意味着可以将选项与&和进行按位组合|

Swift 2(Xcode 7)中, 它再次更改为OptionSetType提供类似集合的接口。

因此,以下代码可以在iOS 7和iOS 8中编译并运行:

let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!

// Swift 1.2:
let components = cal.components(.CalendarUnitDay | .CalendarUnitMonth | .CalendarUnitYear, fromDate: date)
// Swift 2:
let components = cal.components([.Day , .Month, .Year ], fromDate: date)

let newDate = cal.dateFromComponents(components)

(请注意,我省略了变量的类型注释,Swift编译器会从赋值右侧的表达式自动推断类型。)

也可以使用rangeOfUnit()方法(iOS 7和iOS 8)确定给定日期(午夜)的开始:

let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
var newDate : NSDate?

// Swift 1.2:
cal.rangeOfUnit(.CalendarUnitDay, startDate: &newDate, interval: nil, forDate: date)
// Swift 2:
cal.rangeOfUnit(.Day, startDate: &newDate, interval: nil, forDate: date)

如果 您的部署目标是iOS 8,那么它甚至更简单:

let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let newDate = cal.startOfDayForDate(date)

Swift 3(Xcode 8) 更新

let date = Date()
let cal = Calendar(identifier: .gregorian)
let newDate = cal.startOfDay(for: date)
2020-07-07