NSDate从一天开始到一天结束

use*_*028 93 nsdate nsdatecomponents ios

    -(NSDate *)beginningOfDay:(NSDate *)date
{
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];

    [components setHour:0];
    [components setMinute:0];
    [components setSecond:0];

    return [cal dateFromComponents:components];

}

-(NSDate *)endOfDay:(NSDate *)date
{
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:(  NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];

    [components setHour:23];
    [components setMinute:59];
    [components setSecond:59];

    return [cal dateFromComponents:components];

}
Run Code Online (Sandbox Code Playgroud)

当我打电话:[self endOfDay:[NSDate date]]; 我得到了本月的第一天......为什么?我使用这两种方法,因为我需要一个从第一个日期的第一秒开始的间隔(beginningOfDay:date1)到第二个日期的最后一秒(endOfDay:Date2)......

Zel*_*lko 199

开始日/结束日 - 斯威夫特4

  // Extension

extension Date {
    var startOfDay: Date {
        return Calendar.current.startOfDay(for: self)
    }

    var endOfDay: Date {
        var components = DateComponents()
        components.day = 1
        components.second = -1
        return Calendar.current.date(byAdding: components, to: startOfDay)!
    }

    var startOfMonth: Date {
        let components = Calendar.current.dateComponents([.year, .month], from: startOfDay)
        return Calendar.current.date(from: components)!
    }

    var endOfMonth: Date {
        var components = DateComponents()
        components.month = 1
        components.second = -1
        return Calendar.current.date(byAdding: components, to: startOfMonth)!
    }
}

// End of day = Start of tomorrow minus 1 second
// End of month = Start of next month minus 1 second
Run Code Online (Sandbox Code Playgroud)

  • 很棒的图书馆 (7认同)
  • 对于一天的开始,使用[[NSCalendar currentCalendar] startOfDayForDate:...] for iOS8 + (6认同)
  • 这将返回当前时区的startOfDay!NSDate预期采用UTC,但是此转换器返回的是针对默认时区的校正时间。 (4认同)
  • 为什么endOfDay是可选的?是否存在startOfDay不为零的情况,而endOfDay可能为零? (3认同)
  • 因此,根据您如何使用它,您介意一天的结束和开始之间有一秒钟的间隙 https://developer.apple.com/documentation/foundation/nsdate/1409748-compare?language=swift (2认同)

Jaa*_*iim 31

你错过NSDayCalendarUnit

NSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
Run Code Online (Sandbox Code Playgroud)

  • 我有一个奇怪的行为,如果我添加天组件,我会得到前一天的 23:00。 (2认同)
  • @Mike使用时区:components.timeZone = [NSTimeZone timeZoneWithName:@"GMT"]; (2认同)

Aug*_*Lin 24

Swift 4 简单而精确的答案.

开始时间:00:00:00

结束时间:23:59:59.5

let date = Date() // current date or replace with a specific date
let calendar = Calendar.current
let startTime = calendar.startOfDay(for: date)
let endTime = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: date)
Run Code Online (Sandbox Code Playgroud)

  • 这和`let dateAtEnd = Calendar.current.date(bySettingHour:23,minutes:59,second:59,of:Date())有什么不同? (2认同)

Bry*_*yce 21

在iOS 8+中,这非常方便; 你可以做:

let startOfDay = NSCalendar.currentCalendar().startOfDayForDate(date)
Run Code Online (Sandbox Code Playgroud)

为了结束一天的结束,只需使用NSCalendar方法23小时59分59秒,具体取决于您如何定义一天结束.

// Swift 2.0
let components = NSDateComponents()
components.hour = 23
components.minute = 59
components.second = 59
let endOfDay = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: startOfDay, options: NSCalendarOptions(rawValue: 0))
Run Code Online (Sandbox Code Playgroud)

日期数学

Apple iOS NSCalendar文档.(参见章节:日历计算)

NSHipster讨论了NSCalendar方法.


Lib*_*tal 16

我对NSDate的Swift扩展:

Swift 1.2

extension NSDate {

    func beginningOfDay() -> NSDate {
        var calendar = NSCalendar.currentCalendar()
        var components = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: self)
        return calendar.dateFromComponents(components)!
    }

    func endOfDay() -> NSDate {
        var components = NSDateComponents()
        components.day = 1
        var date = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.beginningOfDay(), options: .allZeros)!
        date = date.dateByAddingTimeInterval(-1)!
        return date
    }
}
Run Code Online (Sandbox Code Playgroud)

Swift 2.0

extension NSDate {

    func beginningOfDay() -> NSDate {
        let calendar = NSCalendar.currentCalendar()
        let components = calendar.components([.Year, .Month, .Day], fromDate: self)
        return calendar.dateFromComponents(components)!
    }

    func endOfDay() -> NSDate {
        let components = NSDateComponents()
        components.day = 1
        var date = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.beginningOfDay(), options: [])!
        date = date.dateByAddingTimeInterval(-1)
        return date
    }
}
Run Code Online (Sandbox Code Playgroud)


Ben*_*Ben 12

Swift 4.2 - XCode 10Date类而不是NSDateCalender不是NSCalender

extension Date {

    var startOfDay : Date {
        let calendar = Calendar.current
        let unitFlags = Set<Calendar.Component>([.year, .month, .day])
        let components = calendar.dateComponents(unitFlags, from: self)
        return calendar.date(from: components)!
   }

    var endOfDay : Date {
        var components = DateComponents()
        components.day = 1
        let date = Calendar.current.date(byAdding: components, to: self.startOfDay)
        return (date?.addingTimeInterval(-1))!
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

    let myDate = Date()
    let startOfDate = myDate.startOfDay
    let endOfDate = myDate.endOfDay
Run Code Online (Sandbox Code Playgroud)

  • @Ben 日期和日历不在 UIKit 中,它在 Foundation 中,但是 UIKit 导入 Foundation (2认同)

clo*_*der 8

我认为在 Swift 中最简洁的方法如下:

extension Date {
    func startOfDay() -> Date {
        return Calendar.current.startOfDay(for: self)
    }
    func endOfDay() -> Date {
        return Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: self) ?? self
    }
}
Run Code Online (Sandbox Code Playgroud)


Gur*_*ngh 6

在 Swift 3 及更高版本中

extension Date {
    var startOfDayDate: Date {
        return Calendar.current.startOfDay(for: self)
    }

    var endOfDayDate: Date {
        let nextDayDate = Calendar.current.date(byAdding: .day, value: 1, to: self.startOfDayDate)!
        return nextDayDate.addingTimeInterval(-1)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

var currentDayStart = Date().startOfDayDate
var currentDayEnd = Date().endOfDayDate
Run Code Online (Sandbox Code Playgroud)


Vik*_*Rao 5

对我来说,这里和 stackoverflow 上其他地方的答案都不起作用。为了今天开始,我这样做了。

NSCalendar * gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 
[gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];    
NSDateComponents *components = [gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]]; 
[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 
NSDate *beginningOfToday = [gregorian dateFromComponents:components];
Run Code Online (Sandbox Code Playgroud)

注意这个[gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];.

创建日历时,它会使用当前时区进行初始化,并且当从其组件中提取日期时,由于 NSDate 没有时区,因此当前时区的日期被视为 UTC 时区。因此,我们需要在提取组件之前以及稍后从这些组件中提取日期时设置时区。