How to parse these time zones with NSDateFormatter? - iphone

I'm parsing a large number of internet dates. First I try a formatter with en_US_POSIX locale, then with en_GB. The code looks more or less like this:
{
NSDate *date = [dateString dateWithDateFormat:#"EEE, dd MMM yyyy HH:mm:ss z (zzz)" localeIdentifier:#"en_US_POSIX"];
if (date) return date;
date = [dateString dateWithDateFormat:#"EEE, dd MMM yyyy HH:mm:ss z (zzz)" localeIdentifier:#"en_GB"];
return date;
}
- (NSDate*) dateWithDateFormat:(NSString*)dateFormat localeIdentifier:(NSString*)localeIdentifier
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier];
formatter.dateFormat = dateFormat;
[formatter dateFromString:self];
}
However, date strings with the following time zones fail to parse:
Mon, 16 Jul 2012 12:08:17 +0100 (GMTUK)
Thu, 6 Sep 2012 13:00:06 +0900 (KST)
Wed, 3 Nov 2010 10:12:15 +0100 (Hora est�ndar romance)
Wed, 14 Sep 2011 14:37:35 +0100 (IST)
Wed, 2 May 2012 09:41:06 +0200 (MEST)
Sun, 31 Oct 2010 12:53:06 +0800 (SGT)
Thu, 19 Jan 2012 08:34:44 -0300 (UYT)
What am I doing wrong?
Should I pre-process the strings to remove the time zone parenthesis in these cases only?

NSDate can store a point in time without timezone information. It's up to your software to know whether a specific NSDate instance stores the point in time in UTC or in the local time zone. In most cases, you want to use UTC dates.
Because of that, it's important to handle time zone differences when parsing the dates. But it's not possible to remember the time zone the dates was originally in (at least not with an NSDate instance only).
So I would recommend that you cut off the time zone in parenthesis and just parse the numerical time zone offset before it. That way, you can convert all strings into an NSDate instance in UTC and you shouldn't have any problems parsing the strings.
And shouldn't the date fromat be (i.e. uppercase Z for a numeric time zone offset)?
#"EEE, dd MMM yyyy HH:mm:ss ZZZ"

Related

How to convert milliseconds to local day, date and time format in swift?

I want to display the date in this format (Wed Jan 10 2018 11:20:17). How to convert milliseconds to this format in swift?I want to get the day as Wed, time as 10:30 AM or PM and the date as 10 Jan.
First convert it in date by dividing it by 1000
var date = Date(timeIntervalSince1970: (1477593000000 / 1000.0))
then use DateFormatter to convert in desired format you need
Note: Not tested in XCODE
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "E, d MMM yyyy HH:mm:ss"
print(dateFormatter.string(from: date))
Hope it is helpful to you.

Format Date String in momentjs

I am trying to format a timezone based
How can i convert a JS time into these formats?
"Thu Sep 24 2015 14:00:00 GMT-0700 (PDT)"
"September 24th 2015, 2:00:00 pm UTC-07:00"
"2015-09-24 14:00:00 GMT-0700"
"Sept 24 2015 14:00:00 GMT-0700"
"Thu Sep 24 2015 14:00:00 GMT-0700 (Pacific Daylight Time)"
Converting into any of it would help.
You can use tokens listed in the format documentation, as shown in the following snippet.
Use square brackets [] to add characters that should be escaped (GMT and UTC in the example, if you need current zone abbreviation use the z token).
Note that as the moment-timezone docs says:
Moment.js also provides a hook for the long form time zone name. Because these strings are generally localized, Moment Timezone does not provide any long names for zones.
To provide long form names, you can override moment.fn.zoneName and use the zz token.
You can find in the snippet an example of providing long names for zones.
var time = "2016-11-09 15:38:00", zone = "America/Chicago";
var m = moment.tz(time,zone);
console.log(m.format('ddd MMM D YYYY HH:mm:ss [GMT]ZZ (z)'));
console.log(m.format('MMMM Do YYYY, h:mm:ss a [UTC]ZZ'));
console.log(m.format('YYYY-MM-DD HH:mm:ss [GMT]ZZ'));
console.log(m.format('MMM D YYYY HH:mm:ss [GMT]ZZ'));
// Add long names for sample zones
var abbrs = {
EST : 'Eastern Standard Time',
EDT : 'Eastern Daylight Time',
CST : 'Central Standard Time',
CDT : 'Central Daylight Time',
MST : 'Mountain Standard Time',
MDT : 'Mountain Daylight Time',
PST : 'Pacific Standard Time',
PDT : 'Pacific Daylight Time',
};
moment.fn.zoneName = function () {
var abbr = this.zoneAbbr();
return abbrs[abbr] || abbr;
};
console.log(m.format('ddd MMM D YYYY HH:mm:ss [GMT]ZZ (zz)'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.7/moment-timezone-with-data-2010-2020.min.js"></script>
I was able to make third one using this snippet
var time = "2016-11-09 15:38:00",
zone = "America/Chicago",
format = "YYYY-MM-DD HH:mm:ss zZZ";
moment.tz(time,zone).utc().format(format)

NSDateFormatter different base year iOS 5 and iOS 6 parsing the day of the year

I'm working with calendars and found a problem with NSDateFormatter that behaves different on iOS 5.0 and iOS 6.0.
I try to create dates for certain days of the year.
So for example I would like to know which is the 59'th day of the year.
To achieve this I use a NSDateFormatter and set it's date format to "DDD" (three digits day of the year) and simply try to parse the string containing the day.
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// just gettting rid of the timezone
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setDateFormat:#"DDD"];
NSMutableString *outPutString = [NSMutableString stringWithString:#"\n"];
for (int i = 1; i <= 366; i++)
{
NSString *dayOfTheYearString = [NSString stringWithFormat:#"%i", i];
[outPutString appendFormat:#"%3i: %# string:(%#)\n", i, [formatter dateFromString:dayOfTheYearString], dayOfTheYearString];
}
NSLog(#"%#", outPutString);
[formatter release];
Running this on iOS 5.0 Simulator works fine. the console prints:
001: 1970-01-01 00:00:00 +0000 string:(1)
002: 1970-01-02 00:00:00 +0000 string:(2)
003: 1970-01-03 00:00:00 +0000 string:(3)
004: 1970-01-04 00:00:00 +0000 string:(4)
005: 1970-01-05 00:00:00 +0000 string:(5)
[...]
058: 1970-02-27 00:00:00 +0000 string:(58)
059: 1970-02-28 00:00:00 +0000 string:(59)
060: 1970-03-01 00:00:00 +0000 string:(60)
061: 1970-03-02 00:00:00 +0000 string:(61)
[...]
But on iOS 6.0 the console prints:
001: 2000-01-01 00:00:00 +0000 string:(1)
002: 2000-01-02 00:00:00 +0000 string:(2)
003: 2000-01-03 00:00:00 +0000 string:(3)
004: 2000-01-04 00:00:00 +0000 string:(4)
005: 2000-01-05 00:00:00 +0000 string:(5)
[...]
058: 2000-02-27 00:00:00 +0000 string:(58)
059: 2000-02-28 00:00:00 +0000 string:(59)
060: 2000-02-29 00:00:00 +0000 string:(60)
061: 2000-03-01 00:00:00 +0000 string:(61)
[...]
And this is my main problem. Since year 2000 is a leap year the results of my following calculations differ between iOS 5.0 and iOS 6.0.
I know that it is necessary to be aware of the year being a leap year or not when asking for the x'th day. But if I don't deliver any information about the year I expect the resulting date being in 1970!
So how to force the NSDateFormatter to create (worldwide standard used) dates in year 1970 when not else mentioned in iOS 6.0?
You can specify the base year when you pass in the date. Instead of using
[formatter setDateFormat:#"DDD"];
use
[formatter setDateFormat:#"yyyy-DDD"];
Then, change your day of year string to
NSString *dayOfTheYearString = [NSString stringWithFormat:#"1970-%i", i];

Creating a format string for NSDateFormatter

I have a date in the format Tue, 29 May 2012 00:56:14 +0000 from an XML file, which is not under my control so the original format cannot be changed.
I was researching for how to create format strings for NSDateFormatter, found this page, and came up with the following code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEE', 'dd' 'MMM' 'YYYY' 'HH':'mm':'ss' 'Z"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *parsedDate = [dateFormatter dateFromString:date];
However, after parsing the date above, Tue, 29 May 2012 00:56:14 +0000, with this format string I get 2011-12-27 00:56:14 +0000. So the time is correct, but the date is all jumbled.
Could someone with some more knowledge of NSDateFormatter please explain why this isn't working? To my knowledge the format string seems correct, but apparently it is not. Thanks!!
Your year format string should be lower case, 'yyyy'

Date Formatting in Objective C (iOS SDK)

Hope you can help. I am importing the current GMT time for an iPhone App. This is being retrieved via a JSON web service.
I believe I have the correct formatter string however I am getting a different date (time is still correct) when I try to format the date I've retrieved. The JSON date is formatted like this: Sun, 15 May 2011 20:35:31 +0000
In the example below strGMT is the date in the format I've just mentioned.
This is the code I'm using to get retrieved date into my code:
NSLog(#"Current GMT: %#", strGMT);
NSDateFormatter *gmtFormatter=[[NSDateFormatter alloc] init];
[gmtFormatter setDateFormat:#"EEE, dd MMM YYYY HH:mm:ss VVVV"];
//THIS IS NOT REFORMATTING CORRECTLY HERE
NSDate *gmtDateTime=[gmtFormatter dateFromString:strGMT];
NSLog(#"Current Formatted GMT Date: %#", gmtDateTime);
The log is showing the following:
Current GMT: Sun, 15 May 2011 20:35:31 +0000
Current Formatted GMT Date: 2010-12-26 20:35:31 +0000
Have I not got the formatting string correct? Any ideas why it's gone from 15 May 2011 (today) to 26th December 2010?
Kind regards
Paul
The correct format string is #"EEE, dd MMMM yyyy HH:mm:ss VVVV"