Parse date string with NSDateFormatter with month begins from 0 - objective-c

I can't parse this date string: #"2002 0 20", where 0 is January (First month in year is 0, not 1).
Can I use NSDateFormatter to parse this string?
Here http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Parsing_Dates_Times I've read that month should starts on 1.
UPDATE
I need this formatter because I have much data in this format (it is not my data).
I've not found any solution with NSDateFormatter without creating a subclass and overriding format methods.
I don't use NSScan, because it is a too complicated solution, but I think #Andy is right.
I use this code to parse the string:
- (BOOL)getObjectValue:(out __autoreleasing id *)obj forString:(NSString *)string range:
(inout NSRange *)rangep error:(out NSError *__autoreleasing *)error
{
int year = 0;
int month = -1;
int day = -1;
int coutRead = sscanf([string cStringUsingEncoding:NSUTF8StringEncoding], "Date.UTC(%i, %i, %i)", &year, &month, &day);
BOOL result = NO;
if (coutRead == 3)
{
NSDateComponents* components = [[NSDateComponents alloc] init];
components.year = year;
components.month = month + 1;
components.day = day;
*obj = [self.calendar dateFromComponents:components];
result = YES;
}
else
{
obj = 0;
*rangep = NSMakeRange(NSNotFound, 0);
result = NO;
}
return result;
}

Try this:
NSDateFormatter* formatter = [NSDateFormatter new];
formatter.timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
formatter.shortMonthSymbols = #[#"0", #"1", #"2", #"3", #"4", #"5", #"6", #"7", #"8", #"9", #"10", #"11"];
formatter.dateFormat = #"yyyy MMM dd"; // Note 3 Ms for "short month" format
NSDate* theDate = [formatter dateFromString:#"2002 0 20"];
Result:
2002-01-20 00:00:00 +0000

No you can't. Parse manually.
At your disposal:
You have NSString that can split string on substrings array using custom delimiter, white space in your case. For example:
-(NSArray*)componentsSeparatedByString:(NSString *)separator
NSScanner that you can use to read integers directly from string.
Documentation is straightforward and comprehensive.

Related

How do you compare date objects to strings in Objective-C?

I have an array of dates in this format:
date: 2012-01-02,2012-03-17,2012-04-09,2012-05-07,2012-06-04,2012-08-06,2012-10-29,2012-12-25,2012-12-26.
I want to compare the dates with today's date, but I need some help. This is my code.
NSArray *date =[dict12 objectForKey:#"ie_date_closed"];
NSLog(#"date:%#",date);
int i=date;
for (i=0; i<6; i++)
{
NSComparisonResult result = [todaydate compare:date[i]];
NSLog(#"result:%d",result);
}
Try below code:-
NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyy-MM-dd"];
for (NSString *arrDt in date){
if ([arrDt isEqualToString:[formatter stringFromDate:[NSDate date]]]){
NSLog(#"Equal Date");}}
Note:- You need to set the dateFormat according to array object dates.
Here is the code have a look at & try to implement your self using it :
for (i=0; i<[date count]; i++)
{
NSDateformatter *format = Define Your date Format Here
NSDate yourDate = [format dateFromString:[date objectAtIndex:i]];
If ([YourDate compare:[NSDate date]] == NSOrderedSame)
{
NSLog(#"Both Dates are same");
}
}
Note : I am not giving you whole readymade code but just for a hint so using it you can be able to implement what you want.
Hope this will help.
try it
NSDate *firstTime;
NSDate *nowTime;
NSDate *localDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
dateFormatter.dateFormat = #"YYYY-MM-dd";
NSString *str = [dateFormatter stringFromDate:localDate];
NSArray *date =[dict12 objectForKey:#"ie_date_closed"];
NSLog(#"date:%#",date);
for (i=0; i<[date count]; i++)
{
NSString *openTime =[NSString stringWithFormate:"%#"[date objectAtindex:i]];
NSDateFormatter *dateComperFormatter1 = [[NSDateFormatter alloc] init];
[dateComperFormatter1 setTimeZone:[NSTimeZone systemTimeZone]];
[dateComperFormatter1 setDateFormat:#"YYYY-MM-dd"];
firstTime = [dateComperFormatter1 dateFromString:openTime];
nowTime = [dateComperFormatter1 dateFromString:str];
// NSComparisonResult result;
// // has three possible values: NSOrderedSame,NSOrderedDescending, NSOrderedAscending
//
// result = [nowTime compare:firstTime]; // comparing two dates
NSComparisonResult result = [nowTime compare:firstTime];
}

Manipulate string in objective-c to remove substring between 2 characters

I want to parse a date string that I receive from a web service. However, I sometimes receive the date with decimal component and sometimes without decimal component. Also, sometimes the date comes with a different number of decimal digits.
Assume you got the following date:
NSString *dateString = #"2013-07-22T220713.9911317-0400";
How can remove the decimal values? I want to end up with:
#"2013-07-22T220713-0400";
So I can process it with the DateFormatter that uses no decimal.
You could use a regular expression to match the first occurrence of a decimal followed by numbers, and remove them:
NSString *dateString = #"2013-07-22T220713.9911317-0400";
NSRegularExpression * regExp = [NSRegularExpression regularExpressionWithPattern:#"\\.[0-9]*" options:kNilOptions error:nil];
dateString = [dateString stringByReplacingCharactersInRange:[regExp rangeOfFirstMatchInString:dateString options:kNilOptions range:(NSRange){0, dateString.length}] withString:#""];
Based on #JeffCompton 's suggestion I ended up doing this:
+ (NSDate *)dateFromISO8601:(NSString *)dateString {
if (!dateString) return nil;
if ([dateString hasSuffix:#"Z"]) {
dateString = [[dateString substringToIndex:(dateString.length - 1)] stringByAppendingString:#"-0000"];
}
NSString *cleanDateString = dateString;
NSArray *dateComponents = [dateString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"."]];
if ([dateComponents count] > 1){
NSArray *timezoneComponents = [[dateComponents objectAtIndex:1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"-"]];
if ([timezoneComponents count] > 1){
cleanDateString = [NSString stringWithFormat:#"%#-%#", [dateComponents objectAtIndex:0], [timezoneComponents objectAtIndex:1]];
}
}
dateString = [cleanDateString stringByReplacingOccurrencesOfString:#":" withString:#""];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-d'T'HHmmssZZZ";
NSDate *resultDate = [dateFormatter dateFromString:dateString];
return resultDate;
}
This is a modification of some open-source code but I lost the reference to the original code.
The reason for all the modifications is that I am connecting to API's that can give me the date with decimals or without, and sometimes without the : separating HH, mm, and ss.

Unable to convert original date using dateFromString

I am trying to convert a time string using the following code
NSString *origDate = #"2012-12-06T09:27:18+08:00";
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setFormatterBehavior:NSDateFormatterBehavior10_4];
[df setDateFormat:#"yyyy-mm-dd HH:mm:ss VVVV"];
NSDate *convertedDate = [df dateFromString:origDate];
However when I print the convertedDate, it returns me null. My guess is that the Date format U am using does not match. How can I modify the code to make it work? What format can I use to match my string?
EDIT (After referring to apple's documentation)
I checked the date format documentation on apple's page and found the following code
NSDateFormatter *rfc3339DateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[rfc3339DateFormatter setLocale:enUSPOSIXLocale];
[rfc3339DateFormatter setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
[rfc3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
// Convert the RFC 3339 date time string to an NSDate.
NSDate *date = [rfc3339DateFormatter dateFromString:rfc3339DateTimeString];
The format above seems to match what I have in the original date string "2012-12-06T09:27:18+08:00". However I am still getting a null value back. Am I getting closer? How else can I update this?
Based on your original input, this format string provided to your date formatter should get the job done:
#"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZZZ"
Note: I had tested this under Mac OS X 10.8.2.
The format String will parse on iOS6 (not iOS5 -> nil) but it is useless for output, since the parsed date will loose it's timezone information.
Output will be something like "2012-12-06T17:27:18Z" in iOS6 maybe this is depending on wether the timezone is set to GMT.
my Code:
static NSDateFormatter *gXmlDateFormatter = nil;
// lazy init
+ (NSDateFormatter *)xmlDateFormatter
{
// e.g. updateDateTime="2012-09-18T11:06:19+00:00"
if (gXmlDateFormatter == nil) {
// prepare for parsinf Arinc-ISO-XML-dates input
gXmlDateFormatter = [[NSDateFormatter alloc] init];
gXmlDateFormatter = [NSTimeZone timeZoneForSecondsFromGMT:0];
gXmlDateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
gXmlDateFormatter.dateFormat = #"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZZZ"; // only parsing! in iOS 6 (iOS5 will parse nil)
// gXmlDateFormatter.dateFormat = #"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"; // all iOS but with NO colons in timeZone (add/remove)
}
NSLog(#"gXmlDateFormatter:%#",gXmlDateFormatter);
return gXmlDateFormatter;
}
// there's a problem with the above dateformater and iOS5 creating nil-results
+ (NSDate *)dateFromXMLString:(NSString *)arincDateString
{
NSString *dateString = arincDateString;
// xmlDateStrings may contain a ':' in the timezone part. iOS and Unicode DO NOT
// so always remove the xml-standard colon ':' from the timezone to make it iOS/Unicode compatible
// xml: http://www.w3schools.com/schema/schema_dtypes_date.asp
// iOS: http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns)
NSRange zRange = NSMakeRange(arincDateString.length-3, 1);
dateString = [arincDateString stringByReplacingOccurrencesOfString:#":" withString:#"" options:0 range:zRange];
NSDate *date = [self.arincDateFormatter dateFromString:dateString];
if(!date)NSLog(#"PARSING arincDateString:'%#' -> (NSDate*)%# ",arincDateString,date);
return date;
}
+ (NSString *)xmlStringFromDate:(NSDate *)date
{
if( !date ) return nil; // exit on nil date
#autoreleasepool {
NSString *dateString = [self.arincDateFormatter stringFromDate:date];
// iOS5 does not use a ':' in the timeZone part but xml needs it
// so allways add the xml-standard colon ':' into the timezone
NSMutableString *string = [NSMutableString stringWithString:dateString];
if( 22 < string.length ) { // prevent crashing
[string insertString:#":" atIndex:22];
} else {
NSLog(#"date output string too short:%d<22",string.length);
}
dateString = string;
if(!dateString)
NSLog(#"OUTPUT '%#' -> (NSString*)%#",date,dateString);
return dateString;
}
}

Localized date (month and day) and time with NSDate

I want to be able to get the local date and time for wherever my app is run, based on the iPhone configuration. Specifically I need the date to be of format mm/dd or dd/mm (or dd.mm, mm.dd, dd-mm, mm-dd, etc) depending on the locale, and time is hh:mm. Is this possible with some combination of SDK methods?
Thanks!
I have modified the code so that it just takes the date and time out of the NSDate object with no changes:
NSDate* date = [NSDate date];
NSString* datePart = [NSDateFormatter localizedStringFromDate: date
dateStyle: NSDateFormatterShortStyle
timeStyle: NSDateFormatterNoStyle];
NSString* timePart = [NSDateFormatter localizedStringFromDate: date
dateStyle: NSDateFormatterNoStyle
timeStyle: NSDateFormatterShortStyle];
NSLog(#"Month Day: %#", datePart);
NSLog(#"Hours Min: %#", timePart);
Well, I believe the following code works for what I need:
NSString *dateComponents = #"yMMd";
NSString *dateFormat = [NSDateFormatter dateFormatFromTemplate:dateComponents options:0 locale:[NSLocale currentLocale]];
NSArray *tmpSubstrings = [dateFormat componentsSeparatedByString:#"y"];
NSString *tmpStr;
NSRange r;
if ([[tmpSubstrings objectAtIndex:0] length] == 0) {
r.location = 1;
r.length = [[tmpSubstrings objectAtIndex:1] length] - 1;
tmpStr = [[tmpSubstrings objectAtIndex:1] substringWithRange:r];
} else {
r.location = 0;
r.length = [[tmpSubstrings objectAtIndex:0] length] - 1;
tmpStr = [[tmpSubstrings objectAtIndex:0] substringWithRange:r];
}
NSString *newStr = [[NSString alloc] initWithFormat:#"%# H:mm", tmpStr];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:newStr];
NSString *formattedDateString = [formatter stringFromDate:[NSDate date]];

How to display date as "15th November 2010" in iPhone SDK?

HI,
I need to display date as "15th November 2010" in iPhone SDK.
How do I do that?
Thanks!
You can use a Date Formatter as explained in this post:
// Given some NSDate* date
NSDateFormatter* formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"dd MMM yyyy"];
NSString* formattedDate = [formatter stringFromDate:date];
I believe you can simply just put "th" at the end of the dd in the format string. like this:
#"ddth MMM yyy
but I don't have my Mac in front of me to test it out. If that doesn't work you can try something like this:
[formatter setDateFormat:#"dd"];
NSString* day = [formatter stringFromDate:date];
[formatter setDateFormat:#"MMM yyyy"];
NSString* monthAndYear = [formatter stringFromDate:date];
NSString* date = [NSString stringWithFormat:#"%#th %#", day, monthAndYear];
I know I'm answering something old; but I did the following.
#implementation myClass
+ (NSString *) dayOfTheMonthToday
{
NSDateFormatter *DayFormatter=[[NSDateFormatter alloc] init];
[DayFormatter setDateFormat:#"dd"];
NSString *dayString = [DayFormatter stringFromDate:[NSDate date]];
//yes, I know I could combined these two lines - I just don't like all that nesting
NSString *dayStringwithsuffix = [myClass buildRankString:[NSNumber numberWithInt:[dayString integerValue]]];
NSLog (#"Today is the %# day of the month", dayStringwithsuffix);
}
+ (NSString *)buildRankString:(NSNumber *)rank
{
NSString *suffix = nil;
int rankInt = [rank intValue];
int ones = rankInt % 10;
int tens = floor(rankInt / 10);
tens = tens % 10;
if (tens == 1) {
suffix = #"th";
} else {
switch (ones) {
case 1 : suffix = #"st"; break;
case 2 : suffix = #"nd"; break;
case 3 : suffix = #"rd"; break;
default : suffix = #"th";
}
}
NSString *rankString = [NSString stringWithFormat:#"%#%#", rank, suffix];
return rankString;
}
#end
I grabbed the previous class method from this answer: NSNumberFormatter and 'th' 'st' 'nd' 'rd' (ordinal) number endings