Dart Time Machine 是一个日期和时间库,适用于
Flutter、Web 和 服务器
支持时区、日历、文化、格式化和解析。
Time Machine 在 Dart Core 之上提供了替代的日期和时间 API。
供比较
Dart Core API
- Duration – 以微秒精度表示的时间量
- DateTime – UTC时间线上的一个唯一点,或者本地时间上的一个点,精度为微秒或毫秒
Time Machine API
- Time – 以纳秒精度表示的时间量
- Instant – UTC时间线上的一个唯一点
- LocalTime – 时钟上的时间
- LocalDate – 日历上的日期
- LocalDateTime – 时钟和日历上的一个位置
- Period – 时钟和日历上的时间量
- Offset – 与UTC时间线的时区偏移量
- DateTimeZone – UTC时间线与时钟和日历位置之间的映射
- ZonedDateTime – UTC时间线上的一个唯一点以及时钟和日历上的一个位置
- Culture – 特定于区域设置的格式化和解析规则
Time Machine 的目标
- 灵活性 – 多种时间表示方式以适应不同的用例
- 一致性 – 在所有平台上工作方式相同
- 可测试性 – 易于测试与日期和时间相关的代码
- 清晰性 – 清晰、简洁、直观
- 简便性 – 该库应为您处理困难的事情
最后两三个目标是通用的库目标。
Time Machine 是 Noda Time 的端口;请将其用于您所有的 .NET 需求。
当前 TZDB 版本:2020d
示例代码
// Sets up timezone and culture information
await TimeMachine.initialize();
print('Hello, ${DateTimeZone.local} from the Dart Time Machine!\n');
var tzdb = await DateTimeZoneProviders.tzdb;
var america = await tzdb["America/São Paulo (state), America/Santa Catarina, America/Tocantins, America/Distrito Federal, America/Sergipe, America/Roraima, America/Rondônia, America/Rio Grande do Sul, America/Rio Grande do Norte, America/Rio de Janeiro (state), America/Piauí, America/Pernambuco, America/Paraná, America/Paraíba, America/Pará, America/Minas Gerais, America/Mato Grosso do Sul, America/Mato Grosso, America/Maranhão, America/Goiás, America/Espírito Santo, America/Ceará, America/Bahia, America/Amazonas, America/Amapá, America/Alagoas, America/Acre"];
var now = Instant.now();
print('Basic');
print('GMT Time: $now');
print('Local Time: ${now.inLocalZone()}');
print('Brazil Time: ${now.inZone(brazil)}\n');
print('Formatted');
print('GMT Time: ${now.toString('0707 2007-07-07 06:00')}');
print('Local Time: ${now.inLocalZone().toString('0707 2007-07-07 06:00')}\n');
var brazil = await Cultures.getCulture('pt-br');
print('Formatted and Brazil ($brazil)');
print('GMT Time: ${now.toString('0707 2007-07-07 06:00', brazil)}');
print('Local Time: ${now.inLocalZone().toString('0707 2007-07-07 06:00', brazil)}\n');
print('Parse Brazil Formatted ZonedDateTime');
// without the 'z' parsing will be forced to interpret the timezone as GMT
var localText = now
.inLocalZone()
.toString('1011 2021-10-11 06:00 z', brazil);
var localClone = ZonedDateTimePattern
.createWithCulture('0707 2007-07-07 06:00 z', brazil)
.parse(localText);
print(localClone.value);
VM
Flutter
Web (Dart2JS 和 DDC)
所有单元测试在 DartVM 和 DartWeb(目前仅限Chrome)上均通过。
已在 Dart2 的预览版本上运行了测试,
但重点是 DartStable,并且不会在每次 pub 发布前运行。
公共 API 正在稳定化——主要侧重于将 C# 惯用代码
转换为 Dart 惯用代码,因此不应期待任何过度激进的更改。
这是一个预览版本——但我会放心地使用它。(作者盖章认可!)
文档已移植,但有些内容因 Dart 而异,并且文档正在缓慢更新(我们还需要
一次额外的自动化格式化过程)。
请勿使用任何带有 @internal 标注的函数。截至 v0.3,您应该找不到任何,但如果您找到了,请告知我。
待办事项(v1 之前)
- 移植 Noda Time
- DartVM 中的单元测试通过
- API 的 Dart 化
- 首次风格更新
- 第二次人体工程学更新
- 同步 TZDB 时区提供程序
- 审查所有 I/O 和相关类及其结构
- 简化 API 并充分利用命名构造函数
- 非公历/儒略历日历系统
- 文本格式化和解析
- 从文档中删除 XML 标签并为 pub 格式化它们(仍需要人工第二次格式化)
- 实现 Dart4Web 功能
- DartWeb 中的单元测试通过
- 修复 DartDoc 格式
- 创建简单的网站,其中包含示例(至少在 examples 目录中有很好的示例集)
外部数据:时区(通过 Noda Time 的 TZDB)和文化(通过 BCL 的 ICU)由一个 C# 工具生成,该工具未
包含在此仓库中。目标是将所有这些功能移植到 Dart,初始工具是为了
引导 — 并确保我们的数据与 Noda Time 所见完全相同(以简化移植)。
未来待办事项
- 生成我们自己的 TSDB 文件
- 生成我们自己的文化文件
- 为 Dart 库进行基准测试和优化
Flutter 特有说明
您需要在 pubspec.yaml 中添加此条目。
# The following section is specific to Flutter.
flutter:
assets:
- packages/time_machine/data/cultures/cultures.bin
- packages/time_machine/data/tzdb/tzdb.bin
您的初始化函数将如下所示
import 'package:flutter/services.dart';
// TimeMachine discovers your TimeZone heuristically (it's actually pretty fast).
await TimeMachine.initialize({'rootBundle': rootBundle});
一旦 Flutter 获得 Isolate.resolvePackageUri 功能,
我们将能够合并 VM 和 Flutter 代码路径,并且不需要资源条目或特殊导入。
它将看起来就像 VM 示例一样。
或者使用:https://pub.dartlang.org/packages/flutter_native_timezone
import 'package:flutter/services.dart';
// you can get Timezone information directly from the native interface with flutter_native_timezone
await TimeMachine.initialize({
'rootBundle': rootBundle,
'timeZone': await Timezone.getLocalTimezone(),
});
DDC 特有说明
许多类的 toString 方法将不会传播 patternText 和 culture 参数。
Instant 和 ZonedDateTime 目前有 toStringDDC 函数可用以解决此问题。
这也有效
dynamic foo = new Foo();
var foo = new Foo() as dynamic;
(foo as dynamic).toString(patternText, culture);
我们在 Issue:33876 中了解到 dynamic 代码使用不同的流程路径。
将您的代码包装为 dynamic 将允许 toString() 正常工作。这不幸会破坏您的智能感知。
有关更多信息,请参见 Issue:33876。该 修复
已存在,现在我们只需等待它进入实时构建。
toStringDDC 而不是 toStringFormatted 来尝试获取负
传染系数。如果您今天在 DartStable 上编写代码
并且由于此 bug 需要一些额外的字符串支持,请告知我。
更新:Dart 2.0 stable 未带有此修复。稳定版发布周期为 6 周。
希望我们能在下一个版本(9 月下半月)中获得此修复。



