Objective C - Convert DateTime to Local DateTime - objective-c

I am pretty new to Objective C and it has been horrible experience to get the current device datetime in systemTimeZone. This is what I have:
NSDate *now = [NSDate date];
NSDateFormatter *DateFormatter=[[NSDateFormatter alloc] init];
[DateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[DateFormatter setDateFormat:#"MM-dd-yyyy HH:mm"];
NSString *currentDateTime = [DateFormatter stringFromDate:now];
NSDate *curDate = [DateFormatter dateFromString:currentDateTime];
Line 5 NSString has the correct local datetime in currentDateTime string variable. But Line 6 again switches back to UTC DateTime. I do not understand why it would switch back to UTC even though the DateFormatter has the systemTimezone set. Can you please help me find out what is that I am missing?

Just set the timeZone in the dateFormatter, This code is enough
NSString *dateString = #"24 08 2011 09:45PM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MM yyyy hh:mma"];
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"BST"];
[dateFormatter setTimeZone:sourceTimeZone];
NSDate *dateFromString = [dateFormatter dateFromString:dateString];
The dateFromString will now have the date 24 08 2011 08:45PM(GMT).. Then to convert this to string with local time just code the following,
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone localTimeZone]];
[formatter setLocale:[NSLocale systemLocale]];
[dateFormatter setDateFormat:#"dd MM yyyy hh:mma"];
NSString *stringFromDAte = [dateFormatter stringFromDate:dateString];
or You can also try this one:
NSTimeInterval seconds; // assume this exists
NSDate* ts_utc = [NSDate dateWithTimeIntervalSince1970:seconds];
NSDateFormatter* df_utc = [[[NSDateFormatter alloc] init] autorelease];
[df_utc setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[df_utc setDateFormat:#"yyyy.MM.dd G 'at' HH:mm:ss zzz"];
NSDateFormatter* df_local = [[[NSDateFormatter alloc] init] autorelease];
[df_local setTimeZone:[NSTimeZone timeZoneWithName:#"EST"]];
[df_local setDateFormat:#"yyyy.MM.dd G 'at' HH:mm:ss zzz"];
NSString* ts_utc_string = [df_utc stringFromDate:ts_utc];
NSString* ts_local_string = [df_local stringFromDate:ts_utc];
// you can also use NSDateFormatter dateFromString to go the opposite way
Table of formatting string parameters:
https://waracle.com/iphone-nsdateformatter-date-formatting-table/
If performance is a priority, you may want to consider using strftime
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/strftime.3.html

Related

Converting an NSString result from SQLite into a formatted NSDate

I know that it sounds incessantly familiar, but most of the suggested solutions on SO have not worked for me for some strange reason.
I have a date string returned from an SQLite query as an NSString in this format:
2019-06-10 13:45:33
However, when any of the suggested date formatter solutions are applied, with or without timezone localisation, I keep getting such a result:
Mon Jun 10 13:45:33 2019
This is one of the routines I've tried, among many others:
NSString * dateString = #"2019-06-10 13:45:33";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
//[dateFormatter setDateFormat:#"YYYY-MM-dd HH:mm:ss"];
//[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss ZZZ"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
// dateFromString > Mon Jun 10 13:45:33 2019
Could I be doing something wrong or is there some missing step in the conversion?
TIA.
I could guess that you wanted another output format, if it is the case then you could try code like this:
NSString * dateString = #"2019-06-10 13:45:33";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
//[dateFormatter setDateFormat:#"YYYY-MM-dd HH:mm:ss"];
//[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss ZZZ"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
NSDateFormatter *printDateFormatter = [[NSDateFormatter alloc] init];
printDateFormatter.dateStyle = NSDateIntervalFormatterMediumStyle;
printDateFormatter.timeStyle = NSDateIntervalFormatterMediumStyle;
NSLog(#"%#", [printDateFormatter stringFromDate:dateFromString]);
The result will be:
10 Jun 2019 at 13:45:33
Use a different formatter to format the string from the date. For example:
NSDateFormatter * formatter=[[NSDateFormatter]alloc]init];
formatter.dateStyle = NSDateFormatterMediumStyle;
formatter.timeStyle = NSDateFormatterNoStyle;
NSString * formattedDateString = [formatter stringFromDate:date];
setDateFormat is for inputting date strings and getting NSDates.
dateStyle and timeStyle is for formatting dateStrings from NSDates.

NSDateformatter incompatible format

Tried almost everything and get null,
the format I pass as parameter 'NSString' : WED 13-11-2013
-(NSDate*)stringToDate:(NSString*)dateString{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
// [dateFormat setDateFormat:#"EE, d-LLLL-yyyy HH:mm:ss Z"];
// [dateFormat setDateFormat:#"EE, dd-MM-yyyy"];
[dateFormat setDateFormat:#"EEE, dd-MM-yyyy"];
// NSString *str = [dateString stringByAppendingString:#" 09:00:00 +0000"];
// NSDate *date = [dateFormat dateFromString:dateString];
NSDate *date = [dateFormat dateFromString:dateString];
return date;
}
Hi try that it works for me:
-(NSDate*)stringToDate:(NSString*)dateString{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"EEE dd-MM-yyyy ";
[dateFormatter setLocale:[NSLocale currentLocale]];
NSDate *date = [dateFormatter dateFromString:dateString];
return date
}

Format date with NSDateFormatter

I want to format 06-06-2013 1:51 PM as Jun 06,2013.
I have tried all possible different formatting styles using NSDateFormatter but failed.
Try this
First You need to convert this string back to NSDate then again convert the NSdate to string using formatter.
NSDateFormatter *dateFormatForDB = [[NSDateFormatter alloc] init];
[dateFormatForDB setDateFormat:#"dd-MM-yyyy HH:mm a"]; //Note capital H is 4 24-hour time format
NSDate *aDate = [[[NSDate alloc] initWithTimeInterval:0 sinceDate:[dateFormatForDB dateFromString:aDateString]] autorelease];
if(aDate){
[formatter setDateFormat:#"MMM dd,yyyy"];
NSString *date = [formatter stringFromDate:aDate];
[dateFormatForDB release];
}
Try to use this format
[df setDateFormat:#"MMM dd,yyyy];
By looking at your format, i think this is what you are looking for...
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"dd-MM-yyyy hh:mm a"];
NSDate *newDate = [df dateFromString:dateString];
NSDateFormatter *df2 = [[NSDateFormatter alloc] init];
[df2 setDateFormat:#"MMM dd,yyyy"];
NSString *formattedDate = [df2 stringFromDate:newDate];
This will give you the date as string in the required format. If you want time in 24hr format, replace 'hh' with 'HH'.

Time from a TextView into NSDate

I'm building an iPhone app to take times: a car has to get at a given time at a point, so if the car is sooner or later, gets points.
I need to obtain the most precise timing as I can, so I want to use milliseconds, but as far results are disappointing.
The time is typed on a TextField, let's say 12:17:22 and the code is the following:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setDateFormat:#"HH:mm:ss"];
timeLegStart = [NSDate new];
timeLegStart = [dateFormatter dateFromString:setStartTime.text];
NSLog(#"timeLegStart = %#",timeLegStart);
The output is 1970-01-01 11:17:22 +0000, and I'd like it to be 12:17:22:000
Set your NSDateFormatter's properties like this (replacing with your time zone info):
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"pt_BR"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"America/Sao_Paulo"]];
[dateFormatter setDateFormat:#"HH':'mm':'ss' 'z"];
[dateFormatter setLocale:locale];
The problem here is that NSDate comprises of date and time and they are not separately available. When you are giving the input date with time specs only it load the calendar start date values with the time you provided and creates a date. Hence here comes the date as output.
Actually there is no problem to work with that.
You can use the same formatter to get the time retrieved back:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSDate* timeLegStart = [NSDate new];
timeLegStart = [dateFormatter dateFromString:#"12:12:12"];
NSLog(#"timeLegStart = %#",[dateFormatter stringFromDate:timeLegStart]);
It will give you:
timeLegStart = 12:12:12
EDIT : when logging NSDate it will be in GMT format only.Since you set the timezone to local there date will be always displayed like what you got.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSDate* timeLegStart = [NSDate new];
timeLegStart = [dateFormatter dateFromString:#"12:12:12"];
NSLog(#"timeLegStart = %#",timeLegStart);
Will give you:
2000-01-01 12:12:12 +0000
Well, I've sorted it out this way:
- (void)fijaTiempoInicio
{
//getting current day
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:~ NSTimeZoneCalendarUnit fromDate:[NSDate date]];
[dateComponents setTimeZone:[NSTimeZone timeZoneWithName:#"Europe/Spain"]];
NSDate *currentDate = [[NSCalendar currentCalendar] dateFromComponents:dateComponents];
//extracting year, month and day from current date
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"dd"];
NSString *currentDayString = [NSString stringWithFormat:#"%#",[df stringFromDate:currentDate]];
[df setDateFormat:#"MM"];
NSString *currentMonthString = [NSString stringWithFormat:#"%#",[df stringFromDate:currentDate]];
[df setDateFormat:#"yyyy"];
NSString *currentYearString = [NSString stringWithFormat:#"%#", [df stringFromDate:currentDate]];
NSDateFormatter *ft = [[NSDateFormatter alloc]init];
[ft setTimeZone:[NSTimeZone localTimeZone]];
[ft setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *tempDate = [NSString stringWithFormat:#"%#-%#-%# %#",currentYearString,currentMonthString,currentDayString,txtTiempoInicioTramo.text];
NSLog(#"tempDate= %#",tempDate);
startTime = [ft dateFromString:tempDate];
NSLog(#"startTime= %#",startTime);
Then, anothe method calculate the difference between two NSDates, which is a figure in milliseconds -a float
- (IBAction)btnCapturarTiempo:(id)sender
{
NSDateFormatter *formatCarTime = [[NSDateFormatter alloc]init];
[formatCarTime setDateFormat:#"HH:mm:ss"];
[formatCarTime setTimeZone:[NSTimeZone timeZoneWithName:#"Europe/Madrid"]];
carTime = [NSDate date];
difference = [carTime timeIntervalSinceDate:startTime];
labelTiempoCoche.text = [NSString stringWithFormat:#"%f",difference];

NSString to NSDate returns wrong date

I try to convert my NSString to NSDate object, but NSDateFormatter returns me a strange value.
Here is code:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm"];
NSDate *date = [dateFormat dateFromString:#"2012-08-15 00:00"];
[dateFormat release];
date value is 2012-08-14 21:00 +0000. It is 3 hours difference between NSString value and NSDate value. I think I've missed something, but I don't know what.
This is what i use:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss ZZZ"];
NSDate *date = [dateFormat dateFromString:#"2012-08-15 00:00:00 +0000"];
NSLog(#"\n\n DATE: %# \n\n\n", date);
The +0000 is timezone, so make sure you use your timezone, like +0400.
Edit:
If you can't change the string, you can use this code to do it:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm"];
[dateFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date = [dateFormat dateFromString:#"2012-08-15 00:00"];
As i knew NSDate holds Grinwich time, so if you are in Moscow time zone, everything is wright
In objective c for NSDate if you did not set the setTimeZone, NSDate will take default timezone as localTimeZone. so if you need to get the exact date which you give as NSString string format, you need to setTimeZone as UTC. Follow the sample code, I guess it will be helpful for you.
NSDateFormatter *loacalformatter=[[NSDateFormatter alloc]init];
[loacalformatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *localDate =[loacalformatter dateFromString:#"2012-08-15 00:00"];
NSLog(#"localDate :%#",localDate);
NSDateFormatter *UTCformatter=[[NSDateFormatter alloc]init];
[UTCformatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[UTCformatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *UTCDate =[UTCformatter dateFromString:#"2012-08-15 00:00"];
NSLog(#"UTCDate :%#",UTCDate);
UTCDate :2012-08-15 00:00 +0000 (GMT+00:00)
As suggested in the comments, if the date you receive is UTC then you need to convert it to your local timezone. Apple recommend you always use a properly configured NSDateFormatter when displaying dates, to handle localisation issues.
Here's some example code for turning an NSDate into an NSString:
NSDate *date = // initialised elsewhere
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
dateFormat.locale = [NSLocale currentLocale];
dateFormat.timeZone = [NSTimeZone localTimeZone];
dateFormat.timeStyle = NSDateFormatterShortStyle;
dateFormat.dateStyle = NSDateFormatterShortStyle;
dateFormat.locale = [NSLocale currentLocale];
NSString *dateAsString = [dateFormat stringFromDate:date];