截断NSDate(清零时间)

时间:2010-11-15 18:11:45

标签: objective-c nsdate truncate

我想生成一个新的NSDate 0小时 0分钟 0秒时间。源日期可以是任意随机NSDate

有没有办法实现这个目标?文档对此没有帮助。


示例

拥有:2010-10-30 10:14:13 GMT

想要:2010-10-30 00:00:00 GMT

6 个答案:

答案 0 :(得分:63)

unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:flags fromDate:date];
NSDate* dateOnly = [calendar dateFromComponents:components];

date是您要从中删除时间的日期。

这将分隔日期和时间,并使用默认时间(00:00:00)创建新日期。

修改

考虑时区:

NSDate* dateOnly = [[calendar dateFromComponents:components] dateByAddingTimeInterval:[[NSTimeZone localTimeZone]secondsFromGMT]];

答案 1 :(得分:17)

使用NSCalendar的rangeOfUnit:startDate:interval:forDate:。此代码将根据当前时区选择日期边界。如果您需要特定时区,则需要创建一个NSCalendar并适当设置其时区。

- (NSDate*)boundaryForCalendarUnit:(NSCalendarUnit)calendarUnit
{
    NSDate *boundary;
    [[NSCalendar currentCalendar] rangeOfUnit:calendarUnit startDate:&boundary interval:NULL forDate:self];
    return boundary;
}

- (NSDate*)dayBoundary
{
    return [self boundaryForCalendarUnit:NSDayCalendarUnit];
}

答案 2 :(得分:4)

使用Swift 3,您可以选择其中一种以下四种模式来解决您的问题。

#1。使用Calendar startOfDay(for:)

startOfDay(for:)有以下声明:

func startOfDay(for date: Date) -> Date
  

返回给定Date的第一个时刻,作为Date

下面的Playground代码显示了如何使用此方法:

import Foundation

let date = Date()

// Get new date
let calendar = Calendar.current
let newDate = calendar.startOfDay(for: date)

// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long

let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate)

// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST

#2。使用Calendar date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)

date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)有以下声明:

func date(bySettingHour hour: Int, minute: Int, second: Int, of date: Date, matchingPolicy: Calendar.MatchingPolicy = default, repeatedTimePolicy: Calendar.RepeatedTimePolicy = default, direction: Calendar.SearchDirection = default) -> Date?
  

返回一个新的Date,表示通过将小时,分钟和秒设置为指定Date上给定时间而计算的日期。

下面的Playground代码显示了如何使用此方法:

import Foundation

let date = Date()

// Get new date
let calendar = Calendar.current
let newDate = calendar.date(bySettingHour: 0, minute: 0, second: 0, of: date)

// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long

let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate!)

// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST

#3。使用Calendar dateComponents(_:from:)date(from:)方法

dateComponents(_:from:)有以下声明:

func dateComponents(_ components: Set<Calendar.Component>, from date: Date) -> DateComponents
  

使用日历时区返回日期的所有日期组件。

date(from:)有以下声明:

func date(from components: DateComponents) -> Date?
  

返回从指定组件创建的日期。

下面的Playground代码显示了如何使用这些方法:

import Foundation

let date = Date()

// Get new date
let calendar = Calendar.current
let components = calendar.dateComponents([.day, .month, .year], from: date)
let newDate = calendar.date(from: components)

// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long

let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate!)

// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST

#4。使用NSCalendar range(of:start:interval:for:)

range(of:start:interval:for:)有以下声明:

func range(of unit: NSCalendar.Unit, start datep: AutoreleasingUnsafeMutablePointer<NSDate?>?, interval tip: UnsafeMutablePointer<TimeInterval>?, for date: Date) -> Bool
  

通过引用返回包含给定日期的给定日历单元的开始时间和持续时间。

下面的Playground代码显示了如何使用此方法:

import Foundation

let date = Date()

// Get new date
let calendar = Calendar.current as NSCalendar
var newDate: NSDate?
calendar.range(of: .day, start: &newDate, interval: nil, for: date)

// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long

let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate as! Date)

// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST

答案 3 :(得分:2)

我知道它已经很晚了,但现在有更好的方法: 你为什么不使用

Swift 2

NSCalendar.currentCalendar().dateBySettingHour(0, minute: 0, second: 0, ofDate: yourDateToZeroOutTime, options: [])

Swift 3将是没有NS前缀的东西;)

答案 4 :(得分:1)

Swift 3

extension Date {
    func trimTime() -> Date {
        var boundary = Date()
        var interval: TimeInterval = 0
        _ = Calendar.current.dateInterval(of: .day, start: &boundary, interval: &interval, for: self)

        return Date(timeInterval: TimeInterval(NSTimeZone.system.secondsFromGMT()), since: boundary)
    }
}

答案 5 :(得分:0)

我会使用description方法将给定日期作为字符串,然后修改字符串并使用initWithString创建新日期。

initWithString: 返回使用国际字符串表示格式中给定字符串指定的日期和时间值初始化的NSDate对象。

  • (id)initWithString:(NSString *)description 参数 描述 以国际字符串表示格式-YYYY-MM-DD HH:MM:SS±HHMM指定日期和时间值的字符串,其中±HHMM是GMT小时和分钟的时区偏移量(例如,“2001-” 03-24 10:45:32 +0600“)。 您必须指定格式字符串的所有字段,包括时区偏移量,该字段必须具有加号或减号前缀。 回报价值 使用aString指定的日期和时间值初始化的NSDate对象。