8

I have an app that displays a timetable of certain ferry trips.

If I travel to a different timezone - say 4 hours behind, a 10am ferry trip now shows up as 6am?

I know this has got to do with how dates are treated based on their timezones, but I can't work out how to change that behaviour.

At the moment here's how I am getting the date and displaying it on a UILabel:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"HH:mm"];
[self.departureTime setText:[dateFormatter stringFromDate:[self.route objectForKey:@"departureTime"]]];
[self.arrivalTime setText:[dateFormatter stringFromDate:[self.route objectForKey:@"arrivalTime"]]];
[dateFormatter release];

Thanks in advance for your help.

Rog
  • 18,602
  • 6
  • 76
  • 97
  • 4
    Understand that NSDate itself is independent of timezone -- it represents UTC (Greenwich) time. You must set the timezone of the NSDateFormatter to produce results for the timezone you want. – Hot Licks Oct 11 '11 at 00:19
  • 3
    @DanielRHicks A date has *no* timezone. It does *not* represent UTC, because UTC is a timezone, and a date does not have a timezone. – Dave DeLong Oct 11 '11 at 02:47
  • The time offset in an NSDate is, by convention, the time offset relative to UTC. And setting the timezone of the NSDateFormatter will be useless if the NSDate object is not set relative to UTC. – Hot Licks Oct 11 '11 at 16:32
  • 2
    @DanielRHicks not quite; the *reference date* was measured in the UTC timezone, but it is still an absolute point in time. That absolute point in time exists independent of any timezone. In other words, the reference date can be expressed in *any* time zone. – Dave DeLong Oct 12 '11 at 18:59
  • You're playing with words. The reference date is "the first instant of 1 January 2001, GMT". You can express it in a different timezone, but then it would not be "the first instant". – Hot Licks Oct 12 '11 at 19:57
  • @Hot Licks, I believe you are mistaken. 1 Jan 2001 GMT means the same as (say) 1 January 2001 02:00 Budapest Time. Therefore times returned by NSDate are equally relative to that Budapest time which is equally valid as the reference time. It's the same time! This is not merely playing with words. NSDate does not intrinsically have a timezone, except perhaps a default with which to interpret strings passed to it. "NSDate has a timezone" would mean that it stores date times *without* a timezone, i.e. the timezone NSDate supposedly "has" would then be implicit. This is not the case. – Bradley Thomas Sep 05 '16 at 20:54
  • @BradThomas - The numeric value stored in the NSDate object is the number of milliseconds since 1 Jan 2001 GMT. Yes, that can also be the number of milliseconds since some other time in some other timezone, but if you start thinking of it that way you will quickly confuse yourself -- I guarantee it. – Hot Licks Sep 05 '16 at 23:03
  • But there's no real need to think of it either way, usually. We usually just need to know that NSDate stores a date time relative to some absolute reference date. We don't really need to know that the Apple docs refer to the reference date in GMT, that time zone specification is not really relevant to knowing the kind of information that is stored in an NSDate – Bradley Thomas Sep 05 '16 at 23:11

5 Answers5

7

You'll need to store the timezone that the ferry ride is taking place in and format it for that timezone.

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"HH:mm"]; 

NSDate *now = [NSDate date];   
NSLog(@"now:%@", [dateFormatter stringFromDate:now]);

NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:(-8 * 3600)];     
[dateFormatter setTimeZone:timeZone];
NSLog(@"adjusted for timezone: %@", [dateFormatter stringFromDate:now]);

Outputs:

2011-10-10 20:42:23.781 Craplet[2926:707] now:20:42
2011-10-10 20:42:23.782 Craplet[2926:707] adjusted for timezone: 16:42
bryanmac
  • 38,941
  • 11
  • 91
  • 99
2

You have seen NSDateFormatter's setTimeZone method, yes?

http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDateFormatter/setTimeZone:

(b.t.w., I'd be amazed if there was a ferry that involved crossing four time zones; sounds like a cruise ship itinerary to me)

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
1

You can also use the NSDateComponents class as described by apple's reference:

If you need to create a date that is independent of timezone, you can store the date as an NSDateComponents object—as long as you store some reference to the corresponding calendar.

In iOS, NSDateComponents objects can contain a calendar, a timezone, and a date object. You can therefore store the calendar along with the components. If you use the date method of the NSDateComponents class to access the date, make sure that the associated timezone is up-to-date.

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtTimeZones.html#//apple_ref/doc/uid/20000185-SW1

Community
  • 1
  • 1
cohen72
  • 2,830
  • 29
  • 44
0

Don't confuse an NSDate value with a formatted output like NSLog. NSDate is GMT, Apple's docs:

The sole primitive method of NSDate, timeIntervalSinceReferenceDate, provides the basis for all the other methods in the NSDate interface. This method returns a time value relative to an absolute reference date—the first instant of 1 January 2001, GMT.

NSTimeInterval referenceInterval = [[dateFormatter dateFromString:@"1 January 2001 GMT"] timeIntervalSinceReferenceDate];
NSLog(@"referenceInterval: %f", referenceInterval);

NSTimeInterval estInterval = [[dateFormatter dateFromString:@"1 January 2001 EST"] timeIntervalSinceReferenceDate];
NSLog(@"estInterval:       %f", estInterval);

Output:

referenceInterval: 0.000000  
estInterval:   18000.000000
zaph
  • 111,848
  • 21
  • 189
  • 228
  • That documentation quote doesn't mean "NSDate is GMT" because 1 January 2001 GMT can be equally expressed in any timezone. – Bradley Thomas Sep 05 '16 at 20:40
  • I'm just trying to understand what you mean by "NSDate is GMT", because I can't see any way that an NSDate value has any internal notion of one timezone in preference to any other (including GMT). Except for the fact that the docs arbitrarily quote the reference date in GMT, and perhaps that NSDate will default to recognizing as GMT when accepting a string if a timezone is not explicitly provided. – Bradley Thomas Sep 06 '16 at 17:27
  • Sure we can - e.g. it's 0.0 relative to 1 Jan 2001 02:00 Budapest time. – Bradley Thomas Sep 06 '16 at 19:43
  • You said it wasn't 0.0 in any other timezone, I showed you how it was 0.0 relative to Budapest timezone. I'm not clear how your latest comment addresses that (or how it shows that "NSDate is GMT") – Bradley Thomas Sep 06 '16 at 19:58
  • I'm saying that fact doesn't mean that in some sense NSDate stores GMT values. It's also 0.0 relative to noon in Kamchatka. Why isn't NSDate therefore Kamchatka time? Or is midnight more special than noon? – Bradley Thomas Sep 06 '16 at 20:05
  • But NSDate also stores date values relative to 1 Jan 2001 02:00 Budapest time! Apple effectively says that because 1 Jan 2001 02:00 Budapest time equals 1 Jan 2001 GMT. To use that to claim that in some sense NSDate stores GMT, is wrong in my opinion. It doesn't store GMT any more than it stores any other timezone, unless you attach special significance to the fact that 0.0 maps to midnight. – Bradley Thomas Sep 06 '16 at 20:25
  • I see, you really do understand but just like to argue, sorry I didn't notice that earlier. Nice down-vote BTW, it's times like this I wonder why I bother trying to help. – zaph Sep 06 '16 at 20:51
  • I down voted because accuracy is important. NSDates do not in any substantial sense represent GMT, yet you claim NSDate is GMT. It really isn't, I believe that statement in your answer is misleading at best, and I'm trying to explain to you why and how I believe that it is misleading. We can disagree and that's ok but that doesn't mean NSDate has any intrinsic timezone, GMT or otherwise. – Bradley Thomas Sep 07 '16 at 12:27
  • "NSDate objects encapsulate a single point in time, independent of any particular calendrical system or time zone." https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/ – Bradley Thomas Sep 07 '16 at 12:49
  • If by NSDate is GMT you mean NSDate stores a relative date time e.g. 1/1/2001 00:00 and GMT is to be assumed in order to arrive at the absolute date time, we both know this to be false. If by NSDate is GMT you mean that NSDate stores an absolute date time and also stores a GMT moniker to show that that time should be represented in GMT, we both know that to be false too, due to the necessity of using NSDateFormatter. Those are the only two meaningful interpretations I can see for "NSDate is GMT" and they are both wrong and they both muddy proper understanding. – Bradley Thomas Sep 07 '16 at 12:55
  • If you mean something else by "NSDate is GMT" I struggle to see what it is, because really it can only validly mean "NSDate stores an absolute date time by maintaining a value relative to an absolute reference date time that Apple docs happen to quote to us in GMT"! – Bradley Thomas Sep 07 '16 at 13:05
-1
        NSDate *currentDateTime =  datePicker.date;
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"EEE,MM-dd-yyyy HH:mm:ss"];
        NSString *dateInStringFormated = [dateFormatter stringFromDate:currentDateTime];
        NSLog(@"%@", dateInStringFormated);
vualoaithu
  • 936
  • 10
  • 9