Why is the date off by 1 hour?


#1

Hi All,

I’m working through Aaron’s Objective C book and already I’ve notice a problem with the date object. With this very simple code:

  NSDate *theDate = [NSDate date];
        
  NSLog(@"The current date and time is: %@", theDate);

… the output is off by one hour:

[Switching to process 1574 thread 0x0] 2011-11-13 13:29:03.054 SimpleDate[1574:707] The current date and time is: 2011-11-13 12:29:03 +0000

Could this be something to do with my Mac’s date/time/locale setup ?

-Nick


#2

Very curious. What time zone do you live in? Do you have daylight savings?


#3

Hi Aaron. Great book.
I’m in Demark, that’s gmt+1.
Running lion 10.7.2 and Xcode 4.2.
The system time is fine, as you can see in the compiler output, the timestamp for the code execution is different from the generated date and time. I’ve tried this on two different machines, one with Xcode 4.1 and one with Xcode 4.2. The results are the same, off by 1 hour.
Maybe this is connected to the reports by many iPhone users about problems with the alarm when the clocks go back or forward in summer and winter :slight_smile:

There is no setting for daylight savings on my Mac and lion. It’s configured to set automatically from an Apple time server.

However, my cultural settings are mixed, but the OS should be able to cope with that. For example, my keyboard, currency, date and time formats are set to Danish, while my system language is English.

-nick


#4

Hi Nick & Aaron,
I have exactly the same problem. It’s not a problem for now, but it can be a problem while coding later on. Live in the Netherlands, also my date & time is set automatically by the Apple time server.
This code:

[code]#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{

@autoreleasepool {
    NSDate *now = [NSDate date];
    NSLog(@"The new date lives at %@", now);
}

long secondsSince1970 = time(NULL);
struct tm now;
localtime_r(&secondsSince1970, &now);    
printf("the time & date is %02d-%02d-%04d %02d:%02d:%02d\n", now.tm_mday, now.tm_mon + 1, now.tm_year + 1900, now.tm_hour, now.tm_min, now.tm_sec);

return 0;

}
[/code]

results in this output:

2011-11-14 09:59:04.868 TimeAfterTime[766:707] The new date lives at 2011-11-14 08:59:04 +0000 the time & date is 14-11-2011 09:59:04 Program ended with exit code: 0


#5

Weird isn’t it?

I tried stopping the automatic time / date setup via the Apple server and switched over to manual confguration, but it didn’t help!

A google search for NSDate bugs didn’t reveal much, but apparently there are plenty of bugs in the NSDateFormatter class. A LOT of people are complaining about that, and one software company and a private developer have had a lot of problems with date related bugs on the international Appstore. The private developer was really mad because the bugs ended up giving his software negative reviews.

I guess us folks in europe will have to come up with some workarounds.


#6

I experienced the same thing (also in Denmark) - it must be daylights saving related - a concept Apple apparently have some issues with :slight_smile:


#7

Any time you find a repeatable issue like this you should file a bug on it. If a bug isn’t filed, Apple doesn’t know it exists!


#8

Hi Again,

found this on Stackoverflow.com I’ll give it a try later.

http://stackoverflow.com/questions/4547379/nsdate-is-not-returning-my-local-time-zone-default-time-zone-of-device

The second answer sounds interesting. The one posted by someone called Kendall.

On a side note, I tried playing about with a little GUI code, with a datepicker and a label.

Even that was wrong. The date picker would should 10.30 PM (and a date) but the extracted data, by doing this:

[code] NSString *theDate = [[NSString alloc]

initWithFormat:@"%@", self.myDataPicker.date];

self.lblDate.text = theDate;
[/code]

… still shows 09:30 PM - Doh!


#9

I found this on stack overflow, but I still have to look into how to set the time zone for NSDate…
stackoverflow.com/questions/5583 … -by-1-hour


#10

Hi Guys, got it!

You can not set a timezone for an NSDate object.
After a lot of digging, this strange behavior is by design. NSDate records a single (universal?) point in time that is set to GMT+0

When you display it, you need an NSDateFormatter and then you can then set a timezone on that to correctly display the recorded time in your timezone.

Try this:

{
    @autoreleasepool {
        
        // this does not work correctly, it defaults to GMT and I am in GMT+1
        NSDate *wrongDate = [[NSDate alloc]init];
        
        NSLog(@"This date object says: %@",wrongDate); //Prints GMT (1 hour behind).
        
        NSDateFormatter *df = [[NSDateFormatter alloc] init ];
        
        // Set a TimeZone for the DateFormatter
          
        [df setTimeZone:[NSTimeZone localTimeZone]];
        
        [df setDateFormat:@"yyyy-MM-dd - hh:mm:ss"];
        
        NSLog(@"The formatter says: %@", [df stringFromDate:wrongDate]); //now shows correct date/time
         
        }
     
    return 0;
}

Sample output:

This is pretty goofy behaviour and produces dates and times that need a lot of work. For example, if we save the value of NSDate to a file or a database, we’re still saving the time in GMT+0 and not a local time!

I wonder why then, it works for Aaron and others in the US, because GMT+0 is London, England ?

-Nick


#11

Your explenation is correct and we have the same behavior in the US (as expected). I’m on the west coast (Pacific Time zone) and here’s my output from earlier this evening:

Pacific Standard Time is GMT -8.


#12

OK. Thanks Scott.

I just presumed that, with there being no mention of it in Aaron’s book (or any other examples I’ve seen that just grab a quick “today’s date” using the NSDate object alone ) that other people hadn’t been troubled by the output it was giving.

Oh, well, now we know. :slight_smile:

-nick


#13

Thanks, this worked for me !

2011-11-16 12:14:08.806 Learning1[620:707] The Date is: 2011-11-16 17:14:08 +0000
2011-11-16 12:14:08.808 Learning1[620:707] The time is: 2011-11-16 - 12:14:08

[quote=“nxspam”]Hi Guys, got it!

You can not set a timezone for an NSDate object.
After a lot of digging, this strange behavior is by design. NSDate records a single (universal?) point in time that is set to GMT+0

When you display it, you need an NSDateFormatter and then you can then set a timezone on that to correctly display the recorded time in your timezone.

Try this:

{
    @autoreleasepool {
        
        // this does not work correctly, it defaults to GMT and I am in GMT+1
        NSDate *wrongDate = [[NSDate alloc]init];
        
        NSLog(@"This date object says: %@",wrongDate); //Prints GMT (1 hour behind).
        
        NSDateFormatter *df = [[NSDateFormatter alloc] init ];
        
        // Set a TimeZone for the DateFormatter
          
        [df setTimeZone:[NSTimeZone localTimeZone]];
        
        [df setDateFormat:@"yyyy-MM-dd - hh:mm:ss"];
        
        NSLog(@"The formatter says: %@", [df stringFromDate:wrongDate]); //now shows correct date/time
         
        }
     
    return 0;
}

Sample output:

This is pretty goofy behaviour and produces dates and times that need a lot of work. For example, if we save the value of NSDate to a file or a database, we’re still saving the time in GMT+0 and not a local time!

I wonder why then, it works for Aaron and others in the US, because GMT+0 is London, England ?

-Nick[/quote]


#14

[quote=“nxspam”]Hi Guys, got it!

You can not set a timezone for an NSDate object.
After a lot of digging, this strange behavior is by design. NSDate records a single (universal?) point in time that is set to GMT+0

When you display it, you need an NSDateFormatter and then you can then set a timezone on that to correctly display the recorded time in your timezone.

Try this:

{
    @autoreleasepool {
        
        // this does not work correctly, it defaults to GMT and I am in GMT+1
        NSDate *wrongDate = [[NSDate alloc]init];
        
        NSLog(@"This date object says: %@",wrongDate); //Prints GMT (1 hour behind).
        
        NSDateFormatter *df = [[NSDateFormatter alloc] init ];
        
        // Set a TimeZone for the DateFormatter
          
        [df setTimeZone:[NSTimeZone localTimeZone]];
        
        [df setDateFormat:@"yyyy-MM-dd - hh:mm:ss"];
        
        NSLog(@"The formatter says: %@", [df stringFromDate:wrongDate]); //now shows correct date/time
         
        }
     
    return 0;
}

Sample output:

This is pretty goofy behaviour and produces dates and times that need a lot of work. For example, if we save the value of NSDate to a file or a database, we’re still saving the time in GMT+0 and not a local time!

I wonder why then, it works for Aaron and others in the US, because GMT+0 is London, England ?

-Nick[/quote]
Is this why my output looks as such?

2011-12-05 20:08:24.921 TimeAfterTime[946:707] The date is 2011-12-06 01:08:24 +0000

Even has tomorrow’s date by my system clock.


#15

This is stepping into both ancient history and modern time techniques, I think.

The UNIX representation for time is number of seconds past 1970 (Jan 1, maybe, don’t recall off-hand), and as such has no concepts of time zones. A time representation is a number of seconds, full stop.

UNIX has always taken the approach that system time is UTC (GMT), and if you want to display times locally, you’ll have to convert them yourself.

This is in practice much saner than Windows, which (to the best of my knowledge) treats all time as local. If you store a Windows time representation in a database, and return to it later, unless you stored not only the time but also the time zone (with DST representation, so Eastern isn’t good enough, you need to know EDT vs EST) there’s no good way to know the “real” time for that value. The UNIX practice of dealing with UTC absolute values seems a lot safer, especially since most Americans can’t seem to figure out if they’re currently in DST or not(*).

So jwjody, if you live in the Eastern time zone, that explains why your system is 5 hours ahead of what you think it is. It’s on London time, pretending to be on Eastern time for your sake.

  • I missed most of my last chance to see my cousin play college basketball because some college kid couldn’t figure out time zones, so I’m a little touchy whenever I see someone suggesting we meet at a certain time EST during the summer. If you don’t know, don’t over specify, just say “Eastern”.

#16

My Code:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSDate *now = [NSDate date];
NSLog(@“The new date is %@”, now);
}
return 0;
}

My output: Notice this program was run at 21:12:51 on 1-24-12. Why is it giving my 5:12:51 as the time (for the next day)??

2012-01-24 21:12:51.544 TimeAfterTime[2130:707] The new date is 2012-01-25 05:12:51 +0000


#17

Let me guess: you live on the west coast (or at least, in the Pacific time zone)?


#18

Yes, I live in the PST time zone (California). Everyone seems to be talking about their time being off by 1 hour. Why is mine 8 hours?


#19

UNIX (including MacOS X) store their time values internally as Universal time (UTC/GMT), which is currently 8 hours ahead of you.

I’d have to re-read the thread to see if 1 hour is a recurring theme, but that’s beside the point. If you set that aside and re-read, I think you’ll get a better feel for what’s going on.


#20

Thanks Nick, your solution solves our problems!

[quote=“nxspam”]Hi Guys, got it!

You can not set a timezone for an NSDate object.
After a lot of digging, this strange behavior is by design. NSDate records a single (universal?) point in time that is set to GMT+0

When you display it, you need an NSDateFormatter and then you can then set a timezone on that to correctly display the recorded time in your timezone.

Try this:

{
    @autoreleasepool {
        
        // this does not work correctly, it defaults to GMT and I am in GMT+1
        NSDate *wrongDate = [[NSDate alloc]init];
        
        NSLog(@"This date object says: %@",wrongDate); //Prints GMT (1 hour behind).
        
        NSDateFormatter *df = [[NSDateFormatter alloc] init ];
        
        // Set a TimeZone for the DateFormatter
          
        [df setTimeZone:[NSTimeZone localTimeZone]];
        
        [df setDateFormat:@"yyyy-MM-dd - hh:mm:ss"];
        
        NSLog(@"The formatter says: %@", [df stringFromDate:wrongDate]); //now shows correct date/time
         
        }
     
    return 0;
}

Sample output:

This is pretty goofy behaviour and produces dates and times that need a lot of work. For example, if we save the value of NSDate to a file or a database, we’re still saving the time in GMT+0 and not a local time!

I wonder why then, it works for Aaron and others in the US, because GMT+0 is London, England ?

-Nick[/quote]