Adding/Reducing day in the Date object returns wrong date when day light savings time ends

158 Views Asked by At

I'm using

Calendar.current.date(byAdding: .day, value: -1, to: somedate) ?? somedate

to reduce 1 day from some date. Since Daylight Saving Time Ended on 1'st Nov, 2020. When i'm trying to do this on 2nd Nov, 2020 0hr:0m:0s's date object, i expect it to return 1st Nov, 2020 0hr:0m:0s, but instead it is returning 31st Oct, 2020 23hr:0m:0s.

Is it something i'm doing wrong or is it some other issue?

How to reproduce:-

  • Create a date object using time stamp 1604275200. using Date(timeIntervalSince1970: 1604275200)
  • Change timezone of ur device to some place where daylight savings time is considered. i tried it in HST timezone
  • Try reducing the day using the above given method.
  • You'll see date returning as 31st Oct.

extension Date {
    init(timeIntervalInMillis: Double) {
        self.init(timeIntervalSince1970: timeIntervalInMillis / 1000)
    }
    func add(_ component: Calendar.Component, value: Int) -> Date {
        return Calendar.current.date(byAdding: .day, value: value, to: self) ?? self
    }
    var noon: Date {
        return Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
    }
}
print(Calendar.current.timeZone.identifier)
let date = Date(timeIntervalInMillis: 1604275200000)
print("Date is ",date)
print("Yesterday's date is ",date.add(.day, value: -1))
print("Noon time is ",date.noon)
print("Yesterday date from noon's date is ",date.noon.add(.day, value: -1))

Output:

America/Chicago
Date is  2020-11-02 00:00:00 +0000
Yesterday's date is  2020-10-31 23:00:00 +0000
Noon time is  2020-11-01 18:00:00 +0000
Yesterday date from noon's date is  2020-10-31 17:00:00 +0000

Any help would be appreciated.

1

There are 1 best solutions below

10
Leo Dabus On

edit/update:

There is nothing wrong with your code. Your issue is that you are printing the UTC date representation instead of using DateFormatter with the time zone set to chicago to show the resulting date at the desired timezone.

print("Date is ",date)  // Date is  2020-11-02 00:00:00 +0000\n"
print("Yesterday's date is ",date.add(.day, value: -1))  // "Yesterday's date is  2020-10-31 23:00:00 +0000\n"  
print("Noon time is ",date.noon) // "Noon time is  2020-11-01 18:00:00 +0000\n"
print("Yesterday date from noon's date is ",date.noon.add(.day, value: -1)) // "Yesterday date from noon's date is  2020-10-31 17:00:00 +0000\n"

let fmter = DateFormatter()
fmter.timeZone = TimeZone(identifier: "America/Chicago")!
fmter.dateStyle = .full
fmter.timeStyle = .full

print("Date is ", fmter.string(from: date))  // "Date is  Sunday, 1 November 2020 18:00:00 Central Standard Time\n"
print("Yesterday's date is ", fmter.string(from: date.add(.day, value: -1)))  // "Yesterday's date is  Saturday, 31 October 2020 18:00:00 Central Daylight Time\n"
print("Noon time is ", fmter.string(from: date.noon))  // "Noon time is  Sunday, 1 November 2020 12:00:00 Central Standard Time\n"
print("Yesterday date from noon's date is ",fmter.string(from: date.noon.add(.day, value: -1)))  // "Yesterday date from noon's date is  Saturday, 31 October 2020 12:00:00 Central Daylight Time\n"