NSDateFormatter wrong string after formatting - ios

I receive a date through a string parameter, which is tempDateString, in a [day month year] format (for ex. 01 05 2005):
NSLog(#"tempdatestring %#", tempDateString);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MM YYYY"];
NSDate *dayDate = [dateFormatter dateFromString:tempDateString];
NSLog(#"daydate %#", dayDate);
My problem is, that the two logs don't match. The outputs are:
tempdatestring 04 10 2012
daydate 2011-12-24 22:00:00 +0000
What should I change at the date formatter's date format, to get the good date?

2 Problems
your format is wrong it is #"dd MM yyyy" case sensitive
Use timezone to get the correct value[GMT value]
NSString *tempDateString=#"04 10 2012" ;
NSLog(#"tempdatestring %#", tempDateString);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateFormatter setDateFormat:#"dd MM yyyy"];
NSDate *dayDate = [dateFormatter dateFromString:tempDateString];
NSLog(#"daydate %#", dayDate);

Do this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MM yyyy"];
NSDate *dayDate = [dateFormatter dateFromString:tempDateString];
NSLog(#"daydate %#", dayDate);
NSString *strDate = [dateFormatter stringFromDate:dayDate];
NSLog(#"strDate :%#",strDate);

When you use the %# format specifier, the return value of the -description method invoked on the provided object is used.
NSDate's -description method outputs its value in that specific way.
Your real problem though is that your date format string is incorrect - it should be dd MM yyyy.
I stuck this in a sample Xcode project:
NSString *s = #"04 11 2012";
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"dd MM yyyy"];
NSDate *d = [df dateFromString:s];
NSDateComponents *c = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:d];
NSLog(#"%#", c);
It gave me the following output:
2012-10-04 01:53:24.320 dftest[59564:303] <NSDateComponents: 0x100113e70>
Calendar Year: 2012
Month: 11
Leap month: no
Day: 4

NSDateFormatter *form = [[NSDateFormatter alloc] init];
[form setDateFormat:#"dd MM yyyy"];
form.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:-7200.0];
NSDate *dayDate = [form dateFromString:#"05 10 2012"];
NSLog(#"daydate %#", dayDate);
NSString *strDate = [form stringFromDate:dayDate];
NSLog(#"strDate %#",strDate);
Change date format to #"dd MM yyyy". After this, dateFromString may still parse the wrong date (in my case it was yesterday 21-00). To avoid this I've set TimeZone in my DateFormatter:
form.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:-7200.0];
-7200.0 is my timezone, you should change this to yours ("0" sets to Greenwich). After this log looks like:
daydate 2012-10-05 02:00:00 +0000
strDate 05 10 2012

Related

Convert utc date into 12 hours local date?

My date and time is 20-Nov-2019 21:09 Which is in UTC 24 hours format. now I want to convert it into local time in 12 hours formate. 30-Nov-2019 08:00 AM like this.
My code is :
// create dateFormatter with UTC time format
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MMM-yyyy HH:mm"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
// change to a readable time format and change to local time zone
[dateFormatter setDateFormat:#"dd-MMM-yyyy HH:mm a"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSString *timestamp = [dateFormatter stringFromDate:date];
My code when i send my local time 12 formate into 24 hours UTC
-(NSString *)getUTCFormateDate:(NSDate *)localDate
{
// NSLog(#"%#", localDate);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:#"dd-MMM-yyyy HH:mm"];
NSLocale *twelveHourLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
dateFormatter.locale = twelveHourLocale;
NSTimeInterval timeZoneoffset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
NSTimeInterval utcTimeInterval = [localDate timeIntervalSinceReferenceDate] - timeZoneoffset;
NSDate *utcCurrentDate = [NSDate dateWithTimeIntervalSinceReferenceDate:utcTimeInterval];
NSString *dateString = [dateFormatter stringFromDate:utcCurrentDate];
// NSLog(#"dateString %#", dateString);
return dateString;
}
-(NSDate *)getUTCDate:(NSString *)currentDate{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd-MMM-yyyy HH:mm"];
NSDate *date1 = [dateFormat dateFromString:currentDate];
if (date1 == nil){
[dateFormat setDateFormat:#"dd-MMM-yyyy hh:mm a"];
date1 = [dateFormat dateFromString:currentDate];
}
return date1;
}
I think you are doing too much. The format "hh" is the hour in 12-hour format, HH is 24-hour format. You should not have to set the locale for that (though setting to en_US_POSIX does avoid the user's 24-hour preference in the [NSLocale currentLocale] instance which can override that on iOS).
NSDate is an absolute instance in time. You need to apply a calendar and time zone with an NSDateFormatter to get numeric year/month/day etc. values out of it, but you don't need to adjust the offset to the reference date (that is changing the actual date, not just reformatting it in a different time zone).
NSString *utcString = #"20-Nov-2019 21:09";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
formatter.dateFormat = #"dd-MMM-yyyy HH:mm";
NSDate *date = [formatter dateFromString:utcString];
formatter.timeZone = [NSTimeZone localTimeZone]; // GMT-5 for me
formatter.dateFormat = #"dd-MMM-yyyy hh:mm a";
NSLog(#"date: %#", [formatter stringFromDate:date]);
// date: 20-Nov-2019 04:09 PM

Date Formatter not working?

I want to change my date format from "MM/dd/YYYY HH:mm:ss" to "EEE dd MMM yyyy hh:mm a", but the code I am using not working for example if my input is 11/30/2016T01:04:30 I am getting the month changed as December, can any one help where is the mistake?
NSString * date = #"11/30/2016T01:04:30";
date = [date stringByReplacingOccurrencesOfString:#"T" withString:#" "];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MM/dd/YYYY HH:mm:ss"];
NSDate *myDate = [df dateFromString: date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEE dd MMM yyyy hh:mm a"];
NSString *dayName= [dateFormatter stringFromDate:myDate];
NSLog(#"the converted Day %#",dayName);
no need of this
// date = [date stringByReplacingOccurrencesOfString:#"T" withString:#" "];
use like
NSDateFormatter *df = [[NSDateFormatter alloc] init];
NSString * date = #"11/30/2016T01:04:30";
[df setDateFormat:#"MM/dd/yyyy'T'HH:mm:ss"];
NSDate *myDate = [df dateFromString: date];
[df setDateFormat:#"EEE dd MMM yyyy hh:mm a"];
NSString *dayName= [df stringFromDate:myDate];
NSLog(#"the converted Day %#",dayName);
Output:
the converted Day Wed 30 Nov 2016 01:04 AM

IOS ObjectiveC: How to change from String to Date, if we have TImeZone: Date is coming nil

Actually, I would like to change below string to date, When I'm trying to do this, I'm getting nil date.
Example 1:
Input:
Tue 20 May 2014 09:30:00 PM IST
Looking for/Output : 09 PM (Only Time and AM/PM)
Example 2:
"Tue 20 May 2014 10:00:00 AM CDT"
Output : 10 AM
NSString *dateString=#"20 May 2014 09:30:00 PM IST";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"EEE dd MMM yyyy HH:mm:ss a zzzz";
NSDate *time= [formatter dateFromString:dateString];
//above time object is getting nil
Anybody can you please help me how to change above string to date/time format. I tried many ways But I'm getting nil date object when i'm trying to convert string to date.
Here is how you are going to want to handle this:
NSString * dateString = #"Tue 20 May 2014 10:00:00 AM IST";
NSString *threeLetterZone = [[dateString componentsSeparatedByString:#" "] lastObject];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:threeLetterZone];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"EEE dd MMM yyyy hh:mm:ss a z";
NSDate *date;
if (timeZone)
{
NSString *gmtTime = [dateString stringByReplacingOccurrencesOfString:threeLetterZone withString:timeZone.abbreviation];
date = [formatter dateFromString:gmtTime];
}
NSLog(#"%#", date);
I know its a lot longer but this will return the GMT time of the string.
EDIT:
Cocoa is weird. You won't be able to preserve the timezone. Everything revolves around the GMT/UTC
If you want the local time:
NSString * dateString = #"Tue 20 May 2014 10:00:00 AM IST";
NSString *threeLetterZone = [[dateString componentsSeparatedByString:#" "] lastObject];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:threeLetterZone];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"EEE dd MMM yyyy hh:mm:ss a";
NSDate *date;
if (timeZone)
{
NSString *gmtTime = [dateString stringByReplacingOccurrencesOfString:threeLetterZone withString:#""];
date = [formatter dateFromString:gmtTime];
}
NSLog(#"%#", date);
It looks like there is a subset of time zone abbreviations that work, mainly abbreviations that are tied to a country, not a region. Even timezone abbreviations such as CET (Central European Time) do not work but CST (Cuban Standard Time) does. This makes some sense since 12 vs 24 hour time is usually tied to a country, not a timezone.
There is another problem here, that is the use of English abbreviations: "Tue" and "May".
Here is a version based on the answer by #Chase Walden that does not use GMT. The key element is the same, getting the `NSTimeZone from the string. It is a bit longer.
NSString * dateString = #"Tue 20 May 2014 10:00:00 AM IST";
NSMutableArray *components = [NSMutableArray arrayWithArray:[dateString componentsSeparatedByString:#" "]];
NSString *threeLetterZone = [components lastObject];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:threeLetterZone];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"EEE dd MMM yyyy hh:mm:ss a"];
if (timeZone) {
[components removeLastObject];
dateString = [components componentsJoinedByString:#" "];
[formatter setTimeZone:timeZone];
}
NSDate *date = [formatter dateFromString:dateString];
NSLog(#"%#", date);
2014-05-20 04:30:00 +0000
Here how you should do this in Objective C.
Igone the setTimeZone by the date formatter if you don't want any time zone changes.
NSString *inputDate = #"WhateverTheTime";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"CurrentDateTimeFormat"];
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"IST"]]; //Only if you want to change the timeZone
NSDate *date = [formatter dateFromString:inputDate];
[formatter setDateFormat:#"RequiredDateTimeFormat"];
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]]; //Only if you want to change the timeZone
NSString *requiredOutput = [formatter stringFromDate:date];
Cheers!!

Convert NSString to NSDate and back to different format NSString

I need to take the NSString Dec 4, 2012, 12:33 PM and convert it to separate out the month, day, and year, so that I can have 3 different strings of 12, 04, and 2012.
I figure that I should convert the NSString to NSDate and then reformat the date to change out NSString, but am running into issues.
I have:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM dd, yyyy, hh:mm p"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:substring];
NSLog(#"Date%#", dateFromString);
[dateFormatter release];
However, the date keeps coming back null.
The problem is with your locale I think.
You should try to print how your dateFormatter formats current date [NSDate new].
It works for me:
NSString* substring = #"Dec 12 2012 12:08 PM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormatter setDateFormat:#"MMM d yyyy h:mm a"]; // not 'p' but 'a'
NSDate *dateFromString = [dateFormatter dateFromString:substring];
Convert
[dateFormatter setDateFormat:#"MMM dd, yyyy, hh:mm p"];
to, Because MMM dd, yyyy, hh:mm p not a valid date formate
[dateFormatter setDateFormat:#"MMM dd, yyyy, hh:mm a"];
And
NSDate *dateFromString = [dateFormatter dateFromString:substring];
To get string again
NSLog(#"%#",[dateFormatter stringFromDate:dateFromString]);
for me NSLog is Dec 04, 2012, 12:33 PM
#import "NSString+Date.h"
#implementation NSString (Date)
+ (NSDate*)stringDateFromString:(NSString*)string;
{
NSString *dateString = #"01-02-2010";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// this is imporant - we set our input date format to match our input string
// if format doesn't match you'll get nil from your string, so be careful
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [[NSDate alloc] init];
// voila!
dateFromString = [dateFormatter dateFromString:dateString];
return dateFromString;
}
+(NSString*)StringFromDate :(NSDate*)date;
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"%#", stringDate);
return stringDate;
}
` #end

NSDate from String Conversion

Trying to convert the following string to an NSDate - I thought my DateFormatter was set correctly, but its not working:
NSString *dateToCheckString = #"Friday, Dec. 6, 2013 at 7:00 PM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"eeee, MMM. dd, yyyy at hh a"];
NSDate *dateToCheckNSDate = [[NSDate alloc] init];
dateToCheckNSDate = [dateFormatter dateFromString:dateToCheckString];
// Log it out to see the result:
NSLog(#"Conversion yielded: '%#'", [dateToCheckNSDate description]);
The output I get is (null)
Any ideas?
No it's not correct. dd is a padded day (06 in your example) so that should be just d. Also "7:00" does not match hh (which is padded hours). You are looking for h:mm

Resources