ios NSDate 一天的开始和一天的结束

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13324633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:09:57  来源:igfitidea点击:

NSDate beginning of day and end of day

iosnsdatensdatecomponents

提问by user1028028

    -(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];

}

When I call : [self endOfDay:[NSDate date]]; I get the first of the month ... Why is that? I use this two methods because I need an interval that is from the first second of the first date (beginningOfDay:date1) to the last second of the second date (endOfDay:Date2) ...

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

采纳答案by JaanusSiim

You are missing NSDayCalendarUnitin

你失踪NSDayCalendarUnit

NSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];

回答by Zelko

Start Of Day / End Of Day —?Swift 4

一天的开始/一天的结束——?Swift 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

回答by August Lin

Swift 5Simple and more precise answer.

Swift 5简单而准确的答案。

Start time: 00:00:00

开始时间:00:00:00

End time: 23:59:59.5

结束时间: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)

Extra

额外的

let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: noon)!
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: noon)!
let specificDate = Date("2020-01-01")

extension Date {
    init(_ dateString:String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
        let date = dateStringFormatter.date(from: dateString)!
        self.init(timeInterval:0, since:date)
    }
}

回答by Bryan Bryce

In iOS 8+ this is really convenient; you can do:

在 iOS 8+ 中,这真的很方便;你可以做:

let startOfDay = NSCalendar.currentCalendar().startOfDayForDate(date)

To get the end of day then just use the NSCalendar methods for 23 hours, 59 mins, 59 seconds, depending on how you define end of day.

要获得一天结束,只需使用 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))

Date Math

日期数学

Apple iOS NSCalendar Documentation. (See Section: Calendrical Calculations)

苹果 iOS NSCalendar 文档。(参见章节:日历计算

NSCalendar methods discussed by NSHipster.

NSHipster 讨论的 NSCalendar 方法

回答by Libor Zapletal

My Swift extensions for NSDate:

我的 NSDate Swift 扩展:

Swift 1.2

斯威夫特 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
    }
}

Swift 2.0

斯威夫特 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
    }
}

回答by Ben

Swift 5.1 - XCode 11with Dateclass instead of NSDateand Calenderinstead of NSCalender

Swift 5.1 - XCode 11使用Date类代替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))!
    }
}

Usage:

用法:

    let myDate = Date()
    let startOfDate = myDate.startOfDay
    let endOfDate = myDate.endOfDay

回答by John Doe

Swift3Using *XCode8
Apple is removing the NSfrom the class name so that NSDatecan be swapped out to Date. You may get a compiler warning if you try to cast them saying they will always fail, but they work fine when you run them in the playground.

Swift3Using *XCode8
Apple 正在NS从类名中删除 ,以便NSDate可以换出Date. 如果您尝试将它们强制转换为总是会失败,您可能会收到编译器警告,但是当您在操场上运行它们时,它们可以正常工作。

I replaced my generated NSDatein core data model with Dateand they still work.

我用我NSDate在核心数据模型中生成的替换了Date它们,它们仍然有效。

extension Date {
  func startTime() -> Date {
    return Calendar.current.startOfDay(for: self)
  }

  func endTime() -> Date {
    var components = DateComponents()
    components.day = 1
    components.second = -1
    return Calendar.current.date(byAdding: components, to: startTime())!
  }
}

回答by Maxim Lavrov

You don't have to set up the components to zero, just ignore them:

您不必将组件设置为零,只需忽略它们:

-(NSDate *)beginningOfDay:(NSDate *)date
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date];
    return [calendar dateFromComponents:components];
}

回答by Vikram Rao

For me none of the answers here and else where on stackoverflow worked. To get start of today i did this.

对我来说,这里和 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];

Note this [gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];and [components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];.

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

When a calendar is created it gets initialised with current timezone and when date is extracted from its components, since NSDate has no timezone, the date from current timezone is considered as UTC timezone. So we need to set the timezone before extracting components and later when extracting date from these components.

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

回答by Jaseem Abbas

Swift 3

斯威夫特 3

  class func today() -> NSDate {
        return NSDate()
    }

    class func dayStart() -> NSDate {
          return NSCalendar.current.startOfDay(for: NSDate() as Date) as NSDate
    }

    class func dayEnd() -> NSDate {
        let components = NSDateComponents()
        components.day = 1
        components.second = -1
        return NSCalendar.current.date(byAdding: components as DateComponents, to: self.dayStart() as Date)
    }