简体   繁体   中英

Converting string to NSDate, timezones do not adjust correctly?

I'm trying to convert a time string from one timezone into an NSDate object, and then output it using the local timezone back to a string. However I seem to be going 1 hour out. For an example, I've added in the output timezone so that I can show the error. There are a few similar questions but nothing gives a hint to where I am going wrong with this one!!! Both timezones are currently in daylight savings at the time of posting this - however NSDateFormatter should take care of any difference based upon the timezone.

UPDATE: The issue seems to be with converting the LA time into GMT, not onwards to BST. All NSDate's are stored as GMT as far as I'm aware. The below code demonstrates this (with locale added - doesn't seem to make a difference):

NSDateFormatter *dateF = [[NSDateFormatter alloc] init];
[dateF setDateFormat:@"HH:mm"];
[dateF setTimeZone:[NSTimeZone timeZoneWithName:@"America/Los_Angeles"]];
[dateF setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
NSDate* sourceDate = [dateF dateFromString:@"09:15"];

NSLog(@"Date GMT: %@", [sourceDate description]);
NSLog(@"Date BST: %@", [sourceDate descriptionWithLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"]]);

Output:

Date GMT: 1970-01-01 17:15:00 +0000 this is incorrect!

Date BST: Thursday, 1 January 1970 18:15:00 GMT+01:00 thus this is incorrect too

ORIGINAL EXAMPLE

09:15 in LA should be 17:15 in London, not 18:15...

NSDateFormatter *dateF = [[NSDateFormatter alloc] init];
[dateF setDateFormat:@"HH:mm"];
[dateF setTimeZone:[NSTimeZone timeZoneWithName:@"America/Los_Angeles"]];

NSDate* sourceDate = [dateF dateFromString:@"09:15"];

NSDateFormatter *dateformatter = [[NSDateFormatter alloc] init];
[dateformatter setDateFormat:@"HH:mm"];
[dateformatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/London"]];
NSLog(@"%@", [dateformatter stringFromDate:sourceDate]);

NSDate objects store dates in absolute time. For example, the date object created in Listing 16 represents 4:00 PM CDT, 5:00 EDT, and so on.

NSCalendar *gregorian=[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"CDT"]];
NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init];
[timeZoneComps setHour:16];
//specify whatever day, month, and year is appropriate
NSDate `enter code here`*date=[gregorian dateFromComponents:timeZoneComps];

From NSTimeZone docs:

Note that, strictly, time zone database entries such as “America/Los_Angeles” are IDs not names. An example of a time zone name is “Pacific Daylight Time”. Although many NSTimeZone method names include the word “name”, they refer to IDs.

https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Classes/NSTimeZone_Class/Reference/Reference.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM