Truncate NSDate (Zero-out time)

前端 未结 6 883
孤街浪徒
孤街浪徒 2020-12-02 19:02

I want to generate a new NSDate with 0 hours, 0 minutes, and 0 seconds for time. The source date can be any r

相关标签:
6条回答
  • 2020-12-02 19:07

    I know its late, but there are now better methods: why dont you just use

    Swift 2

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

    Swift 3 would be something without the NS prefix ;)

    0 讨论(0)
  • 2020-12-02 19:15

    Use NSCalendar's rangeOfUnit:startDate:interval:forDate:. This code will choose the day boundary based on the current time zone. If you want a particular time zone, you need to create an NSCalendar and set its time zone appropriately.

    - (NSDate*)boundaryForCalendarUnit:(NSCalendarUnit)calendarUnit
    {
        NSDate *boundary;
        [[NSCalendar currentCalendar] rangeOfUnit:calendarUnit startDate:&boundary interval:NULL forDate:self];
        return boundary;
    }
    
    - (NSDate*)dayBoundary
    {
        return [self boundaryForCalendarUnit:NSDayCalendarUnit];
    }
    
    0 讨论(0)
  • 2020-12-02 19:18

    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)
        }
    }
    
    0 讨论(0)
  • 2020-12-02 19:21

    I would use the description method to get the given date as a string, then modify the string and create your new date with initWithString.

    initWithString: Returns an NSDate object initialized with a date and time value specified by a given string in the international string representation format.

    • (id)initWithString:(NSString *)description Parameters description A string that specifies a date and time value in the international string representation format—YYYY-MM-DD HH:MM:SS ±HHMM, where ±HHMM is a time zone offset in hours and minutes from GMT (for example, “2001-03-24 10:45:32 +0600”). You must specify all fields of the format string, including the time zone offset, which must have a plus or minus sign prefix. Return Value An NSDate object initialized with a date and time value specified by aString.
    0 讨论(0)
  • 2020-12-02 19:28

    With Swift 3, you can choose one of the four following patterns in order to solve your problem.


    #1. Using Calendar startOfDay(for:)

    startOfDay(for:) has the following declaration:

    func startOfDay(for date: Date) -> Date
    

    Returns the first moment of a given Date, as a Date.

    The Playground code below shows how to use this method:

    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. Using Calendar date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)

    date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:) has the following declaration:

    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?
    

    Returns a new Date representing the date calculated by setting hour, minute, and second to a given time on a specified Date.

    The Playground code below shows how to use this method:

    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. Using Calendar dateComponents(_:from:) and date(from:) methods

    dateComponents(_:from:) has the following declaration:

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

    Returns all the date components of a date, using the calendar time zone.

    date(from:) has the following declaration:

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

    Returns a date created from the specified components.

    The Playground code below shows how to use those methods:

    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. Using NSCalendar range(of:start:interval:for:)

    range(of:start:interval:for:) has the following declaration:

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

    Returns by reference the starting time and duration of a given calendar unit that contains a given date.

    The Playground code below shows how to use this method:

    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
    
    0 讨论(0)
  • 2020-12-02 19:31
    unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    NSCalendar* calendar = [NSCalendar currentCalendar];
    NSDateComponents* components = [calendar components:flags fromDate:date];
    NSDate* dateOnly = [calendar dateFromComponents:components];
    

    date is the date you want to remove the time from.

    This separates the date and time and creates a new date with the default time (00:00:00).

    EDIT

    To take time zone into account:

    NSDate* dateOnly = [[calendar dateFromComponents:components] dateByAddingTimeInterval:[[NSTimeZone localTimeZone]secondsFromGMT]];
    
    0 讨论(0)
提交回复
热议问题