Incorrect time string with NSDateFormatter with Daylight Saving Time

久未见 提交于 2019-12-24 11:37:23

问题


I'm using CET as my default timezone in my application. In Germany Daylight saving time will start from 29 March 2015. Now I'm doing some testing to see if my dates will be converted correctly in the future. I used following code to test it.

NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:@"CET"];
[NSTimeZone setDefaultTimeZone:timeZone];

NSDate *now = [NSDate date]; // 10 Feb, 2015
NSDate *dateAfter29March = [now dateByAddingMonths:2]; // 10 April, 2015

NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss ZZZ"];
[formatter setTimeZone:timeZone];

NSLog(@" NOW DATE -> %@",[formatter stringFromDate:now]);
NSLog(@" DATE AFTER 29 March -> %@",[formatter stringFromDate:dateAfter29March]);

The category method for adding months is

- (NSDate *)dateByAddingMonths:(NSInteger) dMonths {
    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.month = dMonths;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    return [calendar dateByAddingComponents:components toDate:self options:0];
}

The Output of Console is as follows:

NOW DATE -> 2015-02-10 18:28:05 +0100
DATE AFTER 29 March -> 2015-04-10 18:28:05 +0200

Where my expected time on date after 29 March was 17:28:05 as One hour in now less after daylight time. What am I doing wrong?

PS: I also tried to set the output strings in a label and no change occurs.


回答1:


I really don't see what you are complaining about.

You asked the OS to add two months to a date. And adding two months means that it uses the calendar, and returns a date that is two months later, on the same day of the month, at the same time. It should take changes in DST into account, and it does. That's what adding two months means.

Imagine we have a meeting that we always do at the first of the month, at 10am in the morning. You want that meeting at 10am in the morning, whether it is DST or not.




回答2:


Try this;

[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

NSDate *now = [NSDate date]; // 10 Feb, 2015
NSDate *dateAfter29March = [self dateByAddingMonths:2 date:now]; // 10 April, 2015


NSLog(@"now -> %@", now);
NSLog(@"dateAfter29March -> %@", dateAfter29March);
NSLog(@"========================================");


NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:@"CET"];

NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss ZZZ"];
[formatter setTimeZone:timeZone];

NSLog(@"NOW DATE -> %@",[formatter stringFromDate:now]);
NSLog(@"DATE AFTER 29 March -> %@",[formatter stringFromDate:dateAfter29March]);

It worked fine for me. See the logs

now -> 2015-02-11 06:01:56 +0000
dateAfter29March -> 2015-04-11 06:01:56 +0000
========================================
NOW DATE -> 2015-02-11 07:01:56 +0100
DATE AFTER 29 March -> 2015-04-11 08:01:56 +0200



回答3:


You can use nextDaylightSavingTimeTransition to find out when is the next daylight saving time transition for your time zone:

NSTimeZone(abbreviation: "CET")!.nextDaylightSavingTimeTransition!   // "Mar 28, 2015, 22:00"

You can create a NSDateFormatter extension to format your time using the CET time zone as follow:

extension NSDate {
    var time:String {
        let formatter = NSDateFormatter()
        formatter.timeZone = NSTimeZone(abbreviation: "CET")
        formatter.dateFormat = "HH:mm"
        return formatter.stringFromDate(self)
    }
}



let futureDate = NSCalendar.currentCalendar().dateWithEra(1, year: 2015, month: 3, day: 27, hour: 13, minute: 0, second: 0, nanosecond: 0)!
let futureDateDLST = NSCalendar.currentCalendar().dateWithEra(1, year: 2015, month: 3, day: 29, hour: 13, minute: 0, second: 0, nanosecond: 0)!

futureDate.time      // 17:00"
futureDateDLST.time  // "18:00"


来源:https://stackoverflow.com/questions/28438156/incorrect-time-string-with-nsdateformatter-with-daylight-saving-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!