truthful_ness
truthful_ness

Reputation: 84

NSDate and NSDate stringFromDate are inconsistent

I am trying to convert a mysql datetime field to another timezone. The conversion seems correct when I print the date object, however when I print the date as a string the time is incorrect. Source code and output are below.

Source:

edited - print original interval in seconds and string, add timezones

interval = [NSNumber numberWithDouble: seconds];
NSLog(@"interval in ms: %@",interval); 
self.dateStamp = [[NSDate alloc] initWithTimeIntervalSince1970:seconds/1000];


if(![currentZone.name isEqualToString: timezone]){          //need to convert
    NSDateFormatter *fromTZ = [[NSDateFormatter alloc]init];
    [fromTZ setTimeZone:currentZone];
    [fromTZ setDateFormat:@"hh:mm yyyy-MM-dd"];
    NSLog(@"original date: %@",[fromTZ stringFromDate:self.dateStamp]);
    NSDateFormatter *toTZ = [[NSDateFormatter alloc]init];
    [toTZ setTimeZone:spotZone];
    [toTZ setDateFormat:@"hh:mm yyyy-MM-dd"];
    NSString *tempdate = [fromTZ stringFromDate:self.dateStamp];
    NSDate *toDate = [toTZ dateFromString:tempdate];
    NSLog(@"Date: %@",toDate);
    NSLog(@"Date String: %@", [toTZ stringFromDate:toDate]);
}

Output:

interval in ms: 1384193573000

original date: 01:12 2013-11-11 //date in current timezone: America/Phoenix

Date: 2013-11-11 08:12:00 +0000 //date in new timezone: America/New York

Date String: 01:12 2013-11-11

Upvotes: 1

Views: 262

Answers (2)

Martin R
Martin R

Reputation: 539775

Your server sends the time 1384193573000 (in milliseconds) since 1.1.1970, but not with respect to GMT as it is usually done, but with respect to a different time zone, "America/Phoenix" in your example.

Therefore you have to add a correction first, which is the difference between "America/Phoenix" and GMT:

NSTimeInterval serverTime = 1384193573000/1000.;
NSTimeZone *fromZone = [NSTimeZone timeZoneWithName:@"America/Phoenix"];
NSTimeInterval diff = [fromZone secondsFromGMTForDate:[NSDate dateWithTimeIntervalSince1970:0]];
NSDate *dateStamp = [NSDate dateWithTimeIntervalSince1970:(serverTime - diff)];

This was the crucial step. dateStamp is now a "proper" NSDate object representing the time sent from the server. What remains is to display the date. That is done as in the above comments and the other answer. For example:

NSTimeZone *toZone = [NSTimeZone timeZoneWithName:@"America/New_York"];
NSDateFormatter *toTZ = [[NSDateFormatter alloc]init];
[toTZ setTimeZone:toZone];
[toTZ setDateFormat:@"HH:mm yyyy-MM-dd"];
NSString *result = [toTZ stringFromDate:dateStamp];

// result = 20:12 2013-11-11

Upvotes: 1

Peter Foti
Peter Foti

Reputation: 5654

NSDate has no concept of time zone, it is simply an object representing the number of seconds since January 1, 2001 GMT and represented in UTC. No matter what you try and set it to, when you straight log an NSDate its going to give you the same result. The only way to circumvent this is to use the NSDateFormatter which you've already done. Everything you've posted is the expected behavior.

Upvotes: 2

Related Questions