setting date format for NSDateFormatter - ios

I am trying to set the date format for something like "2011-04-21 03:31:37.310396". I think I'm not getting the fractional seconds right. I'm looking at http://unicode.org/reports/tr35/tr35-10.html#Date_Format_Patterns for guidelines on how to specify it and I think my issue is in the format itself.
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ssSSSSSS";
NSDate* serverDate = [dateFormatter dateFromString:stringFormOfDate];
Help?

try
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss.SSSSSS";
NSDate* serverDate = [dateFormatter dateFromString:#"2011-04-21 03:31:37.310396"];
NSLog(#"%#", serverDate);
I guess you probably forgot the dot

As per Zaph's comment in the other answer: the maximum number of S is 3. Any more just produce zeros.
E.g.
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss.SSSSSS"; // Last 3 'S' ignored.
Then #"2011-04-21 03:31:37.311396" will produce 2011-04-21 03:31:37.311000
To maintain full microsecond precision try this magic:
-(NSDate *)_dateFromUtcString:(NSString *)utcString{
if(!utcString){
return nil;
}
static NSDateFormatter *df = nil;
if (df == nil) {
df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[df setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
}
NSArray* parts = [utcString componentsSeparatedByString:#"."];
NSDate *utcDate = [df dateFromString:parts[0]];
if(parts.count > 1){
double microseconds = [parts[1] doubleValue];
utcDate = [utcDate dateByAddingTimeInterval:microseconds / 1000000];
}
return utcDate;
}
Now an NSString "2011-04-21 03:31:37.310396" will parse fully to an NSDate 2011-04-21 03:31:37.310396

Related

IOS: NSDateFormatter

I am trying to create something similar to Kevin Lawler's Timeago for future dates. It seems that using dateFormatter and setting SetDoesRelativeDateFormatting:YES is the closest native api to that library or similar libraries in other languages. Apple provides the sample code below that I have working. However, its future capability is limited to swapping tomorrow for tomorrow's date and so I am trying to combine it with NSDateFormatter. For some reason, however, I can't get the two to work together.
Apple reference code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeStyle = NSDateFormatterNoStyle;
dateFormatter.dateStyle = NSDateFormatterMediumStyle;
dateFormatter.doesRelativeDateFormatting = YES;
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:60*60*24*3];
NSString *dateString = [dateFormatter stringFromDate:date];
NSLog(#"dateString: %#", dateString); //logs valid output
If instead of using timestyle or datestyle, however, I use setDateFormat when I log out the result, I get nil.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssz"];
dateFormatter.doesRelativeDateFormatting = YES;
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:60*60*24*3];
NSString *dateString = [dateFormatter stringFromDate:date];
NSLog(#"dateString: %#", dateString); //logs blank
Does doesRelativeDateFormatting only work with NSDateFormatterMediumStyle or can you combine it with setDateFormat in some way that I am not seeing?
Please use below code it worked for me
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeStyle = NSDateFormatterNoStyle;
dateFormatter.dateStyle = NSDateFormatterMediumStyle;
dateFormatter.doesRelativeDateFormatting = YES;
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:60*60*24*3];
NSString *dateString = [dateFormatter stringFromDate:date];
NSLog(#"dateString: %#", dateString); //logs valid output
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssz"];
dateFormatter.doesRelativeDateFormatting = NO;
date = [NSDate dateWithTimeIntervalSinceNow:60*60*24*3];
dateString = [dateFormatter stringFromDate:date];
NSLog(#"dateString: %#", dateString); //logs date correctly

NSDateFormatterLongStyle string to NSDate

I have a UIDataPicker in my viewController with default location, when my user finishes selecting the date I run this code:
NSString *dateString = [NSDateFormatter localizedStringFromDate:[self.dataPicker date]
dateStyle:NSDateFormatterLongStyle
timeStyle:NSDateFormatterNoStyle];
With that code I can storage the date in the following format:
May 31, 2016
Later in my code I need to convert this string into a real date format, for this I use the code below:
-(NSDate*)convertStringToDate:(NSString*)date{
NSString *dateString = date;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
return [dateFormatter dateFromString:dateString];
}
But this code return a null value. As the datepicker is set by default, my system can receive any date format, but in the end I want it to be converted to the format en_us.
How I can solve this problem?
Don't store the date as a string; store it as an offset, in seconds, from some reference date.
i.e:
uint64_t offset = (uint64_t)[[self.dataPicker date] timeIntervalSinceReferenceDate];
// store this 64-bit unsigned integer.
This takes less space and is quicker to convert to/from an NSDate object.
You can leave the offset as an NSTimeInterval (64-bit floating point double) if you prefer, but as you aren't storing date & time, uint64_t should do...
Use this code,
-(NSDate*)convertStringToDate:(NSString*)date{
NSString *dateString = date;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormatter setDateFormat:#"MMM d, yyyy"];
return [dateFormatter dateFromString:dateString];
}
hope its helpful
The formatting string depends on the locale you are using. From the localizedStringFromDate documentation:
Returns string representation of a given date formatted for the
current locale using the specified date and time styles.
This method uses a date formatter configured with the current default
settings. The returned string is the same as if you configured and
used a date formatter as shown in the following example:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.formatterBehavior = NSDateFormatterBehavior10_4;
formatter.dateStyle = dateStyle; formatter.timeStyle = timeStyle;
NSString *result = [formatter stringForObjectValue:date];
Means, you should do the next:
-(NSDate*)convertStringToDate:(NSString*)dateString {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.formatterBehavior = NSDateFormatterBehavior10_4;
dateFormatter.dateStyle = NSDateFormatterLongStyle;
dateFormatter.timeStyle = NSDateFormatterNoStyle;
return [dateFormatter dateFromString:dateString];
}

NSDateFormatter dateFromString format string issue

I encountered a small problem today: I receive a couple of dates (NSString) from a web server. To use those dates correctly they need to be parsed into NSDate objects, for which I'm using the following code:
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"dd.MM.yyy HH:mm:ss";
return [formatter dateFromString:dateString]
The dates I am receiving are in the following format e.g.: #"02.06.2015 13:31:24".
My problem is that the above code returns nil. I think the issue probably is that I don't have the correct format string, which I have not been able to get right..
Any help would be highly appreciated!
You are missing a 'y' in your format. It should be:
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"dd.MM.yyyy HH:mm:ss";
return [formatter dateFromString:dateString]
Please try below code -
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"dd.MM.yyyy HH:mm:ss";
return [formatter dateFromString:dateString]
-(NSDate *)getDateFromString:(NSString *)string
{
NSString * dateString = [NSString stringWithFormat: #"%#",string];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd.MM.yyyy HH:mm:ss"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
return myDate;
}
Call it wherever required :)
[self getDateFromString:#"13.07.2013 16:22:11"];

Unable to parse this dateString into an NSDate

I am trying to parse
2013-01-23T22:46:29.564Z
into an NSDate with:
NSDate *date = [GeneralHelper getDateFromDateString:expiryDateASStr];
if(date != nil) {
printf("\n PARSED DATE %s", [date.description UTF8String]);
} else {
printf("\n failed to parse");
}
but it is failing, how can I get this to work? Thanks!
Use a NSDateFormatter
NSString * dateString = #"2013-01-23T22:46:29.564Z";
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"];
NSDate * date = [dateFormatter dateFromString:dateString];
Like #Gabriele said, using a NSDateFormatter is the way to go. The following will work for you, including the date format:
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setLocale:[NSLocale currentLocale]];
[df setCalendar:[NSCalendar currentCalendar]];
[df setTimeZone:[NSTimeZone defaultTimeZone]];
[df setDateFormat:#"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"];
NSLog(#"%#", [df dateFromString:expiryDateASStr]);
Do NOT use the capital Ys "YYYY" unless you want the year in "Week of Year" based calendars. Most use cases "yyyy" is the correct way to specify the year.

iOS: How to get a proper Month name from a number?

I know that the NSDateformatter suite of functionality is a boon for mankind, but at the same time it is very confusing to me. I hope you can help me out.
Somewhere in my code, there is an int representing a month. So: 1 would be January, 2 February, etc.
In my user interface, I would like to display this integer as proper month name. Moreover, it should adhere to the locale of the device.
Thank you for your insights
In the mean time, I have done the following:
int monthNumber = 11
NSString * dateString = [NSString stringWithFormat: #"%d", monthNumber];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
[dateFormatter release];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMMM"];
NSString *stringFromDate = [formatter stringFromDate:myDate];
[formatter release];
is this the way to do it? It seems a bit wordy.
Another option is to use the monthSymbols method:
int monthNumber = 11; //November
NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
NSString *monthName = [[df monthSymbols] objectAtIndex:(monthNumber-1)];
Note that you'll need to subtract 1 from your 1..12 monthNumber since monthSymbols is zero-based.
let monthName = DateFormatter().monthSymbols[monthNumber - 1]
You can change the dateFormat of the NSDateFormatter. So to simplify your code:
int monthNumber = 11
NSString * dateString = [NSString stringWithFormat: #"%d", monthNumber];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
[formatter setDateFormat:#"MMMM"];
NSString *stringFromDate = [formatter stringFromDate:myDate];
[dateFormatter release];
You should also set the locale once you init the date formatter.
dateFormatter.locale = [NSLocale currentLocale]; // Or any other locale
Hope this helps
Best solution for this is , standaloneMonthSymbols method,
-(NSString*)MonthNameString:(int)monthNumber
{
NSDateFormatter *formate = [NSDateFormatter new];
NSArray *monthNames = [formate standaloneMonthSymbols];
NSString *monthName = [monthNames objectAtIndex:(monthNumber - 1)];
return monthName;
}
How about:
NSUInteger i = <your month integer>;
NSDateFormatter *df = [NSDateFormatter new];
// change locale if the standard is not what you want
NSArray *monthNames = [df standaloneMonthSymbols];
NSString *monthName = [monthNames objectAtIndex:(i - 1)];
[df release];
Both answers from Anna Karenina and Carl doesn't work that well as they won't return month name in nominativ for some cultures. I suggest to use the proposed solution from Pascal, which solves this issue (by replacing monthSymbols with standaloneMonthSymbols)
In Swift 3.0
let monthNumber = 3
let fmt = DateFormatter()
fmt.dateFormat = "MM"
let month = fmt.monthSymbols[monthNumber - 1]
print(month)
// result
"March\n"
Swift 4.X
print((DateFormatter().monthSymbols[month-1].capitalized)) //month is int less than 12
For Example:
print((DateFormatter().monthSymbols[11-1].capitalized))
Output
November
NSDate to NSString -> As Dateformat Ex: 2015/06/24
NSDateFormatter *dateformate=[[NSDateFormatter alloc]init];
[dateformate setDateFormat: #"yyyy/MM/dd"];
NSString *date = [dateformate stringFromDate:selectedDate]; // Convert date to string
NSDate to NSString -> As Dateformat Ex: 2015 June 24, 1:02 PM
[dateformate setDateFormat:#"yyyy MMMM dd, h:mm a"];
NSString *displayDate = [dateformate stringFromDate:selectedDate]; // Convert date to string
NSLog(#"date :%#",date);
NSLog(#"Display time = %#", displayDate);
And with ARC :
+ (NSString *)monthNameFromDate:(NSDate *)date {
if (!date) return #"n/a";
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MM"];
return [[df monthSymbols] objectAtIndex:([[df stringFromDate:date] integerValue] - 1)];
}
You should be able to get rid of the release and re-allocation of the dateFormatter, cutting out a couple of lines, but that's all I see.

Resources