Reputation: 42139
I have an NSDate
object that I am sending to an API that we use. Our app is used across the world, so the API is wanting the date to be in UTC, e.g.:
"/Date(1481704200000)/"
However, the date needs to have the timezone offset taken into account since the API/server is not doing this for us. If we don't do this, the date is incorrect when we view it on the server.
I am doing the following, which seems to produce an incorrect date:
// Offset
float timezoneoffset = [[NSTimeZone localTimeZone] secondsFromGMT];
// Date
CFTimeInterval startDate = [[NSDate date] timeIntervalSince1970];
startDate = startDate - timezoneoffset;
NSString *dateStarted = [NSString stringWithFormat:@"/Date(%.0f000)/", startDate];
How can I correctly take the local time zone into account and create a correctly formatted UTC date string?
Upvotes: 2
Views: 667
Reputation: 525
public let Date_format_Default:String = "yyyy-MM-dd HH:mm:ss"
Set this format string for UTC string;
public let Date_format_Z:String = "yyyy-MM-dd HH:mm:ssZ"
public let Time_zone_UTC:String = "UTC"
open class func convertDate2UTC(_ date:String)->(String){
var df_:DateFormatter?=DateFormatter()
df_!.dateFormat=Date_format_Z
let tz_=TimeZone(identifier: Time_zone_UTC)
df_!.timeZone=tz_
let df_s=df_!.date(from: date)
df_!.dateFormat=Date_format_Default
let string_=df_!.string(from: df_s!)
df_ = nil
return string_;
}
Upvotes: -1
Reputation: 2352
NSDate *currentDate = [NSDate date];
Now it is in UTC, (at least after using the method below) To store this time as UTC (since refernce date 1970) use
double secsUtc1970 = [[NSDate date]timeIntervalSince1970];
Set Date formatter to output local time:
NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];
// or Timezone with specific name like
// [NSTimeZone timeZoneWithName:@"Europe/Riga"]
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString *localDateString = [dateFormatter stringFromDate:currentDate];
NSDate
object always uses UTC as time reference, but the string representation of a date is not neccessarily based on UTC timezone.
To get timezones, you can use this:
NSTimeZone* timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSString* timeZoneName = [timeZone localizedName:NSTimeZoneNameStyleStandard locale:[NSLocale currentLocale]];
NSLog(@"Name : %@", timeZoneName);
If you call [NSTimeZone abbreviationDictionary]
you'll get a dictionary containing all available abbreviations.
NSLog(@"%@",[NSTimeZone abbreviationDictionary]);
Result :
2015-07-10 11:44:05.954 APP[1472:26120] {
ADT = "America/Halifax";
AKDT = "America/Juneau";
AKST = "America/Juneau";
ART = "America/Argentina/Buenos_Aires";
AST = "America/Halifax";
BDT = "Asia/Dhaka";
BRST = "America/Sao_Paulo";
BRT = "America/Sao_Paulo";
BST = "Europe/London";
CAT = "Africa/Harare";
CDT = "America/Chicago";
CEST = "Europe/Paris";
CET = "Europe/Paris";
CLST = "America/Santiago";
CLT = "America/Santiago";
COT = "America/Bogota";
CST = "America/Chicago";
EAT = "Africa/Addis_Ababa";
EDT = "America/New_York";
EEST = "Europe/Istanbul";
EET = "Europe/Istanbul";
EST = "America/New_York";
GMT = GMT;
GST = "Asia/Dubai";
HKT = "Asia/Hong_Kong";
HST = "Pacific/Honolulu";
ICT = "Asia/Bangkok";
IRST = "Asia/Tehran";
IST = "Asia/Calcutta";
JST = "Asia/Tokyo";
KST = "Asia/Seoul";
MDT = "America/Denver";
MSD = "Europe/Moscow";
MSK = "Europe/Moscow";
MST = "America/Denver";
NZDT = "Pacific/Auckland";
NZST = "Pacific/Auckland";
PDT = "America/Los_Angeles";
PET = "America/Lima";
PHT = "Asia/Manila";
PKT = "Asia/Karachi";
PST = "America/Los_Angeles";
SGT = "Asia/Singapore";
UTC = UTC;
WAT = "Africa/Lagos";
WEST = "Europe/Lisbon";
WET = "Europe/Lisbon";
WIT = "Asia/Jakarta";
}
Hope this will be helpful.
Upvotes: 1
Reputation: 318814
There is no need for any timezone manipulation.
NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
NSString *dateStarted = [NSString stringWithFormat:@"/Date(%.0f)/", interval * 1000];
This gives you the time in UTC regardless of the user's timezone.
Try it. Run this code with several different timezone settings on your test device and you will get the same result in every case.
Upvotes: 5