Search code examples
iosnsdatenscalendarnsdatecomponents

How to get the correct year from NSDate in all circumstances?


I know about NSDateComponents, but the thing is that some sort of week-based mechanism will mess up the result when the date is at the head or at the foot of a year.

For example:

NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit calendarUnit = NSYearCalendarUnit;
NSDateComponents *dateComponents = [calendar components:calendarUnit fromDate:self.date];

(lldb) po self.date
2015-12-31 16:00:00 +0000

(lldb) po dateComponents
<NSDateComponents: 0x12f4c83f0>
    Calendar Year: 2016

Changing minimumDaysInFirstWeek doesn't make much difference either, and NSDateFormatter doesn't seem to be a better way.


Solution

  • As @Larme indicated in his comment, your local timezone is affecting your result;

    You have specified 4 pm on the 31 Dec 2015 at UTC. This is midnight on the 1st of January 2016 in your local timezone (UTC+8).

    You can use the NSCalendar method componentsInTimeZone to get the year in a specific time zone:

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSTimeZone *tz=[NSTimeZone timeZoneForSecondsFromGMT:0];
    NSDateComponents *dateComponents = [calendar componentsInTimeZone:tz fromDate:self.date];
    int year=dateComponents.year;  // This will be 2015