Flutter时间管理插件chrono的使用
Flutter时间管理插件chrono的使用
概述
Chrono 是一个为 Dart 设计的时间包,支持所有平台。它提供了用于时间戳、时区无关(本地)日期和时间以及基于公历的不同持续时间的强类型数据类。
使用方法
由于 Dart 核心库也提供了名为 DateTime
和 Duration
的类,你可能需要手动添加 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
结合了 Date
和 Time
,但不包含时区信息。这在其他语言中也被称为普通或本地时间。
例如,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
)Hours
、Minutes
、Seconds
、Milliseconds
、Microseconds
、Nanoseconds
:整数小时等
DateDuration
:基于天和月的持续时间FixedDaysDuration
:基于天的持续时间,可以是Days
或Weeks
MonthsDuration
:基于月的持续时间,可以是Months
或Years
CompoundDaysDuration
:Months
+Days
CompoundDuration
:Months
+Days
+FractionalSeconds
Duration
类从 Dart 核心对应的是 TimeDuration
/FractionalSeconds
,但仅限于微秒精度。
一些持续时间类也有对应的 …Duration
类,例如 Minutes
和 MinutesDuration
。
MinutesDuration
是所有基于分钟的持续时间的抽象基类。
Minutes
是扩展 MinutesDuration
的具体类。
在构造或返回值时,你应该直接使用 Minutes
。
然而,在参数中,你应该接受任何 MinutesDuration
。
这样,调用者不仅可以传递 Minutes
,还可以传递 Hours
。
要将其转换为 Minutes
,请调用 asMinutes
混合持续时间
CompoundDuration
和 CompoundDaysDuration
可以表示具有混合符号的值,例如 -1个月和1天。
当使用混合持续时间进行加减运算时,首先计算 Months
,然后是 Days
,最后是 FractionalSeconds
。
例如,向2023年8月31日添加1个月和减去1天的结果是2023年9月29日:
-
首先,添加1个月,结果为2023年9月30日。 (九月只有30天,所以天数会被截断。)
-
然后,减去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
,你可以选择以下方法之一:
- 使用你想要使用的转换器注解字段:
@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);
}
- 在
JsonSerializable
注解中指定转换器,使其适用于该类的所有字段:
@JsonSerializable(converters: [DateTimeAsIsoStringJsonConverter()])
class MyClass {
// ...
}
- 创建一个可重用的
JsonSerializable
实例:
const jsonSerializable = JsonSerializable(converters: [DateTimeAsIsoStringJsonConverter()]);
[@jsonSerializable](/user/jsonSerializable)
class MyClass {
// ...
}
更多关于Flutter时间管理插件chrono的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于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),
),
],
),
),
);
}
}
注意:
- 上述代码中的
chrono
插件主要用于解析自然语言日期时间字符串,但在这个示例中,我们仅展示了基本的DateTime
格式化,因为直接格式化日期时间并不是chrono
的主要功能。chrono
更常用于从文本中解析出日期和时间信息。 chrono
插件在Flutter社区中的流行度和维护状态可能会有所不同,因此在实际项目中,请确保检查该插件的最新文档和社区支持情况。- 上述示例中实际上并未直接使用
chrono
的核心功能(解析自然语言日期时间),因为Flutter自带的DateTime
和intl
包已经能很好地处理基本的日期时间格式化。如果需要使用chrono
的解析功能,可以参考该插件的官方文档和示例代码。
由于chrono
在Flutter中的使用可能更多涉及到解析复杂的日期时间字符串,而不是简单的格式化,因此在实际应用中,你可能需要结合具体的业务需求来编写更复杂的代码。