it-source

시간 성분이 없는 NSD 날짜 비교

criticalcode 2023. 11. 2. 21:51
반응형

시간 성분이 없는 NSD 날짜 비교

신속한 운동장에서, 제가 사용해왔던 것은

NSDate.date() 

그러나 이는 항상 시간 요소가 추가되어 나타납니다.내 앱의 경우 시간 요소를 무시해야 합니다.스위프트에서 가능한가요?어떻게 할 수 있습니까?시간 요소를 모든 날짜에 동일한 시간으로 설정할 수 있다고 해도 효과가 있을 것입니다.

또한 두 날짜를 비교하려고 하는데 현재 다음 코드를 사용하고 있습니다.

var earlierDate:NSDate = firstDate.earlierDate(secondDate)

이것이 유일한 방법입니까 아니면 시간 요소를 무시하는 방법으로 할 수 있습니까?예를 들어 저는 같은 날이더라도 결과를 원하지 않고 다른 시간을 원합니다.

사용합니다.CalendariOS 8.0+의 날짜를 비교하는 기능

func compare(_ date1: Date, to date2: Date, toGranularity component: Calendar.Component) -> ComparisonResult


패싱.day단위로서

다음과 같은 기능을 사용합니다.

let now = Date()
// "Sep 23, 2015, 10:26 AM"
let olderDate = Date(timeIntervalSinceNow: -10000)
// "Sep 23, 2015, 7:40 AM"

var order = Calendar.current.compare(now, to: olderDate, toGranularity: .hour)

switch order {
case .orderedDescending:
    print("DESCENDING")
case .orderedAscending:
    print("ASCENDING")
case .orderedSame:
    print("SAME")
}

// Compare to hour: DESCENDING

var order = Calendar.current.compare(now, to: olderDate, toGranularity: .day)


switch order {
case .orderedDescending:
    print("DESCENDING")
case .orderedAscending:
    print("ASCENDING")
case .orderedSame:
    print("SAME")
}

// Compare to day: SAME

Xcode 11.2.1, Swift 5 이상

날짜에 동일한 일 구성 요소가 있는지 확인합니다.

Calendar.current.isDate(date1, equalTo: date2, toGranularity: .day)

필요에 따라 세분화를 조정합니다.

iOS 8.0+의 NSCalendar에는 다음과 같은 몇 가지 유용한 방법이 있습니다.

startOfDayForDate, isDateInToday, isDateInYesterday, isDateInTomorrow

그리고 날짜를 비교할 때도:

func isDate(date1: NSDate!, inSameDayAsDate date2: NSDate!) -> Bool

시간 요소를 무시하려면 다음을 사용할 수 있습니다.

var toDay = Calendar.current.startOfDay(for: Date())

하지만 iOS 7도 지원해야 한다면 언제든지 확장자를 작성할 수 있습니다.

extension NSCalendar {
    func myStartOfDayForDate(date: NSDate!) -> NSDate!
    {
        let systemVersion:NSString = UIDevice.currentDevice().systemVersion
        if systemVersion.floatValue >= 8.0 {
            return self.startOfDayForDate(date)
        } else {
            return self.dateFromComponents(self.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: date))
        }
    }
}

Swift 4:

func compareDate(date1:Date, date2:Date) -> Bool {
    let order = NSCalendar.current.compare(date1, to: date2, toGranularity: .day)
    switch order {
    case .orderedSame:
        return true
    default:
        return false
    }
}

애슐리 밀스 솔루션을 빌려서 두 날짜를 비교하기 위해 다음과 같은 방법을 썼습니다.두 날짜를 비교하고 두 날짜가 동일한 경우 true를 반환합니다(시간의 줄무늬).

func compareDate(date1:NSDate, date2:NSDate) -> Bool {
    let order = NSCalendar.currentCalendar().compareDate(date1, toDate: date2,
        toUnitGranularity: .Day)
    switch order {
    case .OrderedSame:
        return true
    default:
        return false
    }
}

그리고 이것을 이렇게 부릅니다.

if compareDate(today, date2: anotherDate) {
    // The two dates are on the same day.
}

두 날짜의 비교가 신속하게 이루어집니다.

    // Date comparision to compare current date and end date.
    var dateComparisionResult:NSComparisonResult = currentDate.compare(endDate)

    if dateComparisionResult == NSComparisonResult.OrderedAscending
    {
        // Current date is smaller than end date.
    }
    else if dateComparisionResult == NSComparisonResult.OrderedDescending
    {
        // Current date is greater than end date.
    }
    else if dateComparisionResult == NSComparisonResult.OrderedSame
    {
        // Current date and end date are same.
    }

두 날짜를 비교하기 위해 Swift 4 확장자를 작성했습니다.

import Foundation

extension Date {      
  func isSameDate(_ comparisonDate: Date) -> Bool {
    let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
    return order == .orderedSame
  }

  func isBeforeDate(_ comparisonDate: Date) -> Bool {
    let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
    return order == .orderedAscending
  }

  func isAfterDate(_ comparisonDate: Date) -> Bool {
    let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
    return order == .orderedDescending
  }
}

용도:

startDate.isSameDateAs(endDate) // returns a true or false

iOS7 지원용

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let date1String = dateFormatter.stringFromDate(date1)
let date2String = dateFormatter.stringFromDate(date2)
if date1String == date2String {
    println("Equal date")
}

설명을 이용해서 두 날짜를 비교할 수 있습니다.

let date1 = NSDate()
let date2 = NSDate(timeIntervalSinceNow: 120)
if date1.description == date2.description {
    print(true)
} else {
    print(false)   // false (I have added 2 seconds between them)
}

날짜의 시간 요소를 다른 시간으로 설정하려면 다음 작업을 수행할 수 있습니다.

extension NSDate {
    struct Calendar {
        static let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    }
    var day:    Int { return Calendar.gregorian.component(.Day,    fromDate: self)   }
    var month:  Int { return Calendar.gregorian.component(.Month,  fromDate: self)  }
    var year:   Int { return Calendar.gregorian.component(.Year,   fromDate: self)  }

    var noon: NSDate {
        return Calendar.gregorian.dateWithEra(1, year: year, month: month, day: day, hour: 12, minute: 0, second: 0, nanosecond: 0)!
    }
}

let date1 = NSDate()
let date2 = NSDate(timeIntervalSinceNow: 120)
print(date1.noon == date2.noon)   // true

또는 NSDateFormatter를 사용하여 수행할 수도 있습니다.

extension NSDate {
    struct Date {
        static let formatterYYYYMMDD: NSDateFormatter = {
            let formatter = NSDateFormatter()
            formatter.dateFormat = "yyyyMMdd"
            return formatter
        }()
    }
    var yearMonthDay: String {
        return Date.formatterYYYYMMDD.stringFromDate(self)
    }
    func isSameDayAs(date:NSDate) -> Bool {
        return yearMonthDay == date.yearMonthDay
    }
}

let date1 = NSDate()
let date2 = NSDate(timeIntervalSinceNow: 120)
print(date1.yearMonthDay == date2.yearMonthDay)   // true

print(date1.isSameDayAs(date2))    // true

또 다른 옵션(iOS8+)은 달력 메서드를 사용하는 것입니다(SameDayAsDate::).

extension NSDate {
    struct Calendar {
        static let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    }
    func isInSameDayAs(date date: NSDate) -> Bool {
        return Calendar.gregorian.isDate(self, inSameDayAsDate: date)
    }
}
let date1 = NSDate()
let date2 = NSDate(timeIntervalSinceNow: 120)
if date1.isInSameDayAs(date: date2 ){
    print(true)   // true
} else {
    print(false)
}

스위프트 3

        let order = NSCalendar.current.compare(date1, to: date2, toGranularity: .day)

        if order == .orderedAscending { 
          // date 1 is older
        }
        else if order == .orderedDescending { 
          // date 1 is newer
        }
        else if order == .orderedSame { 
          // same day/hour depending on granularity parameter
        }

스위프트3용

var order = NSCalendar.current.compare(firstDate, to: secondDate, toGranularity: .hour)

if order == .orderedSame {
    //Both the dates are same. 
    //Your Logic.
}

스위프트:

extension NSDate {

    /**
    Compares current date with the given one down to the seconds.
    If date==nil, then always return false

    :param: date date to compare or nil

    :returns: true if the dates has equal years, months, days, hours, minutes and seconds.
    */
    func sameDate(date: NSDate?) -> Bool {
        if let d = date {
            let calendar = NSCalendar.currentCalendar()
            if NSComparisonResult.OrderedSame == calendar.compareDate(self, toDate: d, toUnitGranularity: NSCalendarUnit.SecondCalendarUnit) {
                return true
            }

        }
        return false
    }
}

당신이NSDate.date()운동장에서 기본 설명이 인쇄된 것을 볼 수 있습니다. 사용합니다.NSDateFormatter날짜 부분만 포함하여 날짜 객체에 대한 현지화된 설명을 인쇄합니다.

(비교를 위해) 날짜의 특정 부분을 영점화하려면NSDateComponents와 공동으로NSCalendar.

제 경험에 따르면, 대부분의 사람들이 NSDate를 사용할 때 발생하는 문제는 '정상적'인 의미의 날짜(즉, 현지 시간대 자정부터 시작하는 24시간)를 나타내는 데 사용될 수 있다는 잘못된 가정에서 비롯됩니다.일반적으로(매일/비프로그래밍) 사용할 경우, 실시간으로 서로 다른 기간을 다루더라도 런던의 2014년 1월 1일은 베이징 또는 뉴욕의 2014년 1월 1일과 동일한 날짜입니다.이것을 극단적으로 설명하자면 크리스마스 섬의 시간은 UTC+14이고 미드웨이 섬의 시간은 UTC-11입니다.그러므로 2014년 1월 1일 이 두 섬은 다른 섬이 한 시간 동안 완성될 때까지 시작조차 하지 않음에도 불구하고 같은 날짜입니다.

기록 중인 날짜(그리고 시간 구성 요소를 기록하고 있지 않은 경우에는 기록할 수 있음)를 사용하지 않고 NSDate(2001-01-01 00:00 UTC 이후에 몇 초만 저장)를 사용하지 않고 연도 월과 일을 정수로 저장합니다(아마도 이러한 값을 포함하는 CivilDate 클래스를 직접 생성하여).

날짜를 비교하기 위해서는 NSDate만 입력하고 비교를 위해 두 NSDate 모두에서 시간대를 "UTC"로 명시적으로 선언해야 합니다.

날짜가 다른 날짜와 동일한 날짜인지 비교해야 하는 경우 다음을 사용합니다.

Calendar.current.isDate(date1, inSameDayAs: date2)

스위프트 4

func compareDate(date1:Date, date2:Date) -> Bool {
    let order = Calendar.current.compare(date1, to: date2,toGranularity: .day)
    switch order {
    case .orderedSame:
        return true
    default:
        return false
    }
}

질문에 대답하기

스위프트에서 가능한가요?

네, 가능합니다.


아, 당신도 이제 어떻게.

let cal = NSCalendar.currentCalendar()
cal.rangeOfUnit(.DayCalendarUnit, startDate: &d1, interval: nil, forDate: d1) // d1 NSDate?
cal.rangeOfUnit(.DayCalendarUnit, startDate: &d2, interval: nil, forDate: d2) // d2 NSDate?

이제 d1과 d2에는 날짜가 포함됩니다.

와 비교해 보다d1!.compare(d2!)

시간 부분 없이 표시하려면 NSDateFormatter를 사용합니다.

언급URL : https://stackoverflow.com/questions/24577087/comparing-nsdates-without-time-component

반응형