NSString to NSDate = nil (with timezone) - in-app-purchase

Trying to convert "expires_date" string value into NSDate object.
date string = "2019-08-18 15:12:09 America/Los_Angeles"
Any suggestions?
-(NSDate*)expires_date{
NSMutableDictionary * dictionary = [_dictionary mutableCopy];
NSString * date_string = [dictionary valueForKey:#"expires_date"];
//date_string = "2019-08-18 15:12:09 America/Los_Angeles"
NSDateFormatter *dateFormatter = [IAPSKReceipt formatter];
NSDate *date = [dateFormatter dateFromString:date_string];
return date;
}
+(NSDateFormatter*)formatter{
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter = [NSLocale localeWithLocaleIdentifier:#"en_US"];
dateFormatter = #"yyyy-MM-dd HH:mm:ss";
dateFormatter = [NSTimeZone timeZoneForSecondsFromGMT:0];
return dateFormatter;
}

you might want to look into ISO8601DateFormatter which is tailored for what you’re trying to do:
https://developer.apple.com/documentation/foundation/iso8601dateformatter

In addition to #Shai Mishali's answer:
Considering the timezone, your date does not seem to be RFC3339 nor ISO8601 compliant.
ISO8601 allows substituting the 'T' in the middle for a ' ' so you will not get a nil response. However since the timezone is not according to spec, it will not be parsed and the expected response will not be in the desired LA timezone (PST, GMT-8).
Here is your date in legal ISO8601/RFC3339:
"2019-08-18T15:12:09-0800"

Related

how to convert this date format to our regular date in objective-c

I have a date in the following format
11/03/2562 BE, 21:45:57
14/03/2562 BE, 10:42:05
14/03/2562 BE, 21:12:14
I want to convert those dates in current regular date format.
What should be the value of NSDateFormatter in objective-c for above date string?
You have to create two formatters - one for converting buddhist date string to NSDate and one for converting NSDate to gregorian date string
' - used to escape symbols within date format string
NSString *buddhistString = #"11/03/2562 BE, 21:45:57";
NSDateFormatter *buddhistFormatter = [[NSDateFormatter alloc] init];
buddhistFormatter.dateFormat = #"dd/MM/yyyy GG, HH:mm:ss";
buddhistFormatter.calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierBuddhist];
NSDateFormatter *gregorianFormatter = [[NSDateFormatter alloc] init];
gregorianFormatter.dateFormat = #"dd/MM/yyyy, HH:mm:ss"; // Or other format you'd like
gregorianFormatter.calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
NSDate *date = [buddhistFormatter dateFromString:buddhistString];
NSString *gregorianString = [gregorianFormatter stringFromDate:date];
NSLog(#"%#", gregorianString);
// prints 11/03/2019, 21:45:57

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];
}

Objective c : Get ISO Formated Date from String '2015-11-25T00:00:00.000Z'

In our app we are getting Date string "2015-11-25T00:00:00.000Z" from server.
Now we have to convert this string into into NSDate.
I've used the following code for conversion. Which is having an ISO Date Format.
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *outputDate = [dateFormatter dateFromString:#"2015-11-25T00:00:00.000Z"];
But it returns null.
Can anyone please suggest where did I make the mistake...
Your code is correct.
It returns:
(lldb) po outputDate
2015-11-25 00:00:00 +0000
Try next code:
NSDateFormatter *dateFormatter = [NSDateFormatter new];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
dateFormatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSZ";
NSDate *outputDate = [dateFormatter dateFromString:#"2015-11-25T00:00:00.000Z"];

Can't parse date from string

I can't parse date from string via NSDateFormatter. The date string is #"2014-01-21T20:00:36+04:00". I am trying to use this format string: #"yyyy-MM-ddTHH:mm:ss" but it doesn't work. Please help me.
The full code is:
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-ddTHH:mm:ssZ";
NSDate * date = [dateFormatter dateFromString:dateString];
add Z at the end #"yyyy-MM-dd'T'HH:mm:ssZZZZZ" as you have timezone included
Following on from http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
NSString *dateString = #"2014-01-21T20:00:36+04:00";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
dateFormat.dateFormat = #"yyyy-MM-dd'T'HH:mm:ssZZZZZ";
NSDate *date = [dateFormat dateFromString:dateString];
NSLog(#"Parsed date is %#", date);
yields the following output which seems correct
Parsed date is 2014-01-21 16:00:36 +0000

How to parse ISO 8601 using NSDateFormatter with optional milliseconds part

I'm trying to use an NSDateFormatter to parse dates that are in either of these formats
#"2013-02-01T14:21:00"
or
#"2013-02-01T14:21:56.345"
Currently I am using the below method to parse the string and return a date:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss"];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"]];
NSDate *date = [dateFormatter dateFromString:dateToFormat];
This works fine for the first style of date but returns nil for a string that includes the milliseconds part.
I suppose I could test for the existence of the milliseconds and strip them but I was wondering if I could change the date format to treat the .SSS as optional?
Thanks for your help
As far as I know there is no way to make optional parameters.
The usual solution is to use two formatters, one for each format.
To decide which formatter to use, you can either
Count the number of characters in the date string (as suggested in Parsing a RFC 822 date with NSDateFormatter)
Just try both formatters and get the first non-nil result.
Since your date formats are similar, you can go with only one formatter and if the date string is too short, append .000 before using the formatter.
The correct approach since iOS 10 is to use ISO8601DateFormatter specifically created to handle all variations of ISO 8601 date strings. Please see the example below:
let date = Date()
var string: String
let formatter = ISO8601DateFormatter()
string = formatter.string(from: date)
let GMT = TimeZone(abbreviation: "GMT")
let options: ISO8601DateFormatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withTimeZone]
string = ISO8601DateFormatter.string(from: date, timeZone: GMT, formatOptions: options)
And Objective-C version:
NSDate *date = [NSDate date];
NSString *string;
NSISO8601DateFormatter *formatter = [[NSISO8601DateFormatter alloc] init];
string = [formatter stringFromDate:date];
NSTimeZone *GMT = [NSTimeZone timeZoneWithAbbreviation: #"GMT"];
NSISO8601DateFormatOptions options = NSISO8601DateFormatWithInternetDateTime | NSISO8601DateFormatWithDashSeparatorInDate | NSISO8601DateFormatWithColonSeparatorInTime | NSISO8601DateFormatWithTimeZone;
string = [NSISO8601DateFormatter stringFromDate:date timeZone:GMT formatOptions:options];
I wrote an universal parser which dropped milliseconds part.
#implementation JSONModel(NSPAdditions)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSArray* parts = [string componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#" T"]];
if ([parts count] <= 1) {
return [formatter dateFromString:string];
}
NSString *part0 = parts[0];
NSAssert([part0 length] == [#"yyyy-MM-dd" length], #"Date format error");
NSString *part1 = parts[1];
if ([part1 length] > [#"HH:mm:ss" length]) {
part1 = [part1 substringToIndex:[#"HH:mm:ss" length]];
}
NSString *fmted = [NSString stringWithFormat:#"%# %#", part0, part1];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
return [formatter dateFromString:fmted];
}
#end

Resources