flutter_local_notifications icon indicating copy to clipboard operation
flutter_local_notifications copied to clipboard

Remove dependency on TimeZone

Open caseycrogers opened this issue 10 months ago • 4 comments

Describe the bug Not a bug. This is (sort of?) a feature request.

Constructing a TZDateTime from a Flutter environment is a nightmare: https://stackoverflow.com/questions/64305469/how-to-convert-datetime-to-tzdatetime-in-flutter

This is okay from the example app, but tz.initializeTimeZones is failing on my device ("Unsupported operation: Isolate.resolvePackageUriSync").

  tz.initializeTimeZones();
  final String? timeZoneName = await FlutterTimezone.getLocalTimezone();
  tz.setLocalLocation(tz.getLocation(timeZoneName!));

It's not clear to me what value TZDateTime is providing-the built in DateTime object is already time zone aware and Flutter gives me the user's current time zone. As far as I can tell, the only novel thing TZ does is map location to timezone, but in a Flutter context, this is useless because I already have the device reported timezone and getting location is a permissions escalation.

As such, the dependency on TimeZone should be removed entirely from this package's external API.

TZDateTime already implements DateTime so if someone really wanted to use it they still could.

Or, at the very least, maybe there could be a built in method to produce a valid TZDateTime from a Flutter build context.

caseycrogers avatar Apr 01 '24 10:04 caseycrogers

This is okay from the example app, but tz.initializeTimeZones is failing on my device ("Unsupported operation: Isolate.resolvePackageUriSync").

Did you raise an issue or check the timezone repo to see if there's a solution? It may not be an official package from Google but is maintained by a developer who works at Google

It's not clear to me what value TZDateTime is providing-the built in DateTime object is already time zone aware and Flutter gives me the user's current time zone. As far as I can tell, the only novel thing TZ does is map location to timezone, but in a Flutter context, this is useless because I already have the device reported timezone and getting location is a permissions escalation.

The plugin needed to deal with timezones as it was necessary to solve daylight savings issues so that the schedule remains consistent despite the change going to/from daylight savings may bring with the UTC/GMT offset. This brings the additional benefit of allowing apps to schedule notifications based on a timezone if needed. I'm not sure how location permission comes to into the picture with what you said as you would've run the example app to see that getting the user's permission for their location isn't needed. I assume that when you say that you already have the timezone that you're referring to https://api.dart.dev/stable/3.4.0/dart-core/DateTime/timeZoneName.html. If so, then it's problematic as it's not recognised by the native platform and would cause issues. As an example, I'm based in Sydney and this currently returns AEST. When daylight savings happens it would be AEDT. If the native platforms happened to recognise it, then it puts the burden on developers to deal with the daylight savings to adjust the offset themselves. The best way to deal with this is to use the IANA representation of a timezone. This is what's used/recognised by the native platforms and the timezone package provides a representation of the date/time using an IANA timezone. The platforms have their own way of returning the IANA timezone for the device and this is where plugins like https://pub.dev/packages/flutter_timezone are needed

It's a long reply but hopefully gives you a better idea on the reason behind why things are the way they are. As for

Or, at the very least, maybe there could be a built in method to produce a valid TZDateTime from a Flutter build context.

I have no plans to do so as I'd like to keep the plugin focused on notifications. You could create a package and publish one that combines the packages I mentioned but note that the current way of constructing a TZDateTime is already similar to how this is done on the native platforms e.g. https://developer.android.com/reference/java/time/ZonedDateTime#of(java.time.LocalDateTime,%20java.time.ZoneId)

MaikuB avatar May 17 '24 11:05 MaikuB

I use flutter_local_notifications version 13 to avoid the timezone dependency

andcea avatar May 28 '24 21:05 andcea

Can't we work with UTC dates instead of time zoned dates and avoid the need for the timezone dependency? Converting to UTC should solve the daylight savings issues.

andcea avatar May 28 '24 21:05 andcea

If you know of a way then you're welcome to submit a PR. It's my understanding that this isn't possible, especially on iOS/macOS where the API used to schedule a notification can also be made recurring based on the specified date/time components. As a result, this requires the timezone to be known

MaikuB avatar Jun 10 '24 06:06 MaikuB

Closing due to lack of response and I tried explain why things are the way they are. Haven't seen any PRs or other suggestions either. Happy to look at PRs around this but my preference would be that where possible to avoid reinventing what others in the community already provide. One thing I forgot to mention is around...

This is okay from the example app, but tz.initializeTimeZones is failing on my device ("Unsupported operation: Isolate.resolvePackageUriSync").

One thing to check here is if this is actually device-specific issue. Wanted to mention as it's mentioned to be ok in example app and as such won't actually device-specific issue unless there was a miscommunication. By that I mean if this was meant to say the example app doesn't work on the device you're using. I don't know what device you're using either. I'm wondering this is instead to do with calling the method in a different context (background isolate?) and that is where it fails. If so, then I suggest raising this as an issue on the timezone repository with details on how to reproduce it. This way the maintainer can try to investigate and this could in turn help others using the package

MaikuB avatar Sep 21 '24 02:09 MaikuB

For anyone interested, you can get around the timezone package by converting your dart DateTime to UTC first:

TZDateTime.from(dateTime.toUtc(), UTC)

Then you can use it with .zonedSchedule

flutterLocalNotificationsPlugin.zonedSchedule(
  ...
  TZDateTime.from(notification.dateTime.toUtc(), UTC),
  ...
)

It would be nice if flutter_local_notifications could get rid of the timezone dependency and schedule notifications by just converting the dart DateTime to UTC internally.

andcea avatar Sep 25 '24 19:09 andcea