如何在抖动中将DateTime转换为TZDateTime?

问题描述

我正在尝试使用Flutter_local_notifications包通过我的应用程序推送本地通知,并且像在FlutterNotificationsPlugin上一样,不建议使用“ .schedule”,但我尝试使用“ .zonedSchedule”,但它需要TZDateTime值。

var androidDetails = AndroidNotificationDetails(t.id,"Task Notifier","Notifies if you have a task scheduled at a particular time");
    var generalNotificationDetails =
        NotificationDetails(android: androidDetails);
    var Now = DateTime.Now();
    var scheduledTime = DateTime(
            Now.year,Now.month,_dayTasks.date.day,t.time.hour,t.time.minute)
        .subtract(Duration(minutes: 5));
    //use zonedSchedule once you figure out how to convert datetime to TZdatetime
    // await notifications.zonedSchedule(
    //     0,"Task",t.description,scheduledTime,generalNotificationDetails,//     androidAllowWhileIdle: true,//     uilocalnotificationDateInterpretation:
    //         UIlocalnotificationDateInterpretation.wallClockTime);
    await notifications.schedule(0,"Ideal Day Task",generalNotificationDetails);

解决方法

实际上,zonedSchedule()需要TZDateTime值。我采用的方法是利用另一个包将原始DateTime值转换为TZDateTime值。以下是我使用的一种实现的摘录。看到第五行?它涉及到函数TZDateTime.from()。它会使用您最初使用的DateTime并将其转换为TZDateTime。但是,它需要您当前的位置。那就是类TimeZone的所在。

    import 'package:timezone/timezone.dart' as tz;
    :
    :
    :

    final timeZone = TimeZone();

    // The device's timezone.
    String timeZoneName = await timeZone.getTimeZoneName();

    // Find the 'current location'
    final location = await timeZone.getLocation(timeZoneName);

    final scheduledDate = tz.TZDateTime.from(dateTime,location);

    try {
      await _flutterLocalNotificationsPlugin.zonedSchedule(
        id,title,body,scheduledDate,platformChannelSpecifics,androidAllowWhileIdle: androidAllowWhileIdle,payload: payload,uiLocalNotificationDateInterpretation:
            uiLocalNotificationDateInterpretation,);
    } catch (ex) {
      id = -1;
    }
    return id;

我很快编写了TimeZone类。此类与另一个插件(flutter_native_timezone)配合使用,该插件可查找设备的“当前位置”并提供该语言环境的标准名称:

import 'package:timezone/data/latest.dart';
import 'package:timezone/timezone.dart' as t;
import 'package:flutter_native_timezone/flutter_native_timezone.dart';

class TimeZone {
  factory TimeZone() => _this ?? TimeZone._();

  TimeZone._() {
    initializeTimeZones();
  }
  static TimeZone _this;

  Future<String> getTimeZoneName() async => FlutterNativeTimezone.getLocalTimezone();

  Future<t.Location> getLocation([String timeZoneName]) async {
    if(timeZoneName == null || timeZoneName.isEmpty){
      timeZoneName = await getTimeZoneName();
    }
    return t.getLocation(timeZoneName);
  }
}

使用该课程,你很好。

,

我刚刚尝试解决相同的问题。要了解这一点,我们需要对平台渠道有基本的了解。

https://flutter.dev/docs/development/platform-integration/platform-channels?tab=android-channel-kotlin-tab

一旦我们了解了这一点,示例中的代码将变得更加易于理解: https://github.com/MaikuB/flutter_local_notifications/blob/1fe78b9d129d674cd97cfba49734577b24c56925/flutter_local_notifications/example/android/app/src/main/java/com/dexterous/flutterlocalnotificationsexample/MainActivity.java

实际概念:

首先,我们将需要像这样导入tz。这可以在您的main.dart或帮助文件中完成。

import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;

要从简单的dateTime创建TZDateTime,我们将需要通过平台渠道查询设备时区。

Future<void> configureLocalTimeZone() async {
  tz.initializeTimeZones();
  final String timeZoneName = await platform.invokeMethod('getTimeZoneName');
  tz.setLocalLocation(tz.getLocation(timeZoneName));
}

在特定于平台的实现中实现getTimeZoneName的地方。

请务必在下一步之前致电configureLocalTimeZone

当我们想从TZDateTime对象创建DateTime时,我们通常可以这样做

var time = tz.TZDateTime.from(
    scheduledNotificationDateTime,tz.local,);

完整的实现在以下示例代码中进行了展示: https://github.com/MaikuB/flutter_local_notifications/blob/1fe78b9d129d674cd97cfba49734577b24c56925/flutter_local_notifications/example/lib/main.dart

在我非常简单的工作流程(YMMV)中,我没有考虑过不同的情况。 希望这可以帮助! :)

,

我也遇到了同样的问题并试图找到解决方案,但有些解决方案要么已经过时,要么正在使用不同的软件包。 zonedSchedule() 函数需要 TZDateTime。所以我们可以

Duration offsetTime= DateTime.now().timeZoneOffset;

这将为我们提供您的机器时间和 UTC 之间的差异,然后我们将从本地时间(默认为 UTC)中减去它

import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz; 
.
.
.
Future initializetimezone() async {
    tz.initializeTimeZones();
  }

Future<void> scheduleNotification()async{
await initializetimezone();
var androidChannel = AndroidNotificationDetails(
      'App',"Notifications",'Customize',importance: Importance.max,priority: Priority.high,playSound: true,enableLights: true,ongoing: false,visibility: NotificationVisibility.public,);
var iosChannel = IOSNotificationDetails();
var platfromChannel =
    NotificationDetails(android: androidChannel,iOS: iosChannel);
// year,month,etc can manually entered or you can use 
// DateTime.now() also for current time in local machine.
tz.TZDateTime zonedTime = tz.TZDateTime.local(year,day,hour,minute).subtract(offsetTime);
 await flutterLocalNotificationsPlugin.zonedSchedule(
      0,'Some Notification','Description',zonedTime,platfromChannel,uiLocalNotificationDateInterpretation:
          UILocalNotificationDateInterpretation.absoluteTime,payload: 'Payload',androidAllowWhileIdle: true,);
}

我希望这会有所帮助。当 UTC 和本地机器之间的时差为正值 (+5:30:00.000000) 时,这对我有用,我不确定负时差国家/地区。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...