1

I wish to modify current system time (set a custom NSTimeZone) and get back a new NSDate object.

The code I've made

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
NSLog(@"System time: %@", [dateFormatter stringFromDate:[NSDate date]]);
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Aqtobe"]];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(@"Aqtobe time: %@", dateString);

The output

System time: 2014-02-05 10:00:46 +0000

Aqtobe time: 2014-02-05 15:00:46 +0500

But if I try to get new NSDate object from Aqtobe time:

NSLog(@"New NSDate: %@", [dateFormatter dateFromString:dateString]);

I get

New NSDate: 2014-02-05 10:02:40 +0000

Where I was wrong? Thanks in advance

Artem Z.
  • 1,243
  • 2
  • 14
  • 36
  • 4
    `NSDate` will always return GMT. You can format it to whatever timezone you want when you print it (like you did). You can find more information [here](http://stackoverflow.com/questions/5214947/help-me-understand-nsdate-date) – Gad Feb 05 '14 at 10:15
  • I don't completely understand. You want to check if a date is between two dates? – Gad Feb 05 '14 at 10:26
  • I'll write it as an answer due to lack of room. – Gad Feb 05 '14 at 10:35
  • You are not providing the timezone.. Default timezone is GMT. So it is providing that same date – Himanshu Joshi Feb 05 '14 at 10:35

3 Answers3

3

NSDate always returns date in GMT +0:00. So, it (NSDate object) always have correct converted value but in GMT +0:00. So for using it as text you will always have to use same date formatter with same zone. If you want to use date as string from date in other places (out of dateformatter object scope), it is better to make special method for conversion.

It is explained clearly below with example:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss Z";

NSLog(@"System time: %@", [dateFormatter stringFromDate:[NSDate date]]);

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Aqtobe"]];

NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(@"Aqtobe time: %@", dateString);

// date will always contain value in GMT +0:00
NSDate *date = [dateFormatter dateFromString:dateString];
NSLog(@"New NSDate (NSDate): %@", [dateFormatter stringFromDate:date]);

// converts date into string
NSLog(@"New NSDate (NSString): %@", [dateFormatter stringFromDate:date]);

For detailed explaination you can refer this question: Does [NSDate date] return the local date and time?

Community
  • 1
  • 1
Nitesh Borad
  • 4,583
  • 36
  • 51
1

NSDate has many methods for comparing date such as isEqualToDate: (for a more detailed of the methods and usage you can see this SO question). This method, that I took from here, will let you determine if date is between firstDate and lastDate.

- (BOOL)isDate:(NSDate *)date inRangeFirstDate:(NSDate *)firstDate lastDate:(NSDate *)lastDate {
   return [date compare:firstDate] == NSOrderedDescending &&
          [date compare:lastDate]  == NSOrderedAscending;
}

I hope this is what you meant. If not please explain exactly what you're trying to do.

Community
  • 1
  • 1
Gad
  • 2,867
  • 25
  • 35
  • Yes, I've found the method how to check if date between 2 dates. My problem: I got 2 dates (called startTime and endTime) from server API (there are already with Aqtobe timezone `"start_time":"2000-01-01T15:00:00Z","end_time":"2000-01-01T16:00:00Z"`) and I have to check if my system time (It must be with Aqtobe timezone!) is between these 2 dates. – Artem Z. Feb 05 '14 at 10:55
  • I've tried to use `[dateFormatter dateFromString]`. But it takes my system date without timezone correction which I've explained in my question. – Artem Z. Feb 05 '14 at 10:57
0

You can use NSDateComponents and NSCalendar to create a new date. From the Date and Time Programming Guide

Creating Dates with Time Zones

Time zones play an important part in determining when dates take place. Consider a simple calendar application that keeps track of appointments. For example, say you live in Chicago and you have a dentist appointment coming up at 10:00 AM on Tuesday. You will be in New York for Sunday and Monday, however. When you created that appointment it was done with the mindset of an absolute time. That time is 10:00 AM Central Time; when you go to New York, the time should be presented as 11:00 AM because you are in a different time zone, but it is the same absolute time. On the other hand, if you create an appointment to wake up and exercise every morning at 7:00 AM, you do not want your alarm to go off at 1:00 PM simply because you are on a business trip to Dublin—or at 5:00 AM because you are in Los Angeles.

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.

Listing 16 Creating a date from components using a specific time zone

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 *date=[gregorian dateFromComponents:timeZoneComps];

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.

Anyway, keep in mind that a date is a unique point in time. What you display to the user is different based on their locale and time zone.

Gianluca Tranchedone
  • 3,598
  • 1
  • 18
  • 33