You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中flutter_local_notifications时区异常:TZDateTime未用设备时区?

问题分析与解决

在真机测试flutter_local_notifications组件时,出现了时区名称显示为香港(Asia/Hong_Kong),但TZDateTime却使用UTC+0时区的异常情况,香港时区应为UTC+08:00,这明显不符合预期。

问题代码与输出

时区初始化代码

Future<void> _configureLocalTimeZone() async {
    tz.initializeTimeZones();
    final String timeZoneName = await FlutterTimezone.getLocalTimezone();
    print(timeZoneName);
    tz.setLocalLocation(tz.getLocation(timeZoneName));
}

初始化输出

I/flutter (28341): Asia/Hong_Kong

时区使用代码

tz.TZDateTime _nextInstanceOfTenAM() {
    final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
    print(tz.local);
    tz.TZDateTime scheduledDate = tz.TZDateTime(tz.local, now.year, now.month, now.day, now.hour,now.minute+1);
    print("called");
    if (scheduledDate.isBefore(now)) {
      scheduledDate = scheduledDate.add(const Duration(days: 1));
    }
    print(now.timeZoneName);
    print(now.timeZoneOffset);
    print(scheduledDate);
    return scheduledDate;
}

使用输出

I/flutter (22333): UTC
I/flutter (22333): 0:00:00.000000
I/flutter (22333): 2024-01-23 13:50:00.000Z

原因

核心问题是**tz.setLocalLocation没有生效**,从输出tz.local为UTC可以看出,_configureLocalTimeZone函数要么没有被执行,要么执行时机晚于_nextInstanceOfTenAM的调用,导致tz.local仍使用默认的UTC时区。

解决方法

  1. 确保时区初始化优先执行
    在使用tz.local之前,必须等待_configureLocalTimeZone执行完成。比如在main函数中初始化:

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await _configureLocalTimeZone();
      runApp(MyApp());
    }
    

    或者在页面的initState中异步初始化:

    @override
    void initState() {
      super.initState();
      _initApp();
    }
    
    Future<void> _initApp() async {
      await _configureLocalTimeZone();
      // 初始化完成后再调用时区相关逻辑,比如_nextInstanceOfTenAM
      _nextInstanceOfTenAM();
    }
    
  2. 验证初始化流程
    可以在_configureLocalTimeZone末尾添加打印,确认函数执行完成:

    Future<void> _configureLocalTimeZone() async {
        tz.initializeTimeZones();
        final String timeZoneName = await FlutterTimezone.getLocalTimezone();
        print(timeZoneName);
        tz.setLocalLocation(tz.getLocation(timeZoneName));
        print("时区初始化完成:${tz.local}"); // 新增打印
    }
    

    如果没有看到这条打印,说明函数未被调用,需要检查调用逻辑。

内容的提问来源于stack exchange,提问作者ZZZ iioo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:49:57