I have a NSDate object. Let's say it represents "1-10-2011"
NSDate *date = [df dateFromString:@"2011-10-01 00:00:00"];
That date translates into "2011-09-30开发者_如何学Go 22:00:00" because of my timezone.
Question: How do I get a new Date object representing "2011-10-01 00:00:00" in my local timezone?
NSDate only represents an absolute point in time. It has no concept of timezone or calendar. When you create a NSDate instance it is just a number of seconds since January 1st 2001 GMT! It does not matter if you are in New York, Tokyo, Barcelona or Jerusalem.
At your example, you instance the NSDate based on GMT, but [date description]
(used in NSLog
) translates it into your local time. There you have the mismatch.
So there are two parts to consider:
1. NSDate creation using NSCalendar and NSTimeZone
If you are creating a date manually you should specify the calendar (2012 in Gregorian, but 5772 in Hebrew) and time zone (22PM London time, but 7AM Sydney time).
// Use the user's current calendar and time zone
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setTimeZone: [NSTimeZone systemTimeZone]];
// Specify the date components manually (year, month, day, hour, minutes, etc.)
NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init];
[timeZoneComps setHour:22];
[timeZoneComps setMinute:0];
[timeZoneComps setSecond:0];
// ... year, month, ...
// transform the date compoments into a date, based on current calendar settings
NSDate *date = [calendar dateFromComponents:timeZoneComps];
At this point date stores the exact point in time (in seconds) representing the current calendar.
2. NSDate output using NSDateFormatter
For a controlled output of your NSDate you need NSDateFormatter, which is used to convert dates into strings.
Based on Apple NSDateFormatter Class Reference documentation
There are many attributes you can get and set on a style date formatter, ... You are encouraged, however, not to change individual settings. Instead you should accept the default settings established on initialization and specify the format using setDateStyle:, setTimeStyle:
This is specially important for the output, which is different for every locale. By default NSDateFormatter observes the current user’s locale settings. So the same NSDate could be 22.11.2011 18:33:19
, or Nov 22, 2011 6:33:19 PM
, or 2011-11-22 下午6:33:19
or even २२-११-२०११ ६:३३:१९ अपराह्
, all for the same input and with the same code.
And the code:
// NSDate *date -> NSString *dateString
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
// Medium style date, short style time => "Nov 23, 1937 3:30pm"
NSString *dateString = [dateFormatter stringFromDate:date];
Or you could transform it using the class method localizedStringFromDate:dateStyle:timeStyle:
I hope this clarifies the problem.
[NSDate date]
returns the date in GMT.
When you state:
That date translates into "2011-09-30 22:00:00" because of my timezone.
Is that from NSLog
or NSDateFormatter
? Don't rely in [date description]
which NSLog uses, it takes into account your local timezone, use NSDateFormatter
. NSDateFormatter
has a setTimeZone
method.
From Apple docs on [date description]
:
The representation is not guaranteed to remain constant across different releases of the operating system. To format a date, you should use a date formatter object instead
精彩评论