Hi! It seem to be an error in the NSDate handling of the Daylight Saving Time. I set an NSDate to "2016-03-28" and then try to read the value into a string with the stringFromDate function on NSDateFormatter. Then I get the value "2016-03-29". Also when I try addDays(6) to the NSDate of "2016-03-21" I get "2016-03-28" and not "2016-03-27" as expected. When I try these two function on earlier dates, I get values as expected. I think this could be because we set the clock one hour forward as 02:00 in the night between the 26th and 27th of March here in Norway.
Error in NSDate and summertime (Daylight Saving Time)
The devil is in the details. Post your code.
My guess is you're probably not setting the locale and/or time zone on your date formatter, but there's no point guessing without seeing the code.
As far as I know, NSDate does not have a method named `addDays`. Show what your `addDays` is.
Try to subtract 6 days in that same example...where does that land - it should help you isolate if the recent time shift is involved.
Hi, and thanks for your replies 🙂
Here is (a condensed version of) the code that make me confused:
let formatter: NSDateFormatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.locale = NSLocale(localeIdentifier: "nb_NO")
let calendar = NSCalendar.currentCalendar()
var date: NSDate = NSDate()
let currentDateComponents = calendar.components([.YearForWeekOfYear, .WeekOfYear], fromDate: fromDateDate) // I want first day of current week
date = calendar.dateFromComponents(currentDateComponents)!
print(date) // "2016-03-30 22:00:00 +0000"
let strDate: String = formatter.stringFromDate(date)
print(strDate) // "2016-03-31" Why?
The addDays-method seems to be my own extension to NSDate. It might have errors... The above example is not using addDays.
Given your locale setting, I presume you’re in Norway, and thus currently on GMT+2. If so, this sequence makes perfect sense:
print(date) // "2016-03-30 22:00:00 +0000"
let strDate: String = formatter.stringFromDate(date)
print(strDate) // "2016-03-31" Why?Line 1 shows that the date you’re trying to format is 22:00 GMT on 30 Mar. At that time, it was midnight in Norway, and that’s the midnight at the start of 31 Mar, which is what line 3 is printing.
Keep in mind that NSDate does not store a time zone or a calendar. The underlying model of NSDate is that it’s an absolute point in time represented by a NSTimeInterval number of seconds from a reference date. That’s why NSDate always prints as fixed-format GMT.
In your code comment you wrote:
I want first day of current week
Define week in this context? It looks like you’re trying to work with a week-of-year calendar, which is fine but you need to be very careful with how you approach this. The most obvious gotcha is that week-of-year calendars only make sense in a Gregorian context, so you probably want to hard wire the Gregorian calendar everywhere. Normally that’d mean using
NSCalendarIdentifierGregorian, but for week-of-year stuff I’d recommend
NSCalendarIdentifierISO8601 instead.
In terms of calculating relative dates, it’s very likely that NSCalendar can do all the things you want it to do, you just have to use it correctly. Alas, that’s tricky because calendars are, in the general case, hard.
I strongly recommend that you watch WWDC 2011 Session 117 Performing Calendar Calculations, which explains the new APIs we added in iOS 8 / OS X 10.9 to handle the really gnarly edge cases.
The addDays-method seems to be my own extension to NSDate.
Just FYI, having an
addDays(_:) method on NSDate makes no sense because you can’t add days without reference to a calendar. OTOH, NSCalendar can add days for you, no problem (using
dateByAddingComponents(_:toDate:options:)).
If you post more details about your high-level goals, I’d be happy to help you navigate the minefield that is calendrical calculations.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"