programing

NSDate 시작일과 종료일

nasanasas 2020. 9. 4. 07:31
반응형

NSDate 시작일과 종료일


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

}

내가 전화 할 때 : [self endOfDay : [NSDate date]]; 나는 이달의 첫 번째를 얻습니다. 왜 그럴까요? 첫 번째 날짜의 첫 번째 초 (beginningOfDay : date1)에서 두 번째 날짜의 마지막 초 (endOfDay : Date2)까지의 간격이 필요하기 때문에이 두 가지 방법을 사용합니다.


당신은 누락 NSDayCalendarUnit

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

하루의 시작 / 하루의 끝 — 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

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)

iOS 8+에서는 정말 편리합니다. 넌 할 수있어:

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

하루의 끝을 확인하려면 하루의 끝을 정의하는 방법에 따라 23 시간 59 분 59 초 동안 NSCalendar 메서드를 사용하면됩니다.

// 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))

날짜 수학

Apple iOS NSCalendar 문서 . (섹션 : 달력 계산 참조 )

NSHipster에서 논의한 NSCalendar 메서드 .


NSDate 용 내 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
    }
}

스위프트 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
    }
}

스위프트 5.1 - 엑스 코드 (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))!
    }
}

용법:

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

구성 요소를 0으로 설정할 필요없이 무시하면됩니다.

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

스위프트 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)
    }

Swift3는 사용 * XCode8
애플을 제거하고 NS그이 때문에 클래스 이름에서 NSDate로 스왑 할 수 있습니다 Date. 항상 실패 할 것이라고 캐스팅하려고하면 컴파일러 경고가 표시 될 수 있지만 플레이 그라운드에서 실행하면 제대로 작동합니다.

내 생성 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())!
  }
}

나에게는 여기에 대한 답변이 없으며 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]];.

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.


In Swift 3 and above

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)
    }
}

Usage:

var currentDayStart = Date().startOfDayDate
var currentDayEnd = Date().endOfDayDate

One more way to get result:

NSDate *date = [NSDate date];

NSDateComponents *components = [[NSDateComponents alloc] init];
components.day = [[NSCalendar currentCalendar] ordinalityOfUnit:(NSCalendarUnitDay) inUnit:(NSCalendarUnitEra) forDate:date];
NSDate *dayBegin = [[NSCalendar currentCalendar] dateFromComponents:components];

components.day += 1;
NSDate *dayEnd = [[NSCalendar currentCalendar] dateFromComponents:components];

You are missing NSDayCalendarUnit in the components.


Objective-C

NSCalendar * calendar = [NSCalendar currentCalendar];
NSDate * startDate = [calendar startOfDayForDate:[NSDate date]];
NSLog(@"start date is %@", startDate);

Since iOS 8.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+ there is a built in function in the Foundation, which you can use out of the box. No need to implement own functions.

public func startOfDay(for date: Date) -> Date

So you can use it this way:

let midnightDate = Calendar(identifier: .gregorian).startOfDay(for: Date())

It's worth to remember, that this takes upon consideration the device time zone. You can set .timeZone on calendar if you want to have eg UTC zone.

Link to the Apple reference pages: https://developer.apple.com/reference/foundation/nscalendar/1417161-startofday.


Just another way using dateInterval(of:start:interval:for:) of Calendar

On return startDate contains the start of the day and interval the number of seconds in the day.

func startAndEnd(of date : Date) -> (start : Date, end : Date) {
    var startDate = Date()
    var interval : TimeInterval = 0.0
    Calendar.current.dateInterval(of: .day, start: &startDate, interval: &interval, for: date)
    var endDate = startDate.addingTimeInterval(interval-1)
    return (start : startDate, end : endDate)
}

let (start, end) = startAndEnd(of: Date())
print(start, end)

For swift 4

    var calendar = Calendar.current
    calendar.timeZone = NSTimeZone(abbreviation: "UTC")! as TimeZone
    let dateAtMidnight = calendar.startOfDay(for: Date())

    //For End Date
    var components = DateComponents()
    components.day = 1
    components.second = -1

    let dateAtEnd = calendar.date(byAdding: components, to: dateAtMidnight)

    print("dateAtMidnight :: \(dateAtMidnight)")
    print("dateAtEnd :: \(dateAtEnd!)")

This is what I use for Swift 4.2:

    let calendar = Calendar.current
    let fromDate = calendar.startOfDay(for: Date())
    let endDate = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: Date())

Works like a charm for me. You could add this to an extension for start and end dates on Date, however keep in mind that adding an extension increases compile time (unless in the same file as the class), so if you only need it at one place or in one class... don't use an extension.


extension Date {
    func stringFrom(dateFormat: String) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = dateFormat
        return formatter.string(from: self)
    }

    func firstSecondInDay() -> Date {
        let dayStr = self.stringFrom(dateFormat: "yyyy-MM-dd")
        let firstSecondStr = "\(dayStr) 00:00:00"
        let format = DateFormatter()
        format.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return format.date(from: firstSecondStr)!
    }

    func lastSecondInDay() -> Date {
        let dayStr = self.stringFrom(dateFormat: "yyyy-MM-dd")
        let laseSecondStr = "\(dayStr) 23:59:59"
        let format = DateFormatter()
        format.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return format.date(from: laseSecondStr)!
    }
}

Just for reference, simple way to set Start and End of the day in Swift 4,

var comp: DateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: Date())
comp.hour = 0
comp.minute = 0
comp.second = 0
comp.timeZone = TimeZone(abbreviation: "UTC")!


//Set Start of Day
let startDate : Date = Calendar.current.date(from: comp)!
print(“Day of Start : \(startDate)")


//Set End of Day
comp.hour = 23
comp.minute = 59
comp.second = 59

let endDate : Date = Calendar.current.date(from:comp)!
print("Day of End : \(endDate)")

Calendar units should be thought of as intervals. As of iOS 10 Calendar has some nice methods for this

let day = Calendar.autoupdatingCurrent.dateInterval(of: .day, for: Date())
day?.end
day?.start

You can use the same method, to get the start/end of any calendar component (week/month/year etc)

참고URL : https://stackoverflow.com/questions/13324633/nsdate-beginning-of-day-and-end-of-day

반응형