NSDateFormatter NSString w/ day suffix to NSDdate - objective-c

I'm trying to use only a NSDateFormatter to format string representation of a date/time to an NSDate object. The issue is that I can't figure out how to allow the ordinal suffixes in the format.
So lets say I have a string
"Wednesday, August 11th 2010 8:00 PM"
What one line NSDate dateFormat should I use?
Like "EEEE, MMM dd'th' yyyy h:mm a" would work, but that will only work for ordinal days ending in 'th', whereas i need a single format that will allow for 1st, 2nd, 3rd, 4th 5th etc.
It seems like a wildcard character in the format string to accomplish this. I've tried a few things like: % * ?

This is apparently not possible with the NSDateFormatter.

You want to use an NSDateFormatter like so:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle: NSDateFormatterLongStyle];
NSDate *date = [dateFormatter dateFromString:dateString];
[dateFormatter release];
Either NSDateFormatterLongStyle or NSDateFormatterFullStyle should get you the results you're looking for.

Related

Make NSDateFormatter emit the string "UTC" instead of the string "GMT"?

I have the following Objective-C code that attempts to generate a string with the current date/time in UTC:
NSDate *currentDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *utc = [NSTimeZone timeZoneWithName:#"UTC"];
[dateFormatter setTimeZone:utc];
[dateFormatter setDateFormat:#"YYYY-MM-dd--HH-mm-ss zzz"];
NSString *utcDateString = [dateFormatter stringFromDate:currentDate];
This code almost generates what I want. The resulting value of utcDateString on my system is:
2019-06-17--22-28-13 GMT
However, my desired output includes the string "UTC", not "GMT", as in:
2019-06-17--22-28-13 UTC
Is there a way to get the NSDateFormatter to emit the string "UTC" for the zzz portion of the date format? I'd prefer not to have to resort to leaving the "zzz" off of my date format string, and then manually append a "UTC" onto the resulting date string.
There is no date format specifier that returns UTC.
Since you are hardcoding the UTC timezone for the formatter, then simply hardcode the string UTC in the date format.
Also note that you want yyyy, not YYYY for the year.
[dateFormatter setDateFormat:#"yyyy-MM-dd--HH-mm-ss 'UTC'"];
If you need to handle other timezones and want GMT to appear as UTC, then use zzz (as you already are) and use string replacement on the result to convert GMT to UTC.
One other possible idea to consider is to use some number of X for the timezone specifier. This will give the timezone offset as numbers but if the timezone offset is 0, then it results in Z (for Zulu).

NSDate being set to the day before [duplicate]

This question already has answers here:
NSDate Format outputting wrong date
(5 answers)
Closed 7 years ago.
Important update: Of you hover over a NSDATE with your mouse the degugger will convert the NSDate to your local timezone you have set on you Mac, but if you do a NSLOG you will notice that the NSDate is using the timezone that you assigned to the its respective formatter.
If you want to see in the xcode debugger what the NSDate is for the timezone you are working with go to your date/time settings for you Mac OS and change the Timezone to the one you are testing.
I require a NSDate to be created from the date I pass in, but currently it is set to the the day before I pass in:
NSString *dateStr = #"2015-08-09";
NSDateFormatter *myformatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [formatter dateFromString:dateStr];
The code above returns: an NSDate set to '2015-08-08 12:00:00 +0000'
I need an NSDate object set to the datStr I pass in.
This perhaps, from this:
Convert NSDate to NSString with NSDateFormatter with TimeZone without GMT Time Modifier
leave the 'z' lowercase for named timezone, i.e. PST and uppercase 'Z' for -0800
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"MMMM dd, yyyy (EEEE) HH:mm:ss z Z"];
NSDate *now = [NSDate date];
NSString *nsstr = [format stringFromDate:now];
Also, you date should be more robust, like if you want to pass in the current day that your are passing in and it's one day off, then just add a day. The problem, it seems is that the date is returning the correct date which is the end of the last day, add 1 second or a millisecond and it'll probably be corrected, or just hack attack this and add 1 day to the days you are passing in. Be smart! Sometimes you just have to add 1 day to fix stuff and move on.

Converting NSString to NSDate adds one year in some cases

I have some issues converting an NSString to NSDate since the end of the year. The code have always worked great before, but it suddenly started to behave wierd...
For example 2013-01-05 becomes 2014-01-05 when converted to NSDate.
Since it's a whole year it doesn't feel like it's the timezone spooking.
It's not doing this with dates from 2012.
Does anybody have an idea of what might be wrong?
Code:
NSString *dateString = postInfo.noteDate;
NSString *newDateString = [dateString substringToIndex:10];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd"];
NSDate *date = [[NSDate alloc] init];
date = [dateFormat dateFromString:newDateString];
newDateString returns 2013-01-05
date returns 2014-01-05
From the docs:
Y 1..n 1997 Year (in "Week of Year" based calendars). Normally the length specifies the padding, but for two letters it also specifies the maximum length. This year designation is used in ISO year-week calendar as defined by ISO 8601, but can be used in non-Gregorian based calendar systems where week date processing is desired. May not always be the same value as calendar year.
y 1..n 1996 Year. Normally the length specifies the padding, but for two letters it also specifies the maximum length.
So you want 'yyyy'
This 'bug' is also discussed in the fantastic WWDC 2011 Video "Session 117 - Performing Calendar Calculations", a must-see for any iOS/Cocoa-Developer.
Wikipedia article on ISO 8601
NSDate *date = [[NSDate alloc] init];
date = [dateFormat dateFromString:newDateString];
You create a NSDate and than you create another and overwrite the first one. Just do
NSDate *date = [dateFormat dateFromString:newDateString];
use yyyy for year not YYYY, which gives week year. see the ISO standard.
Use yyyy in small letters, YYYY is another thing:
Year (in "Week of Year" based calendars). This year designation is used in ISO year-week calendar as defined by ISO 8601, but can be used in non-Gregorian based calendar systems where week date processing is desired. May not always be the same value as calendar year.
see http://www.unicode.org/reports/tr35/tr35-19.html#Date_Format_Patterns
I hope this will helps u. Try this
- (NSDate*) dateFromString:(NSString*)aStr
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"] autorelease]];
[dateFormatter setDateFormat:#"MM/dd/yyyy HH:mm:ss a"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSLog(#"%#", aStr);
NSDate *aDate = [dateFormatter dateFromString:aStr];
[dateFormatter release];
return aDate;
}

Discrepancy between SQLite's strftime / julianday and Cocoa's timeIntervalSince1970?

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *date1 = [dateFormatter dateFromString:#"1213-02-27"];
NSTimeInterval nsdateResult = [date1 timeIntervalSince1970];
NSTimeInterval sqliteResult = -23883638400;
GHAssertEquals(sqliteResult, nsdateResult, #"sqlite and nsdate should agree");
The expected number is what SQLite tells me should be the result, but this test fails since Cocoa tells me -23883033600 instead of -23883638400...i.e. 4 days later!
What gives? Am I doing something wrong or is either SQLite or Cocoa wrong?
Edit
Just checked the math and it seems Cocoa is giving me a wrong value: according to Wolfram Alpha, there are 276431 days between 2/27/1213 and 1/1/1970. Take this times 24*60*60, and you get the value given by SQLite... so am I doing something wrong or is this some kind of Cocoa bug?
Edit 2
Fvu is right, it has to do with the Gregorian/Julian craziness back in 1582.
NSDate *date1 = [dateFormatter dateFromString:#"1582-10-15"];
NSDate *date2 = [dateFormatter dateFromString:#"1582-10-14"];
NSTimeInterval i = [date2 timeIntervalSinceDate:date1];
Surprisingly, i is 777600, i.e. 10/14 is 9 days LATER than 10/15 because it automatically is viewed as a Julian date whereas 10/15 is viewed as a Gregorian date. So basically what I will need to do is convert any dates before 10/15 from the Julian to the Gregorian calendar.
Your sample date predates the Gregorian calendar so I think some oddities can be expected. However, as at the introduction of the Gregorian calendar the date advanced by 10 days I don't have a bulletproof explanation for the calculated 4 day difference.

NSDateFormatter problem

I am trying to get NSDate from string but its returning nil.
I tried this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-mm-dd'T'HH:mm:ss'Z'"];
NSDate *date = [dateFormatter dateFromString:#"2010-05-07T10:12:32UTC"];
NSLog(#"Success date=%#",[date description]);
Thanks
Your date format string expects the date to end with a literal Z. But your date ends with the string UTC. There are several ways to fix this.
Change your date format string to #"yyyy-mm-dd'T'HH:mm:ss'UTC'".
Or, change your date string to #"2010-05-07T10:12:32Z".
Or, you could change your date format string to: #"yyyy-mm-dd'T'HH:mm:ssz". This will recognize some common 3-letter time zone names, such as PDT for Pacific Daylight Time. Unfortunately, however, it will not recognize UTC as a time zone name (you’d have to use “GMT”).
The literal 'Z' won't match the string UTC.