I'm converting a string "Jun 11, 2012 9:30 PM" to an NSDate and I keep getting 4 hours ahead for some reason. The funny thing is I'm using this same string to feed a UIDatePicker in a detailed view where I have to do the same conversion, and the UIDatePicker renders the time fine. Only when I now try to NSLog it in my main and detailed view do I have problems.
This is in my views :
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMMM dd, yyyy h:mma"];
NSDate *dateFromString = [[[NSDate alloc] init]autorelease];
NSLog(#"DATE %#", _date);
dateFromString = [formatter dateFromString:_date];
NSLog(#"NSDATEFROMSTRING %#", dateFromString);
NSLog returns :
2012-06-11 00:02:09.136 LocalDeals[78090:207] DATE Jun 11, 2012 9:30 PM
2012-06-11 00:02:09.137 LocalDeals[78090:207] NSDATEFROMSTRING 2012-06-12 01:30:00 +0000
Even when I add:
[formatter setTimeZone:[NSTimeZone defaultTimeZone]];
I still get the same results from any time I choose. Any ideas? This is on the simulator by the way and yes my Region Format is set to United States.
When you NSLog an NSDate it will print the time as a GMT time zone
In order to see the correct data you will have to convert the NSDate to string using stringFromDate
NSDate *dateFromString = [[[NSDate alloc] init]autorelease];
NSLog(#"DATE %#", _date);
//Instead of nslog directly, use this stringFromDate:remindOn
NSString *str = [formatter stringFromDate:dateFromString];
NSLog(#"date is %#", str); //This will log the correct data
The problem you are getting is not in the NSDate but it is in Logging it
UPDATE In order to save the data to a file or database i would suggest that you save it like this
NSTimeInterval timeInterval = [dateFromString timeIntervalSince1970];
Now when you read it again from the database you would do
NSDate *data = [[NSDate alloc] initWithTimeIntervalSince1970:timeInterval]
The following code will show your time with your time zone:
NSString *_date = #"Jun 11, 2012 9:30 PM";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMMM dd, yyyy h:mma"];
[formatter2 setDateFormat:#"MMMM dd, yyyy h:mma Z"];
NSDate *dateFromString = [[NSDate alloc] init];
NSLog(#"DATE %#", _date);
dateFromString = [formatter dateFromString:_date];
NSLog(#"NSDATEFROMSTRING %#", dateFromString);
NSLog(#"NSDATEFROMSTRING %#", [formatter stringFromDate:dateFromString]);
NSLog(#"NSDATEFROMSTRING %#", [formatter2 stringFromDate:dateFromString]);
Result:
DATE Jun 11, 2012 9:30 PM
NSDATEFROMSTRING 2012-06-12 04:30:00 +0000
NSDATEFROMSTRING June 11, 2012 9:30PM
NSDATEFROMSTRING June 11, 2012 9:30PM -0700
If you Google for UTC Time now, it does give you a time that is close to the second line in the output, which confirms it is printing out the time as a UTC time.
(We are in different time zone and dateFromString is interpreting the time in the string as your local time.)
Related
When I was trying to convert April from 04 (MM) to Apr (MMM) it turned back into nil, is this a known issue in iOS or am I doing something wrong?
Here's my code for inspection:
NSString *dateString=#"2016-04-01";
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM"];
NSString *stringFromDate = [formatter stringFromDate:myDate];
NSLog(#"%# == %#",dateString,stringFromDate);
when change dataString=#"2015-04-01" the stringFromDate returns Apr
This is my output:
this is the log image
2016-04-01 12:17:45.708[32172:2389414] 2016-04-01 == (null)
2016-04-01 12:17:47.446[32172:2389414] 2015-04-01 == Apr
This is probably a problem in your time zone. Note that when parsing a date without time, the time is assumed to be zero. However, some specific times don't exist, usually due to Daylight Saving Time changes (which happen in March around the world) or due to specific local time changes.
For example, in Jordan, the DST change is Apr 1 2016, 00:00 => Apr 1 2016, 01:00. That means that the time Apr 1 2016, 00:00 does not exist because March 31 2016, 23:59 becomes immediately Apr 1 2016, 01:00. If the date does not exist, date formatter must return nil.
You can usually fix the problem by using a preset GMT time zone that does not have this problem, e.g
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
or
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:[NSTimeZone systemTimeZone].secondsFromGMT];
Note that since you are not parsing time, time zone differences shouldn't affect you.
Steps to reproduce
Set the time zone on your machine to Jordan time zone:
NSString *dateString = #"2016-04-01";
NSDateFormatter* parsingFormatter = [[NSDateFormatter alloc] init];
parsingFormatter.dateFormat = #"yyyy-MM-dd";
NSLog(#"Parsed: %#", [parsingFormatter dateFromString:dateString]); // "(null)"
with time zone fix:
NSString *dateString = #"2016-04-01";
NSDateFormatter* parsingFormatter = [[NSDateFormatter alloc] init];
parsingFormatter.dateFormat = #"yyyy-MM-dd";
parsingFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSLog(#"Parsed: %#", [parsingFormatter dateFromString:dateString]); // "2016-04-01 00:00:00 +0000"
I tried your code and it gives me null for year 2022, but years 2018,2020 it gives Apr ... weird!
NSString *dateString=#"2022-04-01";
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"+5:30"]];
[dateFormatter setDateFormat:#"MMM"];
NSString *stringFromDate = [dateFormatter stringFromDate:myDate];
NSLog(#"%# == %#",dateString,stringFromDate);
UPDATE:
Please parse the string as this :
2016-04-01 01:00
Because of daylight saving in Jordan the clock will be shifted +1 hour so there's no time in the universe like this:
2016-04-01 00:00
This should resolve ur issues with the nil object.
When I was trying to convert April from 04 (MM) to Apr (MMM) it turned back into nil, is this a known issue in iOS or am I doing something wrong?
Here's my code for inspection:
NSString *dateString=#"2016-04-01";
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM"];
NSString *stringFromDate = [formatter stringFromDate:myDate];
NSLog(#"%# == %#",dateString,stringFromDate);
when change dataString=#"2015-04-01" the stringFromDate returns Apr
This is my output:
this is the log image
2016-04-01 12:17:45.708[32172:2389414] 2016-04-01 == (null)
2016-04-01 12:17:47.446[32172:2389414] 2015-04-01 == Apr
This is probably a problem in your time zone. Note that when parsing a date without time, the time is assumed to be zero. However, some specific times don't exist, usually due to Daylight Saving Time changes (which happen in March around the world) or due to specific local time changes.
For example, in Jordan, the DST change is Apr 1 2016, 00:00 => Apr 1 2016, 01:00. That means that the time Apr 1 2016, 00:00 does not exist because March 31 2016, 23:59 becomes immediately Apr 1 2016, 01:00. If the date does not exist, date formatter must return nil.
You can usually fix the problem by using a preset GMT time zone that does not have this problem, e.g
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
or
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:[NSTimeZone systemTimeZone].secondsFromGMT];
Note that since you are not parsing time, time zone differences shouldn't affect you.
Steps to reproduce
Set the time zone on your machine to Jordan time zone:
NSString *dateString = #"2016-04-01";
NSDateFormatter* parsingFormatter = [[NSDateFormatter alloc] init];
parsingFormatter.dateFormat = #"yyyy-MM-dd";
NSLog(#"Parsed: %#", [parsingFormatter dateFromString:dateString]); // "(null)"
with time zone fix:
NSString *dateString = #"2016-04-01";
NSDateFormatter* parsingFormatter = [[NSDateFormatter alloc] init];
parsingFormatter.dateFormat = #"yyyy-MM-dd";
parsingFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSLog(#"Parsed: %#", [parsingFormatter dateFromString:dateString]); // "2016-04-01 00:00:00 +0000"
I tried your code and it gives me null for year 2022, but years 2018,2020 it gives Apr ... weird!
NSString *dateString=#"2022-04-01";
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"+5:30"]];
[dateFormatter setDateFormat:#"MMM"];
NSString *stringFromDate = [dateFormatter stringFromDate:myDate];
NSLog(#"%# == %#",dateString,stringFromDate);
UPDATE:
Please parse the string as this :
2016-04-01 01:00
Because of daylight saving in Jordan the clock will be shifted +1 hour so there's no time in the universe like this:
2016-04-01 00:00
This should resolve ur issues with the nil object.
I have a NSDate that I want to display in 4:00 PM form.
NSDate *time = [object objectForKey:#"time"];
NSLog(#"time: %#", time);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [NSLocale currentLocale];
[dateFormatter setDateFormat:#"h:mm a"];
timeLabel.text = [dateFormatter stringFromDate:time];
The log returns:
2014-03-08 13:00:00 +0000
But timeLabel.text reads 1:00 AM, when it should be pm. Any idea what's going on?
You forgot to add the timezone. The rest is fine. You have to give the formatter a timezone or it will use your local one
also be aware that logging with NSLog ALWAYS prints UTC dates
use [formatter setTimezone:timeZoneXY]
you can use following code:
NSString *str=#"17-02-2014 05:00 PM";
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"dd-MM-yyyy hh:mm a"];
NSDate *datetoday=[dateFormatter dateFromString:str];
[dateFormatter setDateFormat:#"yyyy-MM-dd hh:mm:ss Z"];
NSString *strdate=[dateFormatter stringFromDate:datetoday];
NSLog(#"%#",strdate);
NSDate *time = [object objectForKey:#"time"];
NSLog(#"time: %#", time);
Your time variable time format is have 24 hour format. that way it display NSLog 13.00.
After that you have use to converter 12 hour format thats way it display am/pm style
[dateFormatter setDateFormat:#"h:mm a"];
Note:
HH - captial letter H is denote 24 hour format
hh - small letter h is denote 12 hour format
I have a problem related to date formatter, it is returning null for the date "2012-10-21".
I created a sample project only with the code that I want to test, just to be sure that other things are not interfering in the results.
In iOS 5 it is executing as expected, but in iOS 6 the date formatter is returning null.
This is my code:
NSString *myStringDate = #"2012-10-21";
//------------------------//
NSLog(#"Test 1");
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd"];
NSDate *myDate = [formatter dateFromString:myStringDate];
NSLog(#"Date: %#", myDate);
//------------------------//
NSLog(#"Test 2");
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init];
[formatter2 setDateFormat:#"yyyy-MM-dd"];
[formatter2 setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *myDate2 = [formatter2 dateFromString:myStringDate];
NSLog(#"TimeZone: %#", [NSTimeZone systemTimeZone]);
NSLog(#"Date: %#", myDate2);
//------------------------//
NSLog(#"Test 3");
NSDateFormatter *formatter3 = [[NSDateFormatter alloc] init];
[formatter3 setDateFormat:#"yyyy-MM-dd"];
[formatter3 setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:-7200]];
NSDate *myDate3 = [formatter3 dateFromString:myStringDate];
NSLog(#"TimeZone: %#", [NSTimeZone timeZoneForSecondsFromGMT:-7200]);
NSLog(#"Date: %#", myDate3);
//------------------------//
iOS 5.1 simulator results:
Test 1
Date: 2012-10-21 03:00:00 +0000
Test 2
TimeZone: America/Sao_Paulo (BRST) offset -7200 (Daylight)
Date: 2012-10-21 03:00:00 +0000
Test 3
TimeZone: GMT-0200 (GMT-02:00) offset -7200
Date: 2012-10-21 02:00:00 +0000
iOS 6.0 simulator results:
Test 1
Date: (null)
Test 2
TimeZone: America/Sao_Paulo (GMT-03:00) offset -7200 (Daylight)
Date: (null)
Test 3
TimeZone: GMT-0200 (GMT-02:00) offset -7200
Date: 2012-10-21 02:00:00 +0000
NSDateFormatter returns null in iOS 6 only when the date is "2012-10-21". For all others dates of 2012 year, the result its correct on both iOS versions.
Anyone can explain why? Its a bug? My code is wrong?
Looks like Sau Paulo had a Daylight Saving change on the 20th/21st of October going forward an hour (http://www.timeanddate.com/worldclock/clockchange.html?n=233). This doesn't seem like a coincidence. It's possible that the time calculated for Tests 1 and 2 fell between 12am-1am on the 21st October, which isn't possible. iOS 6 may be a bit more strict in this regard.
As far as I can tell, your code looks fine, it may be a bug within iOS (or it could be intended behavior, and iOS 5 was the issue, I can't tell!). The fact that other dates seemed to work suggests an OS issue, the documentation doesn't explain whether this should happen.
This is the code I am using to decrement the date:
(IBAction)showPrevDate:(id)sender
{
NSString *dateForDecrement = _showDateLbl.text;
[dateFormatter setDateFormat:#"MMM d, yyyy (EEE)"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *dateObjectForDecrement = [dateFormatter dateFromString:dateForDecrement];
int subtractDays = 1;
NSDate *dateAfterDecrement=[dateObjectForDecrement dateByAddingTimeInterval:-(24*60*60 * subtractDays)];
[dateFormatter setDateFormat:#"MMM d, yyyy (EEE)"];
_showDateLbl.text = [NSString stringWithFormat:#"%#", [dateFormatter stringFromDate:dateAfterDecrement]];
}
Doesn't work with iOS6 but works with iOS5. Can you verify?
I'm getting some strange output from a NSDateFormatter. I'm converting a date from GMT to the system time zone, which is EDT. This should be -4 hours from GMT.
-(NSDate*)parseDate:(NSString*)inStrDate {
NSLog(#"Date To Parse %#", inStrDate);
NSDateFormatter* dtFormatter = [[NSDateFormatter alloc] init];
[dtFormatter setLocale:[NSLocale systemLocale]];
[dtFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[dtFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss +0000"];
NSDate* dateOutput = [dtFormatter dateFromString:inStrDate];
NSLog(#"Parsed Date %# %#", dateOutput, [NSTimeZone systemTimeZone]);
return dateOutput;
}
Log output:
2012-09-15 22:32:53.358 Date To Parse 2012-09-16 02:32:53 +0000
2012-09-15 22:32:53.360 Parsed Date 2012-09-16 06:32:53 +0000 America/New_York (EDT) offset -14400 (Daylight)
But it's returning +4 hours instead of -4. So where it should output 22.30 EDT (02.30 GMT) it's actually returning 06.30 EDT. Which is 8 hours in the future.
Can anyone help me understand if I'm going wrong somewhere here? I'm scratching my head but I can't figure out why this wont seem to work.
Thanks
You just got the dateFormatter the wrong way around.
When you do
[dtFormatter setTimeZone:[NSTimeZone systemTimeZone]];
you're telling it that the input Date is in terms of your time zone. Therefore, it converts it to GMT and outputs the time +4 hours. To do it the other way around you can use this:
NSDateFormatter* df_local = [[NSDateFormatter alloc] init];
[df_local setTimeZone:[NSTimeZone timeZoneWithName:#"America/New_York"]];
[df_local setDateFormat:#"yyyy.MM.dd' 'HH:mm:ss zzz"];
NSDate* dateOutput = [dtFormatter dateFromString:dateString];
NSLog(#"Parsed Date in GMT %#", dateOutput);
NSString *yourLocalDate = [df_local stringFromDate:dateOutput];
NSLog(#"in EDT %#",yourLocalDate);
This logs
2012-09-16 05:23:53.297 TestingApplication[10109:c07] Date To Parse 2012-09-16 02:32:53 +0000
2012-09-16 05:23:53.302 TestingApplication[10109:c07] Parsed Date in GMT 2012-09-16 02:32:53 +0000
2012-09-16 05:23:53.304 TestingApplication[10109:c07] in EDT 2012.09.15 22:32:53 EDT
if you want a date as a final output you can skip the secondary NSDateFormatter and just 'add' the difference between the UTC date and the local time.
formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[formatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *date = [formatter dateFromString:dateString]; // UTC date
NSDate *date2 = [date dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMTForDate:date]]; // local date!