Apple's NSDateFormatter Class Reference lists, as an example string for NSDateFormatterFullStyle:
Specifies a full style with complete details, such as “Tuesday, April
12, 1952 AD” or “3:30:42pm PST”
In practice, I'm getting strings along the lines of:
Tuesday, April 12, 1952
by using code like:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeStyle = NSDateFormatterNoStyle;
dateFormatter.dateStyle = NSDateFormatterFullStyle;
[dateFormatter stringFromDate:date];
This is the behavior I see in the iOS 5.0 and 4.3 simulators.
Does -[NSDateFormatter stringFromDate:] only append the "AD" string for certain dates? If so, when can I expect it to happen?
There doesn't seem to be anything in the system's region format setting that would affect this.
It also doesn't seem to depend on -[NSDateFormatter eraSymbols] or -[NSDateFormatter longEraSymbols]. In my tests, both are set by default and changing them doesn't change the result of -[NSDateFormatter stringFromDate:].
The actual result that I want is the string that is being generated (without the "AD"), I just want to be sure that I'm doing things correctly.
Maybe this is just a documentation error. If so, I will file a bug report, but I wanted to make sure I wasn't missing anything before doing so.
Related
+(NSDate *)DateServerFormatFromString:(NSString *)date
{
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init] ;
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_GB"];
[dateFormatter setLocale:locale];
[dateFormatter setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
NSDate* returnDate = [dateFormatter dateFromString:date];
return returnDate;
}
The function returns date in format "2013-05-09 08:06:04 AM +0000". But i want it in 24 hour format. The date being passed to this function is in the exact same format as given in setDateFormat method.
The device's region format is set to "United Kingdom" and time format is set to "12 hour format". This should not be changed. When time format is set to 24 hour format in the device, the function works perfectly. What is wrong with the code. I am using iPad 1 with OS 5.1.1. Setting locale identifer or even timezone didnt make a difference. Thanks in advance.
This is not necessarily an answer, just an explanation, found in the Apple docs (here):
Although in principle a format string specifies a fixed format, by
default NSDateFormatter still takes the user’s preferences (including
the locale setting) into account. You must consider the following
points when using format strings:
NSDateFormatter treats the numbers in a string you parse as if they
were in the user’s chosen calendar. For example, if the user selects
the Buddhist calendar, parsing the year 2010 yields an NSDate object
in 1467 in the Gregorian calendar. (For more about different
calendrical systems and how to use them, see Date and Time Programming
Guide.)
In iOS, the user can override the default AM/PM versus 24-hour
time setting. This may cause NSDateFormatter to rewrite the format
string you set.
The problem here is how you're getting the string. You say you got it
by printing the description of returnDate
However, according to the documentation, the -description method says this:
The representation is useful for debugging only.
There are a number of options to aquire a formated string for a date including: date formatters (see NSDateFormatter and Data Formatting Guide), and the NSDate methods descriptionWithLocale:, dateWithCalendarFormat:timeZone:, and descriptionWithCalendarFormat:timeZone:locale:
What this means is that the value returned by -description does not respect any 12- or 24-hour time settings. It's just a debug version.
If you want to express a date as a human-readable string, you must use an NSDateFormatter.
Again and again:
Did you NSLog() the date? Logging a date is always been done in a normalized standard format. If you want to log a date formatted, log the result of a formatter, not the date directly.
You want 24h format for what? Format is used to convert NSDate to NSString with correct string format. Just make reverse converting when you need it
12 hour format
[dateFormatter setDateFormat:#"dd/MM/yyyy hh:mm:ss"];
24 hour format
[dateFormatter setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
Our iOS iPhone app contains this code which produced a valid NSDate object below named resultDate in iOS 5:
static NSDateFormatter *invariantFmt = nil;
if (!invariantFmt) {
invariantFmt = [[NSDateFormatter alloc] init];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[invariantFmt setLocale:locale];
[locale release];
[invariantFmt setDateStyle:NSDateFormatterShortStyle];
[invariantFmt setTimeStyle:NSDateFormatterMediumStyle];
}
NSDate *resultDate = [invariantFmt dateFromString:#"08/04/2010 10:43:39 AM"];
After upgrading to XCode 4.6 and iOS 6.1, that code now gives a nil for resultDate, so something has changed with what they use to parse. The release notes says nothing about NSDateFormatter changing. Internet research has turned up only that they might have changed to use a newer Unicode UTS Locale parsing standard. Obviously they changed something. After twiddling with code and taking a known valid NSDate object and applying the same NSDateFormatter settings to get a NSString, I find that iOS 6.1 likes this string instead: #"08/04/2010, 10:43:39 AM"
The only difference being that extra comma after the date portion. Using that in iOS 6.1 gives back a valid date with the same above code. Anyone seeing this and understand why that's different or if that's an ok Unicode change or a Apple bug?
The format styles should only be used to convert NSDate objects to text to display to the user. When parsing a date string in a known format, you must use a specific format, never the styles. The use of the en_US_POSIX locale is used to ensure that the format you specify isn't tweaked by the OS based on user preferences such as the 24-hour time setting.
So, as you suspected, you need to remove the two calls to set the date and time styles and replace them with a call to set a specific format that matches your known date/time string you need to parse.
Generally you should not output a formatted Date to a file, and later want to parse it back.
A Date should be stored as long value UTC (with or without additional TimeZone offset).
Only in the last moment, before visualizing a Date to UI it should be formatted and local time applied.
This not only i smy experience, it it is also stated in Apple DateFormatting Doku.
What am I doing wrong?
I am trying to getNSDateFormatter to translate custom patterns for dates using the current locale.
Example:
dateFormat = [[NSDateFormatter alloc] init];
dateFormat.locale = [NSLocale currentLocale];
[dateFormat setDateFormat:#"MMM"];
output = [self.dateFormat stringFromDate:dateObject];
No matter what I change my current locale settings to, I always see the English month abbreviations.
Thanks for any help you can provide.
It looks like it was working all of the time. I had been leaving my location set to United States and changing only the language. To get it to work correctly you have to change the location as well as the language.
How can I parse this into an objective-c NSDate most efficiently?
"2010-07-13T11:22:33-07:00"
This is what I tried
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"yyyy-MMM-dd'T'HH:mm:ssZ"];
but did not work
have a look here, i had that issue
"The format that I am being given is halfway between RFC 822 and GMT. if i change the "+00:00" to "+0000" then I can use the "Z" on my format. and if i change it to "GMT+00:00" then I can use ZZZZ to get the data properly. It seems that something has been stripped out to handle this hybrid as it was working for me before with OS 3.x"
I store my NSDates to a file in the international format you get when you call description on a NSDate.
However, I don't know how to go back from the string-format to an NSDate object. NSDateFormatter seems to be limited to a couple of formats not including the international one.
How should I go back from the string-format?
Jeff is right, NSCoding is probably the preferred way to serialize NSDate objects. Anyways, if your really want/need to save the date as a plain date string this might help you:
Actually, NSDateFormatter isn't limited to the predefined formats at all. You can set an arbitrary custom format via the dateFormat property. The following code should be able to parse date strings in the "international format", ie. the format NSDate's -description uses:
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss ZZZ";
NSDate* date = [dateFormatter dateFromString:#"2001-03-24 10:45:32 +0600"];
For a full reference on the format string syntax, have a look at the Unicode standard.
However, be careful with -description - the output of these methods is usually targeted to human readers (eg. log messages) and it is not guaranteed that it won't change its output format in a new SDK version! You should rather use the same date formatter to serialize your date object:
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss ZZZ";
NSString* dateString = [dateFormatter stringFromDate:[NSDate date]];
Instead of saving the description to a file, why not save the object itself? NSDate conforms to the NSCoding protocol; saving the object means you don't have to worry about translating it. See the NSCoding protocol reference for more information.
I would try to set up an NSDateFormatter to successfully parse the string by the following method:
- (NSDate *)dateFromString:(NSString *)string
Note that it could take you a while to get the NSDateFormatter set up just right to successfully parse your string.
If you're going to store program-facing data like this I would also recommend storing it in an easier-to-access format, e.g., CFAbsoluteTime. Once you have it in your program you can format it into the international format or something else human-readable.
Convert it to a format NSDate accepts and then perform the conversion back.
Alternatively, depending on which NSDate you're referring to (!) initWithString should cover international standard dates.