Flutter时间管理插件chrono的使用

Flutter时间管理插件chrono的使用

概述

Chrono 是一个为 Dart 设计的时间包,支持所有平台。它提供了用于时间戳、时区无关(本地)日期和时间以及基于公历的不同持续时间的强类型数据类。

使用方法

由于 Dart 核心库也提供了名为 DateTimeDuration 的类,你可能需要手动添加 import 'package:chrono/chrono.dart';。如果你希望同时使用这两个来源的类,可以使用导入前缀:

import 'dart:core' as core;
import 'package:chrono/chrono.dart';

void main() {
  final dartCoreDateTime = core.DateTime.now();
  final chronoDateTime = DateTime.nowInLocalZone();
}

时间戳

时间戳是一个唯一的 UTC 时间线上的点,存储为自 Unix 纪元以来的持续时间。Chrono 提供了以下类:

  • UnixEpochTimestamp<D>:泛型基于 TimeDuration 类型
    • Instant:任意精度的子类
    • UnixEpochNanoseconds:纳秒精度的子类
    • UnixEpochMicroseconds:微秒精度的子类
    • UnixEpochMilliseconds:毫秒精度的子类
    • UnixEpochSeconds:秒精度的子类

如果你想存储某个事件发生的确切时间点(例如,聊天应用中的消息发送时间),这些类通常是最佳选择。具体选择哪个类取决于你需要的精度。

过去的时间(如生日)应该用 Date 表示。未来的日期(如安排会议的时间)应该用 DateTime 和相应的时区表示。

日期和时间

DateTime 结合了 DateTime,但不包含时区信息。这在其他语言中也被称为普通或本地时间。

例如,2023年4月23日18:24:20在不同的时区发生的时间不同。在 Chrono 的类中,它将被表示为:

类名 编码
DateTime 2023-04-23T18:24:20
Date 2023-04-23
Year 2023
Month 4
YearMonth 2023-04
MonthDay --04-23
OrdinalDate 2023-113
WeekDate 2023-W16-7
YearWeek 2023-W16
Weekday 7
Time 18:24:20

📅 Date 类

Date 是没有时区信息的 ISO 8601 日历日期,例如2023年4月23日。

日期可以用三种不同的类表示:

类名 组件 转换 编码
Date Year + Month + 月中的天数 .asDate 2023-04-23
WeekDate YearWeek + Weekday .asWeekDate 2023-W16-7
OrdinalDate Year + 年中的天数 .asOrdinalDate 2023-113

⌚ Time 类

Time 是没有时区信息的 ISO 8601 时间,例如18:24:20.123456。

由于小数秒使用 Fixed 类表示,因此精度基本上没有限制。

Chrono 不支持闰秒: 它假设所有的分钟都是60秒长。

持续时间

持续时间分为三类:

  • 基于时间的持续时间,例如1小时
  • 基于天的持续时间,例如2天
  • 基于月的持续时间,例如3个月

一天并不总是24小时长(由于夏令时的变化),一个月也不总是30/31天长(由于闰年和不同的月份长度)。Chrono 提供了每个类别的不同类(按继承顺序列出):

  • Duration:抽象基类
    • TimeDuration:基于时间的持续时间:小时、分钟、秒等。
      • FractionalSeconds:无限精度的小数秒(使用 Fixed
      • HoursMinutesSecondsMillisecondsMicrosecondsNanoseconds:整数小时等
    • DateDuration:基于天和月的持续时间
      • FixedDaysDuration:基于天的持续时间,可以是 DaysWeeks
      • MonthsDuration:基于月的持续时间,可以是 MonthsYears
      • CompoundDaysDurationMonths + Days
    • CompoundDurationMonths + Days + FractionalSeconds

Duration 类从 Dart 核心对应的是 TimeDuration/FractionalSeconds,但仅限于微秒精度。

一些持续时间类也有对应的 …Duration 类,例如 MinutesMinutesDurationMinutesDuration 是所有基于分钟的持续时间的抽象基类。 Minutes 是扩展 MinutesDuration 的具体类。 在构造或返回值时,你应该直接使用 Minutes。 然而,在参数中,你应该接受任何 MinutesDuration。 这样,调用者不仅可以传递 Minutes,还可以传递 Hours。 要将其转换为 Minutes,请调用 asMinutes

混合持续时间

CompoundDurationCompoundDaysDuration 可以表示具有混合符号的值,例如 -1个月和1天。

当使用混合持续时间进行加减运算时,首先计算 Months,然后是 Days,最后是 FractionalSeconds。 例如,向2023年8月31日添加1个月和减去1天的结果是2023年9月29日:

  1. 首先,添加1个月,结果为2023年9月30日。 (九月只有30天,所以天数会被截断。)

  2. 然后,减去1天,结果为2023年9月29日。

(如果操作顺序相反,结果将是2023年9月30日。)

序列化

所有时间戳、日期和时间类都支持 JSON 序列化。(未来会添加对持续时间的支持。)

由于存在多种编码方式,Chrono 允许你选择格式: 对于每个类都有一个 JsonConverter 子类,命名为 <Chrono 类型>As<JSON 类型>JsonConverter,例如 DateTimeAsIsoStringJsonConverter。 这些转换器如何编码2001年2月3日4:05:06.007008009 UTC:

转换器类 编码示例
InstantAsIsoStringJsonConverter "2001-02-03T04:05:06.007008009Z"
UnixEpochNanosecondsAsIsoStringJsonConverter "2001-02-03T04:05:06.007008009Z"
UnixEpochNanosecondsAsIntJsonConverter 981173106007008009
UnixEpochMicrosecondsAsIsoStringJsonConverter "2001-02-03T04:05:06.007008Z"
UnixEpochMicrosecondsAsIntJsonConverter 981173106007008
UnixEpochMillisecondsAsIsoStringJsonConverter "2001-02-03T04:05:06.007Z"
UnixEpochMillisecondsAsIntJsonConverter 981173106007
UnixEpochSecondsAsIsoStringJsonConverter "2001-02-03T04:05:06Z"
UnixEpochSecondsAsIntJsonConverter 981173106
DateTimeAsIsoStringJsonConverter "2001-02-03T04:05:06.007"
DateAsIsoStringJsonConverter "2001-02-03"
YearAsIsoStringJsonConverter "2001"
YearAsIntJsonConverter 2001
MonthAsIntJsonConverter 2
YearMonthAsIsoStringJsonConverter "2001-02"
MonthDayAsIsoStringJsonConverter "--02-03"
OrdinalDateAsIsoStringJsonConverter "2001-034"
WeekDateAsIsoStringJsonConverter "2001-W05-6"
YearWeekAsIsoStringJsonConverter "2001-W05"
WeekdayAsIntJsonConverter 6
TimeAsIsoStringJsonConverter "04:05:06.007"

json_serializable

如果你使用 json_serializable,你可以选择以下方法之一:

  1. 使用你想要使用的转换器注解字段:
@JsonSerializable()
class MyClass {
  const MyClass(this.value);

  factory MyClass.fromJson(Map<String, dynamic> json) => _$MyClassFromJson(json);

  @DateTimeAsIsoStringJsonConverter()
  final DateTime value;

  Map<String, dynamic> toJson() => _$MyClassToJson(this);
}
  1. JsonSerializable 注解中指定转换器,使其适用于该类的所有字段:
@JsonSerializable(converters: [DateTimeAsIsoStringJsonConverter()])
class MyClass {
  // ...
}
  1. 创建一个可重用的 JsonSerializable 实例:
const jsonSerializable = JsonSerializable(converters: [DateTimeAsIsoStringJsonConverter()]);

[@jsonSerializable](/user/jsonSerializable)
class MyClass {
  // ...
}

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

1 回复

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


当然,关于Flutter时间管理插件chrono的使用,这里是一个简单的示例代码案例,演示如何在Flutter应用中集成并使用chrono插件来进行时间管理。

首先,确保你已经在pubspec.yaml文件中添加了chrono依赖:

dependencies:
  flutter:
    sdk: flutter
  chrono: ^latest_version  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

接下来是一个简单的示例代码,展示如何在Flutter中使用chrono插件。在这个示例中,我们将使用chrono来格式化日期和时间。

import 'package:flutter/material.dart';
import 'package:chrono/chrono.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Chrono Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChronoExamplePage(),
    );
  }
}

class ChronoExamplePage extends StatefulWidget {
  @override
  _ChronoExamplePageState createState() => _ChronoExamplePageState();
}

class _ChronoExamplePageState extends State<ChronoExamplePage> {
  String formattedDateTime = '';

  @override
  void initState() {
    super.initState();
    // 获取当前时间并格式化
    DateTime now = DateTime.now();
    formattedDateTime = formatDateTime(now);
  }

  String formatDateTime(DateTime dateTime) {
    // 使用chrono的DateParser来解析(虽然这里我们直接格式化了,但chrono可以用于解析复杂的日期时间字符串)
    // 这里我们仅展示基本的DateTime格式化,chrono更强大的功能在于解析自然语言日期时间
    return DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Chrono Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Current Formatted Date and Time:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 10),
            Text(
              formattedDateTime,
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
          ],
        ),
      ),
    );
  }
}

注意

  1. 上述代码中的chrono插件主要用于解析自然语言日期时间字符串,但在这个示例中,我们仅展示了基本的DateTime格式化,因为直接格式化日期时间并不是chrono的主要功能。chrono更常用于从文本中解析出日期和时间信息。
  2. chrono插件在Flutter社区中的流行度和维护状态可能会有所不同,因此在实际项目中,请确保检查该插件的最新文档和社区支持情况。
  3. 上述示例中实际上并未直接使用chrono的核心功能(解析自然语言日期时间),因为Flutter自带的DateTimeintl包已经能很好地处理基本的日期时间格式化。如果需要使用chrono的解析功能,可以参考该插件的官方文档和示例代码。

由于chrono在Flutter中的使用可能更多涉及到解析复杂的日期时间字符串,而不是简单的格式化,因此在实际应用中,你可能需要结合具体的业务需求来编写更复杂的代码。

回到顶部