logo-dtm

Dart Time Machine 是一个日期和时间库,适用于
FlutterWeb服务器
支持时区、日历、文化、格式化和解析。

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

selection_116

Flutter

selection_117

Web (Dart2JS 和 DDC)

selection_118

所有单元测试在 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 方法将不会传播 patternTextculture 参数。
InstantZonedDateTime 目前有 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 月下半月)中获得此修复。

GitHub

https://github.com/Davidlucas66/time_machine_3