😺
timezoneとdevice_calendarを併用する際の注意点
概要
timezone と device_calendar を併用した際に、思わぬ挙動に遭遇したので、その備忘録です。
結論から書くと、timezone と device_calendar を併用する際は、DeviceCalendarPlugin の初期化時にshouldInitTimezone: false
にしましょう。
// shouldInitTimezoneをfalseに!
final deviceCalendarPlugin = DeviceCalendarPlugin(shouldInitTimezone: false)
問題
timezone と device_calendar を併用した所、アプリ起動時に タイムゾーン を Asia/Tokyo で初期化しているのに、他の場所でtz.local
にアクセスすると UTC になっていました。
/// タイムゾーン初期化処理
Future<void> _setupTimezones() async {
tz.initializeTimeZones();
final locationName = await FlutterTimezone.getLocalTimezone();
final location = tz.timeZoneDatabase.getLocation(locationName);
tz.setLocalLocation(location);
print('tz.local: ${tz.local}'); // tz.local: Asia/Tokyo
}
/// アプリ内のどこかの関数
void somePlace() {
print('tz.local: ${tz.local}'); // tz.local: UTC
}
原因
原因としては、DeviceCalendarPlugin
をshouldInitTimezone: true
で初期化すると、DeviceCalendarPlugin
内でも タイムゾーン の初期化が実行され、その際に tz.local
が UTC として初期化されてしまうことでした。
device_calendar.dart
factory DeviceCalendarPlugin({bool shouldInitTimezone = true}) {
if (shouldInitTimezone) {
tz.initializeTimeZones(); // <- ここでタイムゾーン初期化されtz.localがUTCに
}
return _instance;
}
https://github.com/builttoroam/device_calendar/blob/a6352f60480e8ff92bd058af52768d079a9c4cc1/lib/src/device_calendar.dart#L25-L30
解決策
DeviceCalendarPlugin を初期化する際に、shouldInitTimezone: false
として初期化しましょう。
final deviceCalendarPlugin = DeviceCalendarPlugin(shouldInitTimezone: false)
備考
グローバル変数はいつの間にか他から上書きされてしまうこともあり、やっぱり怖いですね、、
調査に意外と時間がかかったので、誰かにお役に立てれば幸いです 🙌
Discussion