I have a EKEvent that I am using with a EKEventEditViewController to add a calendar event in my app. Even though the date is accurate, I get the incorrect time. Can someone help me figure out what I am doing wrong here..
This is the code to generate the event..
EKEvent *addEvent=[EKEvent eventWithEventStore:eventStore];
addEvent.title=event.title;
NSLog(#"Saving Event... %#",[event.date description]);
addEvent.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
addEvent.startDate= event.date;
NSLog(#"Event Date... %#",[addEvent.startDate description]);
addEvent.endDate=[addEvent.startDate dateByAddingTimeInterval:600];
[addEvent setCalendar:[eventStore defaultCalendarForNewEvents]];
addEvent.alarms=[NSArray arrayWithObject:[EKAlarm alarmWithRelativeOffset:-3600]];
My device's timezone is set to 'Port Louis, Mauritius'.
My console output is..
Saving Event... 2012-12-19 20:00:00 +0000
Event Date... 2012-12-19 20:00:00 +0000
But in the EKEventEditViewController, my start date shows Thu,20 Dec 0:00.
This is because the event at "2012-12-19 20:00:00 +0000" (i.e. 8pm GMT) will take place in Maritius at midnight. You're asking the user in Mauritius to add it to their calendar, so it's going to show the event date in the device's local timezone, midnight.
If the event is taking place at 8pm in Mauritius, then your original time is incorrect, because you're saying it's at 8pm GMT. If you're saying that the event is really taking place at 8pm GMT (midnight in Mauritius), then the EKEventEditViewController is just going to show the time according to the local timezone, midnight.
If the user has turned on timezone support, when they pull up the event in the Calendar app, it will show the timezone you specified when you created the even. If they haven't turned on timezone support, it will just show it in the local timezone (adjusting the start time as it should).
Unfortunately, unlike the calendar app, it appears that EKEventEditViewController will not show the timezone but rather displays it in local time, even if the user has turned on timezone support. It does not appear to support this timezone feature, even though it will be correct when they look at their calendar. At least the event is stored with the appropriate timezone information.
Related
I'm using flutter_local_notifications to schedule notifications at specific times every day.
The user can select different time zones, it works on Android but doesn't work on iOS, as I don't have experience with iOS, I don't know how it handles notifications.
Future<void> _showNotification(
BuildContext? context,
NotificationDetails platformChannelSpecifics,
Prayer prayer,
DateTime dateTime) async {// dateTime is the time in another time zone, and time is the time passed to the zonedScheduled method
var time = _nextInstanceOfPrayer(dateTime);
if (time == null) {
return;
}
await flutterLocalNotificationsPlugin.zonedSchedule(
_getId(time, prayer: prayer.toString()),
prayer.toStr(context!),
_getPrayerText(prayer.toStr(context)),
time,
platformChannelSpecifics,
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
);}
And this method to get the time:
tzZone.TZDateTime? _nextInstanceOfPrayer(DateTime dateTime) {
final DateTime now = DateTime.now();
//converts time to specific location
tzZone.TZDateTime scheduledDate = tzZone.TZDateTime.from(
dateTime.subtract(now.timeZoneOffset),
tzZone.UTC,
);
if (scheduledDate.toUtc().isBefore(now.toUtc())) {
return null;
}
return scheduledDate;}
What I'm trying is add notification at the time (time) in phone's local time,
for example, the user selects a +5 GMT time zone (5:00PM) and the local time zone is say +2 GMT (2:00PM), I want to add a notification with the local time of (5:00PM +5 GMT) and show it on (5:00 +2 GMT).
I have tried to convert both times to UTC and show the notification on UTC - local time zone (as shown in the second code), the code shows there are pending notifications but when I change the time of the device it doesn't show anything.
Note: when I add a manual time after 5 seconds, it works perfectly
DateTime.now().add(Duration(seconds: 5));
My app based on LocalNotifications in iOS 10.
I have a "Note" entity with "Reminder Date" (Daily, Weekly etc.). Every day I want a check: for today I have notes to remind or not. In case - if the user has only weekly-remind notes, how to check on what day of the week need to show notification.
Thanks
I dont think there is any possibility to execute your code on a specified time. Instead if your app is working on that time you can execute anything as you want. Otherwise application will not be in memory.
Use the code below to get the current time:
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSLog(#"%#",[dateFormatter stringFromDate:[NSDate date]]);
And check if time matches 9:00 AM
Not: only when your application is running.
Making a notification from APNS server is possible even if application is not working
i can get list of my scheduledLocalNotifications in my table view with this code perfectly ;
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
but the only problem is , my local notifications are firing on correct time but showing with wrong time zone on the list.
I'm also using systemTimeZone for scheduling my local notification like this ;
notification.timeZone = [NSTimeZone systemTimeZone];
What is the correct way to get a list of scheduledLocalNotifications with the correct time zone?
Thanks in advance
I've had the same problem when after i had already scheduled a notification at 3:30 pm and it was correctly scheduled when i NSLog it's fireDate it'll show up in a different time zone and that's how i fixed it.
[localNotification.fireDate descriptionWithLocale:NSGregorianCalendar]
this will return fire date with the Gregorian local (or you should use whatever local you have used when scheduling your local notification)
I've not experienced this problem personally, but it seems that for a number of my users, a notification being set for one time is actually being triggered an hour later.
Here's the code I use to generate the notification:
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.fireDate = date;
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = #"Alert time!";
notif.alertAction = #"Wake me";
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
Fairly standard. The users who've had the problem are on British time, which has daylight savings. I'm wondering if this is an iOS bug of some kind?
I believe the problem was to do with iOS storing a cache of the timeZone. This feature is kind of confusing, as there are 3 different timeZones you can have (and don't worry if half of this confuses you):
[NSTimeZone defaultTimeZone];
Returns the default time zone for the current application. If no default time zone has been set, this method invokes systemTimeZone and returns the system time zone. The default time zone is the one that the application is running with, which you can change (so you can make the application run as if it were in a different time zone).
[NSTimeZone localTimeZone];
Returns an object that forwards all messages to the default time zone for the current application. The local time zone represents the current state of the default time zone at all times. The local time zone adds a level of indirection, it acts as if it were the current default time zone whenever you invoke a method on it.
[NSTimeZone systemTimeZone];
Returns the time zone currently used by the system. If you get the system time zone, it is cached by the application and does not change if the user subsequently changes the system time zone. The next time you invoke systemTimeZone, you get back the same time zone you originally got. You have to invoke resetSystemTimeZone to clear the cached object.
This whole thing baffled me, personally. But that resetSystemTimeZone method seemed interesting:
If the application has cached the system time zone, this method clears that cached object. If you subsequently invoke systemTimeZone, NSTimeZone will attempt to redetermine the system time zone and a new object will be created and cached.
With the possibility of the user moving between time zones, and when some time zones support daylight savings and some don't, and being in mind that Apple themselves have on-going problems with all of this, it seemed like the logical solution would be to make this as non-breakable as possible.
Non-breakable meant that I used systemTimeZone throughout my entire app, and used resetSystemTimeZone on the line before every mention of it.
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.fireDate = date;
[NSTimeZone resetSystemTimeZone];
notif.timeZone = [NSTimeZone systemTimeZone];
I haven't had a problem with this so far. Hopefully this will help someone.
If I were to normalize an EKEvent 's startDate property using a NSDateFormatter and setting the time zone with
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm a"];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
event.startDate = [formatter dateFromString:[NSString stringWithFormat:#"%#", [event.startDate]]];
and I later make a change to that event requiring me to call
[self.event.eventStore saveEvent:currentEvent span:EKSpanThisEvent commit:YES error:nil];
Would it override the time-zone on the server, causing issues for the person (whom uses GCal) in another state that originally created that shared calendar event, or is it just a local change?
If it does affect the event, what is the best way for me to make sure the events on the app side always represent the users current time zone, without having to change format the event each time I refer to it on the UI?
Yes the timezone of an event will sync. If an event happens at 9 Mountain time, the event will be displayed as occurring at 9 to anyone whos devices general setiings is set to mountain time. If their device is eastern time, the event will appear to occur at 7. If you change the time zone of the event to Eastern, devices in mountain time will now see the event occurring at 11, and eastern time devices will see the event occurring at 9. So, changing the time zone does not change the time it occurs in its own time zone, but it will change it relative to where you moved it from.
You can do 2 things after asking the user when the event occurs: 1) you can assume the event occurs in the users devices current time zone. 2) you can ask them where the event occurs and set the events time zone to that.
If you have an event with the wrong time, you should first set its time zone to where the event is actually happening, then change when it occurs to when it actually happens, where it actually happens.
If you just focus on getting the data on the event set correctly, it will appear correctly on everyones device who is sharing the calendar with you.