Flutter时间管理插件time_machine2的潜在功能使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter时间管理插件time_machine2的潜在功能使用

标题

Flutter时间管理插件time_machine2的潜在功能使用

内容

The Dart Time Machine is a date and time library for Flutter (native + web) and Dart with support for time zones, calendars, cultures, formatting and parsing.

Time Machine provides an alternative date and time API over Dart Core. Dart’s native time ande is too simplistic because it only knows UTC or local time with no clear definition of time zone and no safeguards ensuring that time stamps with and without UTC flag aren’t mixed up. This can easily lead to bugs if applications need to work in local time, because native Dart timestamps look the same after conversion. Applications that benefit from Time Machine are applications that need to perform tasks such as

  • scheduling reminders
  • displaying an object’s time information (file dates, email dates, calendar dates)
  • sharing data between users that work in different time zones But Time Machine is also useful for applications that work with universal timestamps only. Its Instant class provides nanosecond precision and fake clocks can be used during unit testing.

Time Machine API

  • Time - an amount of time with nanosecond precision
  • Instant - a unique point on the UTC timeline
  • LocalTime - the time on the clock
  • LocalDate - the date on the calendar
  • LocalDateTime - a location on the clock and calendar
  • Period - amount of time on the clock and calendar
  • Offset - the timezone offset from the UTC timeline
  • DateTimeZone - a mapping between the UTC timeline, and clock and calendar locations
  • ZonedDateTime - a unique point on the UTC timeline and a location on the clock and calendar
  • Culture - formatting and parsing rules specific to a locale

Time Machine’s Goals

  • Flexibility - multiple representations of time to fit different use cases
  • Consistency - works the same across all platforms
  • Testable - easy to test your date and time dependent code
  • Clarity - clear, concise, and intuitive
  • Easy - the library should do the hard things for you

The last two/three are generic library goals.

Time Machine is a port of Noda Time. The original version of this package was created by Dana Ferguson.

Example Code:

// 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 paris = await tzdb['Europe/Paris'];

var now = Instant.now();

print('Basic');
print('UTC Time: $now');
print('Local time: ${now.inLocalZone()}');
print('Paris time: ${now.inZone(paris)}\n');

print('Formatted');
print('UTC time: ${now.toString('dddd yyyy-MM-dd HH:mm')}`);
print('Local time: ${now.inLocalZone().toString('dddd yyyy-MM-dd HH:mm')}\n');

var french = await Cultures.getCulture('fr-FR');
print('Formatted and French ($french)');
print('UTC time: ${now.toString('dddd yyyy-MM-dd HH:mm', french)}');
print('Local time: ${now.inLocalZone().toString('dddd yyyy-MM-dd HH:mm', french)}\n');

print('Parse French Formatted ZonedDateTime');

// without the 'z' parsing will be forced to interpret the timezone as UTC
var localText = now
    .inLocalZone()
    .toString('dddd yyyy-MM-dd HH:mm z', french);

var localClone = ZonedDateTimePattern
    .createWithCulture('dddd yyyy-MM-dd HH:mm z', french)
    .parse(localText);

print(localClone.value);

Flutter specific notes

You’ll need this entry in your pubspec.yaml.

flutter:
  assets:
    - packages/time_machine2/data/cultures/cultures.bin
    - packages/time_machine2/data/tzdb/tzdb.tzf
    # If you explicitly override the TZDB variant to use, include one or both of the following assets.
    # Otherwise tzdb.tzf above is enough.
    - packages/time_machine2/data/tzdb/tzdb_common.tzf
    - packages/time_machine2/data/tzdb/tzdb_common_10y.tzf

Your initialization function will look like this:

import 'package:flutter/services.dart';
import 'package:time_machine2/time_machine2.dart';

WidgetsFlutterBinding.ensureInitialized();

// TimeMachine discovers your TimeZone heuristically (it's actually pretty fast).
await TimeMachine.initialize({'rootBundle': rootBundle});

Or with: 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(),
});

Migrating from the original timeine package

This project is forked from time_machine, the original repository seems to be abandoned. Since the original package couldn’t be adopted, this package had to be given a new name and is available as time_machine2. The following changes are required to migrate from the original package to the new package:

Change dependency in pubspec.yaml:

< time_machine: ^0.9.17
> time_machine2: ^0.10.1

Change import statements:

< import 'package:time_machine/time_machine.dart';
> import 'package:time_machine2/time_machine2.dart';
- import 'package:time_machine2/time_machine_text_patterns.dart'; 

The text pattern library has been merged into the main library for better visibility and to avoid too much clutter in the import statements.

Change of asset declarations in pubspec.yaml (only required for Flutter):

flutter:
  assets:
    - packages/time_machine2/data/cultures/cultures.bin
    - packages/time_machine2/data/tzdb/tzdb.tzf
    # If you explicitly override the TZDB variant to use, include one or both of the following assets.
    # Otherwise tzdb.tzf above is enough.
    - packages/time_machine2/data/tzdb/tzdb_common.tzf
    - packages/time_machine2/data/tzdb/tzdb_common_10y.tzf

Time Zone DB and Culture DB asset handling

Time Machine includes the IANA Time Zone Database and date/time patterns from Unicode CLDR. These assets are XZ compressed and have comparably small size (43kb for the full TZDB and 47kb for date/time patterns for all locales).

In order to work on all platforms seamlessly without requiring too much package-specific configuration, the following strategy is used:

  • Flutter Native: Assets must be listed in pubspec.yaml (see here) and will be bundled with the binary. TimeMachine.initialize() requires the application’s rootBundle as parameter.
  • Flutter Web: Assets must be listed in pubspec.yaml (see here) and will be retrieved through Flutter’s service worker. This will cause additional HTTP requests during TimeMachine.initialize(). The data might be cached by the service worker so that subsequent reloads of the application may load the assets from the cache. TimeMachine.initialize() requires the application’s rootBundle as parameter.
  • Dart only: Assets will be compiled to code and embedded directly into the binary. This increases the size of the binary slightly but makes the entire package self-contained without additional configuration.

Time Machine currently ships three versions of the time zone database:

  • tzdb (default, 43kb): from beginning of time until end of 2037
  • tzdb_common (40kb): includes most common locations, from beginning of time until end of 2037
  • tzdb_common_10y((12kb): includes most common locations, from 2019 to 2029)

The database can be selected by passing the database name to initialize:

TimeMachine.initialize({'tzdb': 'tzdb_common_10y'});

更多关于Flutter时间管理插件time_machine2的潜在功能使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter时间管理插件time_machine2的潜在功能使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,time_machine2 是一个强大的时间管理插件,它提供了丰富的API来处理日期和时间。以下是一些潜在功能的代码示例,展示了如何使用 time_machine2 来执行常见的日期和时间操作。

1. 初始化日期和时间

首先,你需要导入 time_machine2 包并初始化一个 LocalDateZonedDateTime 对象。

import 'package:time_machine2/time_machine.dart';

void main() {
  // 获取当前日期和时间
  var now = ZonedDateTime.now();
  print('当前时间: $now');

  // 创建一个特定的日期和时间
  var specificDate = LocalDate(2023, 10, 5);
  var specificTime = LocalDateTime(2023, 10, 5, 14, 30);
  var specificZonedDateTime = ZonedDateTime(specificTime, LocalDateTime.local().timeZone);
  print('特定日期: $specificDate');
  print('特定时间: $specificTime');
  print('特定时区时间: $specificZonedDateTime');
}

2. 日期和时间运算

你可以轻松地对日期和时间进行加减运算。

void main() {
  var now = ZonedDateTime.now();
  
  // 加7天
  var sevenDaysLater = now + Period(days: 7);
  print('7天后: $sevenDaysLater');

  // 减3小时
  var threeHoursAgo = now - Duration(hours: 3);
  print('3小时前: $threeHoursAgo');
}

3. 获取日期和时间的组成部分

你可以提取日期和时间的各个部分,如年、月、日、小时、分钟等。

void main() {
  var now = ZonedDateTime.now();
  
  int year = now.year;
  int month = now.month;
  int day = now.day;
  int hour = now.hour;
  int minute = now.minute;
  int second = now.second;

  print('年: $year');
  print('月: $month');
  print('日: $day');
  print('小时: $hour');
  print('分钟: $minute');
  print('秒: $second');
}

4. 日期和时间格式化与解析

time_machine2 提供了灵活的日期和时间格式化与解析功能。

void main() {
  var now = ZonedDateTime.now();
  
  // 格式化日期和时间
  var pattern = 'yyyy-MM-dd HH:mm:ss';
  String formatted = now.toString(pattern);
  print('格式化后的时间: $formatted');

  // 解析日期和时间
  var parsedDate = ZonedDateTimePattern.createWithCurrentCulture('yyyy-MM-dd HH:mm:ss').parse('2023-10-05 14:30:00');
  print('解析后的时间: $parsedDate');
}

5. 处理时区

time_machine2 支持轻松处理不同的时区。

void main() {
  var now = ZonedDateTime.now();
  
  // 转换到另一个时区
  var newYorkTimeZone = TimeZone.findSystemTimeZone('America/New_York')!;
  var newYorkTime = now.withZone(newYorkTimeZone);
  print('纽约时间: $newYorkTime');

  var tokyoTimeZone = TimeZone.findSystemTimeZone('Asia/Tokyo')!;
  var tokyoTime = now.withZone(tokyoTimeZone);
  print('东京时间: $tokyoTime');
}

6. 周期性任务

你可以使用 time_machine2 来处理周期性任务,例如每天、每周或每月的某个时间执行任务。

void main() {
  var now = ZonedDateTime.now();
  
  // 每天的某个时间
  var dailyTaskTime = now.withHourAndMinuteAndSecond(9, 0, 0);
  if (now.date == dailyTaskTime.date || now > dailyTaskTime) {
    dailyTaskTime = dailyTaskTime + Period(days: 1);
  }
  print('下次每日任务时间: $dailyTaskTime');

  // 每周的某个时间(例如每周一上午9点)
  var weeklyTaskTime = now.withDayOfWeekAndHourAndMinuteAndSecond(DayOfWeek.monday, 9, 0, 0);
  if (now < weeklyTaskTime && now.dayOfWeek != DayOfWeek.monday) {
    weeklyTaskTime = weeklyTaskTime - Period(weeks: 1);
  } else if (now.dayOfWeek == DayOfWeek.monday && now < weeklyTaskTime) {
    weeklyTaskTime = weeklyTaskTime;
  } else {
    weeklyTaskTime = weeklyTaskTime + Period(weeks: 1);
  }
  print('下次每周任务时间: $weeklyTaskTime');
}

这些代码示例展示了 time_machine2 插件的一些潜在功能,包括日期和时间的初始化、运算、组成部分提取、格式化与解析、时区处理以及周期性任务处理。通过这些功能,你可以轻松地在Flutter应用中实现复杂的时间管理需求。

回到顶部