Flutter 鸿蒙 timezone_provider 1.1.0 使用实战:读取系统 IANA 时区
本文用
timezone_provider 1.1.0在 Flutter 鸿蒙应用中读取当前系统的 IANA
时区标识,并以日历和服务端时间换算场景为例说明刷新、异常和数据存储方式。三方库仓库: https://atomgit.com/oh-flutter/timezone_provider
本文锁定版本:
9c7a14425b5814c820a12cdfa0999c6fabf7fa69完整 Demo: timezone_provider/example(受测提交)
一、最终真机效果

图 1:CHZ-AL00 / HarmonyOS 7.0.0.105 上读取到当前 IANA 时区 Asia/Shanghai。


真机验证从 Asia/Shanghai 切换到大阪对应的 Asia/Tokyo,再恢复 Asia/Shanghai 和自动时区设置。插件每次刷新都读取系统当前值,没有缓存旧结果,也不会修改系统设置。
| 验证点 | 实测结果 |
|---|---|
| 初始读取 | Asia/Shanghai |
| 修改系统时区后刷新 | Asia/Tokyo |
| 恢复系统设置后刷新 | Asia/Shanghai |
| 权限 | 无需新增权限 |
| 自动化与构建 | 7 项 Dart/Widget 测试、静态分析和 HAP 构建通过 |
二、为什么要保存 IANA 标识
UTC+8 只描述某个时刻的偏移,不能唯一表示地区规则。上海和其他区域可能在当前时刻偏移相同,但历史规则、夏令时和未来政策并不一定一致。日历事件、航班时间和跨地区预约应保存 Asia/Shanghai 这类 IANA ID,并配合可靠的时区数据库换算。
这个库只提供“按请求读取”。它适合应用启动、页面恢复或用户点击刷新时获取当前值;如果业务必须实时收到系统时区变化,应使用 flutter_timezone_observer。不要用定时器高频轮询这个简单读取接口。
三、环境与依赖
| 组件 | 实测版本 |
|---|---|
| Flutter OH | 3.41.10-ohos-1.0.1 |
| Dart | 3.11.5 |
| DevEco Studio | 26.0.0 Release |
| HarmonyOS SDK | API 26,示例兼容 API 18 |
| 测试设备 | CHZ-AL00 / HarmonyOS 7.0.0.105 |
| timezone_provider | 1.1.0 / 上述受测提交 |
3.44.9+ohos-0.0.1-canary1 是预览标签,本文没有用它完成同等回归。OHOS 适配尚无稳定 TAG,所以使用完整提交:
dependencies:
timezone_provider:
git:
url: https://atomgit.com/oh-flutter/timezone_provider.git
ref: 9c7a14425b5814c820a12cdfa0999c6fabf7fa69
flutter pub get
请在 pubspec.lock 核对 resolved-ref,不要只看到 pub get 成功就认为版本已经固定。本库读取公开系统国际化数据,不需要修改 module.json5 权限。

图 2:AtomGit 适配分支、仓库来源与当前 HEAD。
四、核心 API
公共 API 只有一个,返回非空 String:
import 'package:timezone_provider/timezone_provider.dart';
final provider = TimezoneProvider();
final String timezone = await provider.getTimezone();
// 示例:Asia/Shanghai
平台读取失败时会抛出 PlatformException。业务不应把失败静默替换成 UTC,否则日志和预约时间会在表面正常的情况下被错误换算。更稳妥的做法是保留上一次成功值,同时明确标记本次刷新失败,并允许用户重试。
五、带并发保护的页面写法
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:timezone_provider/timezone_provider.dart';
class TimezonePage extends StatefulWidget {
const TimezonePage({super.key});
State<TimezonePage> createState() => _TimezonePageState();
}
class _TimezonePageState extends State<TimezonePage>
with WidgetsBindingObserver {
final _provider = TimezoneProvider();
String? _timezone;
String? _error;
bool _loading = false;
int _requestId = 0;
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_refresh();
}
Future<void> _refresh() async {
final requestId = ++_requestId;
setState(() {
_loading = true;
_error = null;
});
try {
final value = await _provider.getTimezone();
if (!mounted || requestId != _requestId) return;
setState(() => _timezone = value);
} on PlatformException catch (error) {
if (!mounted || requestId != _requestId) return;
setState(() => _error = '${error.code}: ${error.message ?? '读取失败'}');
} finally {
if (mounted && requestId == _requestId) {
setState(() => _loading = false);
}
}
}
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) _refresh();
}
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('当前时区'),
actions: [
IconButton(
tooltip: '刷新',
onPressed: _loading ? null : _refresh,
icon: const Icon(Icons.refresh),
),
],
),
body: Center(
child: _loading
? const CircularProgressIndicator()
: Text(_error ?? _timezone ?? '暂无数据'),
),
);
}
页面从系统设置回到前台时会刷新。requestId 防止较早发起、较晚返回的请求覆盖最新结果;mounted 则避免页面销毁后调用 setState。
拿到 IANA ID 后,可以把它连同事件的 UTC 时间一起传给服务端。不要只上传本地格式化文本,也不要把面向用户的“上海时间”当作协议字段。

图 3:getTimezone 经 LocalizationKit 返回系统 IANA ID。
六、测试、构建与真机流程
flutter analyze
flutter test
cd example
flutter test
flutter build hap --debug --no-codesign

图 4:7 项 Dart/Widget 测试与静态检查通过。

图 5:HAP 构建结果和真机宿主锁定提交。

图 6:Asia/Shanghai -> Asia/Tokyo -> Asia/Shanghai 的真实读取和设置恢复记录。
验证时应由用户在系统设置中修改时区,回到应用后主动刷新。城市名称只是设置界面的入口,最终断言应比较插件返回的 IANA ID。本文未把系统设置写入能力算作库功能,因为该库根本不负责修改时区。
七、常见问题
Q1:为什么返回 Asia/Shanghai,不是 GMT+08:00
这是预期结果。IANA ID 能表达地区规则,固定偏移不能完整替代它。
Q2:系统时区变了,页面为什么没有自动更新
本库没有事件流。页面恢复或用户刷新时再次调用 getTimezone();实时监听请使用时区观察库。
Q3:读取失败后能否默认使用 UTC
可以由业务明确选择降级,但必须保留失败状态并提示用户。插件不会把系统异常伪装成真实 UTC 配置。
八、总结
timezone_provider 适合用一个小而明确的 API 读取当前 IANA 时区。本文已验证上海、东京和设置恢复三段流程。项目接入时固定受测 SHA,在页面恢复时刷新,读取失败时不要伪造默认值;需要变化事件时再选用观察型插件。
九、参考链接
欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter
更多推荐


所有评论(0)