iOS - Converting time and date to user time zone - ios

I am sending some requests on a webserver that replies me time and date like this:
"at 18:58 of 05/08/2012"
I can figure out how to get the time and the date in 2 NSStrings(18:58, 05/08/2012).
Note that the server's time zone is +00:00. What I want to accomplish is to present this time based on user's location. So for example if the reply from server is 23:30 at 05/08/2012 and the user's time zone is +2:00 I want to present him 1:30 at 06/08/2012.
Any ideas?

You should do it the following way:
1) First, create an NSDateFormatter to get the NSDate sent from the server:
NSDateFormatter *serverFormatter = [[NSDateFormatter alloc] init];
[serverFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
[serverFormatter setDateFormat:#"'at 'HH:mm' of 'dd/MM/yyyy"];
From Apple docs: note with the Unicode format string format, you should enclose literal text in the format string between apostrophes ('').
2) Convert the string (consider it is defined as theString) to a NSDate:
NSDate *theDate = [serverFormatter dateFromString:theString];
3) Create an NSDateFormatter to convert theDate to the user:
NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];
[userFormatter setDateFormat:#"HH:mm dd/MM/yyyy"];
[userFormatter setTimeZone:[NSTimeZone localTimeZone]];
3) Get the string from the userFormatter:
NSString *dateConverted = [userFormatter stringFromDate:theDate];

instead of getting absolute time from server get timestamp from server and convert that in to date at the client side, for this you didn't have to change the timezone also.

Related

UTC t to local time junk data in swift [duplicate]

I am getting the following string from a server in my iOS app:
20140621-061250
How can I convert it to the local time?
How can I define my date formatter? Is this correct?
dateFormatter.dateFormat = #"YYYYMMd-HHmmss";
The question doesn't specify the nature of what you mean by converting, exactly, but the first thing you should do, regardless of the final goal, is to correctly parse the server response using a properly configured NSDateFormatter. This requires specification of the correct format string, and the time zone must be explicitly set on the formatter or it will infer it from the local time, which would be incorrect in most cases.
Specify The Format String
Let's look at the input string provided:
20140621-061250
This uses four digits for the year, two digits (with a zero-padding) for the month, and two digits (presumably, these will be zero-padded as well) for the day. This is followed by a -, then two digits to represent the hour, 2 digits for the minute, and 2 digits for the second.
Referring to the Unicode date format standards, we can derive the format string in the following way. The four digits representing the calendar year will be replaced with yyyy in the format string. Use MM for the month, and dd for the day. Next would come the literal -. For the hours, I assume that it will be in 24 hour format as otherwise this response is ambiguous, so we use HH. Minutes are then mm and seconds ss. Concatenating the format specifiers yields the following format string, which we will use in the next step:
yyyyMMdd-HHmmss
In our program, this would look like:
NSString *dateFormat = #"yyyyMMdd-HHmmss";
Configure the input date formatter
The time format above does not specify a time zone, but because you have been provided the specification for the server response that it represents the UTC time, we can code this into our application. So, we instantiate an NSDateFormatter, set the correct time zone, and set the date format:
NSTimeZone *inputTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"UTC"];
NSDateFormatter *inputDateFormatter = [[NSDateFormatter alloc] init];
[inputDateFormatter setTimeZone:inputTimeZone];
[inputDateFormatter setDateFormat:dateFormat];
Convert the input string to an NSDate
For demonstration purposes, we hard-code the string you received from the server response; you would replace this definition of inputString with the one you get from the server:
NSString *inputString = #"20140621-061250";
NSDate *date = [inputDateFormatter dateFromString:inputString];
At this point, we have the necessary object to do any further conversions or calculations - an NSDate which represents the time communicated by the server. Remember, an NSDate is just a time stamp - it has no relation to a time zone whatsoever, which only plays a role when converting to and from string representations of the date, or representations of a calendrical date via NSDateComponents.
Next steps
The question doesn't clearly specify what type of conversion is needed, so we'll see an example of formatting the date to display in the same format as the server response (although, I can't think of a likely use case for this particular bit of code, to be honest). The steps are quite similar - we specify a format string, a time zone, configure a date formatter, and then generate a string (in the specified format) from the date:
NSTimeZone *outputTimeZone = [NSTimeZone localTimeZone];
NSDateFormatter *outputDateFormatter = [[NSDateFormatter alloc] init];
[outputDateFormatter setTimeZone:outputTimeZone];
[outputDateFormatter setDateFormat:dateFormat];
NSString *outputString = [outputDateFormatter stringFromDate:date];
Since I'm in UTC-06:00, printing outputString gives the following:
20140621-001250
It's likely you'll instead want to use setDateStyle: and setTimeStyle: instead of a format string if you're displaying this date to the user, or use an NSCalendar to get an NSDateComponents instance to do arithmetic or calculations on the date. An example for displaying a verbose date string to the user:
NSTimeZone *outputTimeZone = [NSTimeZone localTimeZone];
NSDateFormatter *outputDateFormatter = [[NSDateFormatter alloc] init];
[outputDateFormatter setTimeZone:outputTimeZone];
[outputDateFormatter setDateStyle:NSDateFormatterFullStyle];
[outputDateFormatter setTimeStyle:NSDateFormatterFullStyle];
NSString *outputString = [outputDateFormatter stringFromDate:date];
Printing outputString here gives us the following:
Saturday, June 21, 2014 at 12:12:50 AM Mountain Daylight Time
Note that setting the time zone appropriately will handle transitions over daylight savings time. Changing the input string to "20141121-061250" with the formatter style code above gives us the following date to display (Note that Mountain Standard Time is UTC-7):
Thursday, November 20, 2014 at 11:12:50 PM Mountain Standard Time
Summary
Any time you get date input in a string form representing a calendar date and time, your first step is to convert it using an NSDateFormatter configured for the input's format, time zone, and possibly locale and calendar, depending on the source of the input and your requirements. This will yield an NSDate which is an unambiguous representation of a moment in time. Following the creation of that NSDate, one can format it, style it, or convert it to date components as needed for your application requirements.
To get your string into a NSDate, you would use a NSDateFormatter like this:
NSString *myDateAsAStringValue = #"20140621-061250"
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyyMMdd-HHmmss"];
NSDate *myDate = [df dateFromString: myDateAsAStringValue];
You may want to read this post about working with Date and Time
EDIT:
To parse it as UTC you have to add the line:
[df setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
Also, when you print it with NSLog, if you are using the same NSDateFormatter, you will get the input string as output (since you apply the inverse of the parsing function).
Here is the full code, for parsing and for getting the output with a standard format:
//The input
NSString *myDateAsAStringValue = #"20140621-061250";
//create the formatter for parsing
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
[df setDateFormat:#"yyyyMMdd-HHmmss"];
//parsing the string and converting it to NSDate
NSDate *myDate = [df dateFromString: myDateAsAStringValue];
//create the formatter for the output
NSDateFormatter *out_df = [[NSDateFormatter alloc] init];
[out_df setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssz"];
//output the date
NSLog(#"the date is %#",[out_df stringFromDate:myDate]);
One possible solution in Swift using NSDate extension (maybe it could help future viewers of this question):
import UIKit
// For your personal information: NSDate() initializer
// always returns a date in UTC, no matter the time zone specified.
extension NSDate {
// Convert UTC (or GMT) to local time
func toLocalTime() -> NSDate {
let timezone: NSTimeZone = NSTimeZone.localTimeZone()
let seconds: NSTimeInterval = NSTimeInterval(timezone.secondsFromGMTForDate(self))
return NSDate(timeInterval: seconds, sinceDate: self)
}
// Convert local time to UTC (or GMT)
func toGlobalTime() -> NSDate {
let timezone: NSTimeZone = NSTimeZone.localTimeZone()
let seconds: NSTimeInterval = -NSTimeInterval(timezone.secondsFromGMTForDate(self))
return NSDate(timeInterval: seconds, sinceDate: self)
}
}

Lossless conversion of NSDate to NSString and vice versa

I have an NSDate:
2015-07-13 16:04:01 +0000
and I want to convert it to an NSString to be able to store it on a server and then read it back from server and convert back to NSDate without losing any details.
I've been looking at other posts that have suggested doing it as follows:
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *dateString = [dateFormatter stringFromDate:date];
and vice-versa:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [dateFormatter dateFromString:message[#"date"]];
but this leads to the loss and compromise of the format:
Jul 13, 2015
How do I convert NSDate to NSString and back, eventually getting back the exact original NSDate?
You're only formatting the original NSDate with a date (not time) style that reflects the user's preferences and you're only formatting the retrieved NSDate with day, month, and year, i.e. "dd-MM-yyyy". You should be consistent your NSDateFormatters in order to maintain the original format.
Change both
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
and
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
to
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss Z"];
to get and keep the entire date and time format.
An NSDate stores the number of seconds since a reference date. If you are using only iOS applications. then you call a method returning that number of seconds as an NSTimeInterval which is a number, and then you store the number. This means there is absolutely no loss of information. Your data will come back with better than microsecond precision.
If the data has to be read by different devices not running iOS then there is another method returning the number of seconds since Jan 1st, 1970. This is a very standard format that any OS should be able to handle.
Storing a number instead of a string seems to be much better.

Convert a date to English format form Bengali

I have a date picker in my app. The phone is set to Bangladesh local settings. When I select a date from datepicker is always returns the date in Bengali. It return a date in local format.
Like, it returns ০৬/১১/২০১৪
but I want it to be 06/11/2014.
I've tried converting it by date formatter. This is what I tried:
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[NSLocale currentLocale]];
NSDate* date = [formatter dateFromString: self.birthDate.text];
NSDateFormatter *formater = [[NSDateFormatter alloc] init];
[formater setLocale:[NSLocale localeWithLocaleIdentifier:#"en_US"]];
[formater setDateFormat:#"dd/MM/yyyy"];
NSLog(#"%#",[formater stringFromDate:date]);
The output is null.
You are incorrect in your assumption when you say...
When I select a date from datepicker is always returns the date in Bengali. It return a date in local format.
UIDatePicker returns an NSDate object. NSDate has no formatting at all. It has no language, it is purely a point in time.
When you do this...
NSLog(#"%#", someDate);
The system will render that point in time into a string and then print it. It is the rendering into a string that contains the format.
I'm guessing what you are doing is this...
Get a date from a UIDatePicker.
Render that date into a UITextField in Bengali. (or label, or text view or something)
Trying to read the text and store it into a date.
Trying to then "convert" the date to an English string.
What you should be doing is just saving the date that comes from the date picker.
Put it into a property or something.
In your above code I think the bit that is failing is actually the first bit...
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[NSLocale currentLocale]];
NSDate* date = [formatter dateFromString: self.birthDate.text];
Because you're not giving it a format it will fail. But this is the wrong way to go about it anyway.
You should have something like this...
- (void)datePickerChoseADate
{
self.date = self.datePicker.date;
}

Converting UTC time to local time

I am fetching data from the server and part of that data is time. Time is stored in UTC in my DB so what I'm returning is also in UTC. For example: 2014-05-22 05:12:40
Further, I am using the DateTools to show the time difference on the device like X hours ago or X minutes ago etc....
The problem is that when the UTC time coming from the server is compared to the local time there is a huge difference. Something that should say X seconds ago says X hours ago because of the time difference.
Question
How can I convert the date coming from the server to the local time zone set on the device?
This is what I'm doing right now:
#date_formatter = NSDateFormatter.alloc.init
#date_formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
#date_from_server = "2014-05-22 05:12:40"
#date = #date_formatter.dateFromString(#date_from_server)
#time.text = #date.shortTimeAgoSinceNow
I don't know how it is done in ruby motion but in Objective-C, it is done as follows :
1.) Create an instance of NSDateFormatter class
2.) Set a specific date format string of it, and also you set the specific time zone of it
3.) Get a date from the incoming string via the dateformatter instance
4.) Change the time zoneof the date formatter instance to the local time zone
5.) Convert the date obtained previously to the new time zone .
In Objective-C
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:incomingDateFormat];
[df setTimeZone:incomingTimeZone]; // Can be set to #"UTC"
NSDate *date = [df dateFromString:incomingDateString];
[df setDateFormat:newDateFormat];
[df setTimeZone:newTimeZone]; //// Can be set to [NSTimeZone localTimeZone]
NSString *newDateStr = [df stringFromDate:date];
I believe the same can be done in Rubymotion too.
NSDateFormatter *formater = [[NSDateFormatter alloc] init];
formater.dateFormat = #"yyyy-MM-dd HH:mm:ss";
NSString *datestr = #"2014-05-22 05:12:40";
formater.timeZone = [NSTimeZone localTimeZone];
NSDate *date = [[formater dateFromString:datestr] dateByAddingTimeInterval:formater.timeZone.secondsFromGMT];
NSDateFormatter *df=[[[NSDateFormatter alloc] init] autorelease];
// Set the date format according to your needs
[df setTimeZone:[NSTimeZone timeZoneWithName:#"America/Toronto"]];
//[df setDateFormat:#"MM/dd/YYYY HH:mm "] // for 24 hour format
[df setDateFormat:#"YYYY-MM-dd HH:mm:ss"];// for 12 hour format
Try this

how to convert Javascript Date to iOS date format

I am new in iOS development. Actually I am trying to show some information which I get from a web service in a table view.
I have successfully retrieved the response as JSON in my code, but in my table view there is a label to show date.
But in my response the date is something like this
/Date(1391068800000)/
How can I convert this to show in my table view? I think this is Javascript date.
But I'm not sure how to convert it.
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[your timestamp doublevalue]/1000];
divide value by 1000 cause of milliseconds (13 digit)
The date in your response is a timestamp. You can create a date object by:
NSDate *date = [NSDate dateWithTimeIntervalSince1970:1391068800000];
After that you can convert this date to a string in an appropriate format by using the NSDateFormatter class. For example:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
NSString *dateString = [formatter stringFromDate:date];
For more information about formatting dates see: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html

Resources