I'm having trouble converting NSDate date to local DateTime. I'm using Local Notifications and my fireDate property is ok except UTC component in my date.
This is NSDate date and converted date to my local timezone
This is my conversion code as found here Convert UTC NSDate to local Timezone Objective-C
NSDate *someDateInUTC = [NSDate date];
NSTimeInterval timeZoneSeconds = [[NSTimeZone localTimeZone] secondsFromGMT];
NSDate *dateInLocalTimezone = [someDateInUTC dateByAddingTimeInterval:timeZoneSeconds];
I'm adding five seconds to my time component so this is my fireDate:
I'm using push notifications and when the user is somewhere in the app, I want to present him local notification from my push notification. This code is in my - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo method. I've implemented method for local notifications:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState applicationState = application.applicationState;
if (applicationState == UIApplicationStateBackground) {
[application presentLocalNotificationNow:notification];
}
}
I'm thinking that this UTC component in my dateInLocalTimezone is causing my trouble but I don't know how to solve it.
Ok so i read your question. and i have then below example for you.
here i am converting Local time to UTC Time.
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = #"LLL d, yyyy - HH:mm:ss zzz";
NSDate *utc = [fmt dateFromString:#"June 14, 2012 - 01:00:00 UTC"];
fmt.timeZone = [NSTimeZone systemTimeZone];
NSString *local = [fmt stringFromDate:utc];
NSLog(#"%#", local);
Related
I have a date from date picker in ios, I get the date and the time and I convert this to string and saved in localStorage. Then, I get this string date and convert it to NSDate and use it in my notification. But my problem is that the notification are not run because the date changes after conversion.
The time and date from picker is: dateFromPicker=Thursday-20-March-2014 09:21 AM
The time and date from picker before 4 hours is :StringDateBefore4hours=Thursday-20-March-2014 05:21 AM
The string time before 4 hours after converting to NSDate is :DateBefore4hours=2014-03-20 00:21:00 +0000
The time is changed and my notification not run on the time selected what can we do help me please please .
That is code for getting date from picker and assigning to notification
NSDate *date=[self.DatePicker date];
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = date;
localNotification.alertBody = self.TextField.text;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber=[[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
I am trying to get my app to fire a notification based off a scheduled event. The date given is from a schedule that will take place in EST. The time given is Fri Feb 21 2014 12:00:00 -0500 (Noon EST).
When the button to schedule a notification is pressed, it runs this code:
NSString *message = [#"15 minutes until " stringByAppendingString:self.thetitle];
NSLog(#"original%#", self.thedate);
NSDate *newDate = [self.thedate dateByAddingTimeInterval:-60*15];
NSDateFormatter *formatter3 = [[NSDateFormatter alloc] init];
// [formatter3 setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
[formatter3 setTimeStyle:NSDateFormatterShortStyle];
[formatter3 setDateStyle:NSDateFormatterShortStyle];
NSString *detailstext = [formatter3 stringFromDate:newDate];
NSDate *othernewdate = [formatter3 dateFromString:detailstext];
NSLog(#"other%#", othernewdate);
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.timeZone = [NSTimeZone systemTimeZone];
notification.fireDate = othernewdate;
notification.alertBody = message;
notification.soundName = UILocalNotificationDefaultSoundName;
notification.hasAction = YES;
notification.alertAction = NSLocalizedString(#"View", #"View notification button");
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
Since the time being set on the notification fireDate is the othernewdate, I ran an NSLog in the console to see what it showed. It came back:
2014-02-21 16:45:00 +0000
This seems to be perfect, because that time in EST would be 11:45 AM, or 15 minutes before noon, which is what I wanted.
The issue is this:
I am testing this in CST. I run the app, tell it to schedule a notification for this event, and then change my phone clock to be EST and it ends up firing the notification at 10:45.
There will be people using this app from different time zones, and then traveling to EST for when the conference that this app is for starts. I don't want them to schedule lots of notifications while in a different time zone and have it fire at the wrong time. Any suggestions?
If you want the notification to fire at an absolute date/time, independent of the time zone, then you must set notification.timezone = nil.
From the documentation:
"The date specified in fireDate is interpreted according to the value of this property. If you specify nil (the default), the fire date is interpreted as an absolute GMT time, which is suitable for cases such as countdown timers. If you assign a valid NSTimeZone object to this property, the fire date is interpreted as a wall-clock time that is automatically adjusted when there are changes in time zones; an example suitable for this case is an an alarm clock."
enable uilocalnotification
Need to enable this notification schedules daily, I'm not getting, I created 3 different methods for each hour worked but it is not.
8:00 AM
12:00 AM
4:00 PM
-(void)Hour_08 {
NSString *str = [NSString stringWithFormat: #"%# 08:00", self.DayNow];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd hh:mm"];
NSDate *date = [dateFormatter dateFromString: str];
UILocalNotification *OitoHorasNotification = [[UILocalNotification alloc]init];
[OitoHorasNotification setFireDate:date];
OitoHorasNotification.repeatInterval = NSDayCalendarUnit;
[OitoHorasNotification setAlertBody:#"is now 08:00"];
[[UIApplication sharedApplication]scheduleLocalNotification:OitoHorasNotification];
}
Have you taken a look at this site as it suggests you use NSHourCalendarUnit instead of NSDayCalendarUnit which would be the case if you performing notifications after whole days. Or Maybe you are performing Notifications for whole days and therefore your code would be correct I would of miss read you question
I have a method that makes the store of a UILocalNotification:
- (void)save:(NSString *)program at:(NSDate*)date {
NSLog(#"date to save: %#", date);
// NSLog(#"timezone: %#",[date descriptionWithLocale:[NSLocale systemLocale]]);
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
NSLog(#"date to fire: %#", date);
localNotification.fireDate = date;
NSString *s=[program stringByAppendingString:#" is now on "];
NSString *title=[s stringByAppendingString:channel];
localNotification.alertBody = title;
localNotification.alertAction = #"Show...";
//localNotification.timeZone = [NSTimeZone localTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
NSLog(#"notification to save %#",localNotification);
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// Request to reload table view data
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
// Dismiss the view controller
[self dismissViewControllerAnimated:YES completion:nil];
}
And I have as output:
date to save: 2013-08-29 17:00:00 +0000
date to fire: 2013-08-29 17:00:00 +0000
notification to save <UIConcreteLocalNotification: 0xc0c4240>{fire date = Thursday, August 29, 2013, 6:00:00 PM Central European Standard Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Thursday, August 29, 2013, 6:00:00 PM Central European Standard Time, user info = (null)}
Despite uncommenting the timezone setting, the UILocalNotification is always incrementing by one hour, why, and how ?
Thank you for helping.
The date you pass in in GMT, which in you case is does not match your local time zone.
So when you set the date to 17:00 your time corrects it to you timezone (CET) which is GMT+1.
Thus an hour gets added to you date.
A solution is to set the UILocalNotification timezone to GMT:
localNotification.timeZone = [NSTimeZone timeZoneWithName#"GMT"];
From the Apple documentation:
The date specified in fireDate is interpreted according to the value
of this property. If you specify nil (the default), the fire date is
interpreted as an absolute GMT time, which is suitable for cases such
as countdown timers. If you assign a valid NSTimeZone object to this
property, the fire date is interpreted as a wall-clock time that is
automatically adjusted when there are changes in time zones; an
example suitable for this case is an an alarm clock.
I am trying:
NSDate *currentDateInLocal = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"];
NSString *currentLocalDateAsStr = [dateFormatter stringFromDate:currentDateInLocal];
NSDateFormatter * dateFormatter2 = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
[dateFormatter2 setTimeZone:timeZone];
[dateFormatter2 setDateFormat:#"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"];
NSDate *currentDateInUTC = [dateFormatter2 dateFromString:currentLocalDateAsStr];
but It's still does not represent the current UTC time, how can I achieve this?
Thanks
You're overcomplicating things.
NSDates don't have time zones or calendars. [NSDate date] gets the current date, which is a measurement of a moment in history. If I run [NSDate date] in Europe at exactly the same time as you run it in America then we'll get exactly the same value.
How you print a date depends on the calendar and the time zone. So a date printed in the Gregorian calendar looks different from the same one printed in the Julian calendar. And a date printed in the UTC Gregorian calendar looks different from the same one printed in the PST Gregorian calendar. But they're still the same date.
So you want to jump straight to your dateFormatter2.
The accepted answer by Alex Wien is incorrect.
By default, NSDateFormatter adjusts the NSDate’s date-time value from UTC to the user's local time zone. To prevent that adjustment, tell the NSDateFormatter to use the time zone for UTC.
To verify results, google "current time utc".
My source code below should do the job, meaning get the current date-time as a string in ISO 8601 format in the UTC (Zulu) time zone signified by a Z on the end.
NSDate* datetime = [NSDate date];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]]; // Prevent adjustment to user's local time zone.
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString* dateTimeInIsoFormatForZuluTimeZone = [dateFormatter stringFromDate:datetime];
You could put this logic in a pair of convenience methods somewhere in your app.
- (NSString*)now
{
// Purpose: Return a string of the current date-time in UTC (Zulu) time zone in ISO 8601 format.
return [self toStringFromDateTime:[NSDate date]];
}
…and…
- (NSString*)toStringFromDateTime:(NSDate*)datetime
{
// Purpose: Return a string of the specified date-time in UTC (Zulu) time zone in ISO 8601 format.
// Example: 2013-10-25T06:59:43.431Z
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString* dateTimeInIsoFormatForZuluTimeZone = [dateFormatter stringFromDate:datetime];
return dateTimeInIsoFormatForZuluTimeZone;
}
Example of usage…
NSString* now = [self now];
Or turn those minus signs into plus signs to use as class methods rather than instance methods…
NSString* now = [SomeClassNameHere now];
Tip: For better readability by humans, change that T in the format to a SPACE. For better interoperability by software, keep the T. The ISO 8601 spec tolerates a space but recommends keeping the T.
Tip: I've not tested, but… Some people say instantiating [NSDateFormatter][4] is expensive. If doing so often (such as in a loop) consider caching a single instance for re-use.
NSDate *currentDate = [[NSDate alloc] init];
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"] (see link below)
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString *localDateString = [dateFormatter stringFromDate:currentDate];
Available NSTimeZone names
A NSDate object always uses UTC as time reference, but the string representation of a date is not neccessarily based on UTC timezone.
Please note that UTC is not (only) a timeZone, It is a system how time on earth is measured, how it is coordinated (The C in UTC stands for coordinated).
The NSDate is related to a reference Date of midnight 1.1.1970 UTC, altough slightly wrongly described by Apple as 1.1.1970 GMT.
In the original question the last word timeZone is not perfect.
PLEASE SET UP Calendar Identifier !!!
I am not too late! Because I saw no one set up the Calendar Identifier. It is really important for worldwide users. Many users using a non-Gregorian calendar. They will get wrong year string. Especially, when you need store it into your own database. (We met this problem before)
NSCalendarIdentifierGregorian
NSCalendarIdentifierBuddhist
NSCalendarIdentifierChinese
NSCalendarIdentifierHebrew
NSCalendarIdentifierIslamic
NSCalendarIdentifierIslamicCivil
NSCalendarIdentifierJapanese
NSCalendarIdentifierRepublicOfChina
NSCalendarIdentifierPersian
NSCalendarIdentifierIndian
NSCalendarIdentifierISO8601
Code:
-(NSString *)getUTCFormateDate:(NSDate *)localDate
{
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[dateFormatter setCalendar:gregorianCalendar];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setLocale:locale];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *dateString = [dateFormatter stringFromDate:localDate];
return dateString;
}
Swift 3
let utcTimestamp = Date().timeIntervalSince1970
print("timeStamp = \(utcTimestamp)")
May following extension would be easier.
Swift 4: UTC/GMT ⟺ Local (Current/System)
extension Date {
// Convert local time to UTC (or GMT)
func toGlobalTime() -> Date {
let timezone = TimeZone.current
let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
return Date(timeInterval: seconds, since: self)
}
// Convert UTC (or GMT) to local time
func toLocalTime() -> Date {
let timezone = TimeZone.current
let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
return Date(timeInterval: seconds, since: self)
}
}
// Try it
let utcDate = Date().toGlobalTime()
let localDate = utcDate.toLocalTime()
print("utcDate - (utcDate)")
print("localDate - (localDate)")
[NSDate date] is UTC. Maybe you get fooled by looking in the locals? Then it gets converted to your timezone.
If you see the value in the locals, you see it in local time, but if you print it in the console, you see it in UTC.
When you see '+0000' after the time, you know it is in UTC
Still another way to do it is like so in a C++ class in your Objective C project. (So, make a .mm file and build a C++ class with public and private parts, and stick this in the public part (unless you need it private).) Then, reference it like NSString *sNowUTC = MyClass::getUTCTimestamp();.
static NSString *getUTCTimestamp(){
time_t rawtime;
struct tm * timeinfo;
char buffer [80];
time (&rawtime);
timeinfo = gmtime (&rawtime);
// make format like "2016-06-16 02:37:00" for
// June 16, 2016 # 02:37:00 UTC time
strftime (buffer,80,"%F %T",timeinfo);
std::string sTime(buffer);
NSString *sUTC = #(sTime.c_str());
return sUTC;
}
This is what i used.
static func makeISO8601Date(isoDateString: String) -> Date {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
return formatter.date(from: isoDateString)
}
makeISO8601Date(isoDateString: "2017-12-31T23:59:59+00:00")