Dart Duration 类
最后修改于 2025 年 5 月 25 日
Dart 中的 Duration 类表示一个时间间隔,广泛用于测量时间跨度、调度任务和执行基于时间的计算。本教程将探讨 Dart 应用程序中 Duration 类的创建、操作和应用。
Duration 概述
Duration 类是 Dart 核心库的一部分,它提供了一种精确的机制来表示天、小时、分钟、秒、毫秒和微秒等单位的时间间隔。它对于计算时间差、调度事件和管理异步操作中的延迟等任务至关重要。
该类经常与 DateTime 一起使用,用于计算时间戳之间的间隔、调度未来事件或引入延迟。作为一个不可变类,Duration 确保任何修改都会创建一个新实例,从而提高基于时间的操作的安全性与可预测性。
| 功能 | 描述 | 示例 |
|---|---|---|
| 创建 | 使用不同的时间单位定义持续时间 | Duration(hours: 2) |
| 属性(Properties) | 访问不同的时间分量 | duration.inMinutes |
| 算术运算 | 执行加、减或缩放操作 | duration1 + duration2 |
| 比较 | 使用关系运算符比较持续时间 | duration1 > duration2 |
| 格式化 | 将持续时间转换为可读字符串 | duration.toString() |
| 计时器 | 在异步操作中使用持续时间 | Future.delayed(Duration(seconds: 5)) |
Duration 类的不可变性确保其值在创建后不会改变,加法、减法和乘法等操作会生成新实例。这种设计通过防止意外修改来提高可靠性并简化调试。Duration 的一个关键应用是异步编程,它通过 Future.delayed(Duration(...)) 促进延迟,从而实现对时间敏感型操作的精确控制。
创建 Duration
Duration 类允许开发人员使用不同的单位(如天、小时、分钟、秒、毫秒和微秒)来定义时间间隔。所有构造函数参数都是可选的,默认为零,为指定持续时间提供了灵活性。支持负值,持续时间在内部存储为微秒,最大范围为 ±263 - 1 微秒。
void main() {
// Different ways to create durations
Duration hours = Duration(hours: 2);
Duration minutes = Duration(minutes: 30);
Duration seconds = Duration(seconds: 45);
Duration ms = Duration(milliseconds: 500);
Duration us = Duration(microseconds: 1000);
// Combined units
Duration complex = Duration(
days: 1,
hours: 3,
minutes: 15,
seconds: 30,
milliseconds: 500,
microseconds: 250
);
print('2 hours: $hours');
print('30 minutes: $minutes');
print('45 seconds: $seconds');
print('500ms: $ms');
print('1000μs: $us');
print('Complex duration: $complex');
}
此示例说明了如何使用从小时到微秒的不同时间单位创建持续时间,并展示了结合多个单位的复杂持续时间。
$ dart run duration_creation.dart 2 hours: 2:00:00.000000 30 minutes: 0:30:00.000000 45 seconds: 0:00:45.000000 500ms: 0:00:00.500000 1000μs: 0:00:00.001000 Complex duration: 27:15:30.500250
Duration 属性
Duration 类提供了属性来访问不同单位的时间间隔,例如 inDays、inHours、inMinutes、inSeconds、inMilliseconds 和 inMicroseconds。这些属性以指定的单位返回总持续时间。
由于没有直接访问单个组件(例如一天中的小时)的属性,开发人员可以使用模运算来提取特定组件。对于负持续时间,这些属性会返回负值,从而在计算中保持一致性。
void main() {
Duration duration = Duration(
days: 1,
hours: 2,
minutes: 30,
seconds: 45,
milliseconds: 500,
microseconds: 250
);
print('In days: ${duration.inDays}');
print('In hours: ${duration.inHours}');
print('In minutes: ${duration.inMinutes}');
print('In seconds: ${duration.inSeconds}');
print('In milliseconds: ${duration.inMilliseconds}');
print('In microseconds: ${duration.inMicroseconds}');
// Individual components
print('Days component: ${duration.inDays}');
print('Hours component: ${duration.inHours % 24}');
print('Minutes component: ${duration.inMinutes % 60}');
print('Seconds component: ${duration.inSeconds % 60}');
print('Milliseconds component: ${duration.inMilliseconds % 1000}');
print('Microseconds component: ${duration.inMicroseconds % 1000}');
}
此示例演示了如何访问持续时间属性并使用模运算提取单个组件。
$ dart run duration_properties.dart In days: 1 In hours: 26 In minutes: 1590 In seconds: 95445 In milliseconds: 95445500 In microseconds: 95445500250 Days component: 1 Hours component: 2 Minutes component: 30 Seconds component: 45 Milliseconds component: 500 Microseconds component: 250
Duration 算术运算
Duration 类支持算术运算,如加法、减法、乘法、取反和绝对值计算。加法组合两个持续时间,减法计算它们的差值,乘法将持续时间乘以一个整数。取反会反转持续时间的符号,abs 方法返回绝对值。除法(返回 double 而非 Duration)可用于计算持续时间之间的比率。
void main() {
Duration d1 = Duration(hours: 2, minutes: 30);
Duration d2 = Duration(minutes: 45);
// Addition
Duration sum = d1 + d2;
print('Sum: $sum');
// Subtraction
Duration diff = d1 - d2;
print('Difference: $diff');
// Multiplication
Duration multiplied = d1 * 3;
print('Multiplied: $multiplied');
// Division (returns double)
double ratio = d1.inMinutes / d2.inMinutes;
print('Ratio: $ratio');
// Negation
Duration negative = -d1;
print('Negative: $negative');
// Absolute value
Duration absValue = negative.abs();
print('Absolute: $absValue');
}
此示例演示了持续时间上的算术运算,展示了加法、减法、乘法、除法、取反和绝对值计算。
$ dart run duration_arithmetic.dart Sum: 3:15:00.000000 Difference: 1:45:00.000000 Multiplied: 7:30:00.000000 Ratio: 3.3333333333333335 Negative: -2:30:00.000000 Absolute: 2:30:00.000000
比较 Duration
Duration 类允许使用标准运算符(如 ==、<、>、<= 和 >=)以及 compareTo 方法进行比较。compareTo 方法根据持续时间是小于、等于还是大于另一个持续时间,返回 -1、0 或 1。比较基于总微秒数,负持续时间被认为小于正持续时间,从而确保了结果的一致性和直观性。
void main() {
Duration short = Duration(minutes: 5);
Duration medium = Duration(minutes: 15);
Duration long = Duration(hours: 1);
print('short == medium: ${short == medium}');
print('short < medium: ${short < medium}');
print('medium > long: ${medium > long}');
print('short <= medium: ${short <= medium}');
print('long >= medium: ${long >= medium}');
// CompareTo returns -1, 0, or 1
print('short.compareTo(medium): ${short.compareTo(medium)}');
print('medium.compareTo(medium): ${medium.compareTo(medium)}');
print('long.compareTo(medium): ${long.compareTo(medium)}');
}
此示例演示了如何使用标准运算符和 compareTo 方法比较持续时间。
格式化 Duration
Duration 类通过 toString 方法支持格式化,该方法以 HH:MM:SS.microseconds 的格式输出持续时间,负持续时间带有前导减号。对于自定义格式,开发人员可以提取小时、分钟和秒等组件,并使用 padLeft 等方法来确保一致的数字位数,从而实现定制化的字符串表示。
void main() {
Duration duration = Duration(
hours: 2,
minutes: 15,
seconds: 30,
milliseconds: 500,
microseconds: 250
);
// Standard toString() format
print('Default format: $duration');
// Custom formatting
String formatted = [
duration.inHours,
duration.inMinutes.remainder(60),
duration.inSeconds.remainder(60)
].map((seg) => seg.toString().padLeft(2, '0')).join(':');
print('Custom format: $formatted');
// For negative durations
Duration negative = -duration;
print('Negative format: $negative');
// Formatting with milliseconds
String withMs = '${duration.inMinutes}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}.${(duration.inMilliseconds % 1000).toString().padLeft(3, '0')}';
print('With milliseconds: $withMs');
}
此示例演示了使用默认 toString 方法和自定义格式化技术格式化持续时间。
$ dart run duration_formatting.dart Default format: 2:15:30.500250 Custom format: 02:15:30 Negative format: -2:15:30.500250 With milliseconds: 135:30.500
使用 DateTime
Duration 类经常与 DateTime 一起使用来进行时间计算,例如使用 add 将时间戳向前移动,使用 subtract 向后移动,或者使用 difference(返回 Duration)计算两个时间戳之间的间隔。这些操作是时区感知的,默认为本地时区,可确保时间相关逻辑的准确处理。
void main() {
DateTime now = DateTime.now();
Duration offset = Duration(days: 7, hours: 3);
// Adding duration to DateTime
DateTime future = now.add(offset);
print('Now: $now');
print('Future: $future');
// Subtracting duration from DateTime
DateTime past = now.subtract(offset);
print('Past: $past');
// Difference between DateTimes is a Duration
Duration diff = future.difference(past);
print('Difference: $diff');
// Time until/since specific DateTime
DateTime event = DateTime(2025, 12, 25);
Duration untilEvent = event.difference(now);
print('Days until event: ${untilEvent.inDays}');
}
此示例说明了 Duration 与 DateTime 的结合使用,用于推进、回溯和计算时间戳之间的差异。
$ dart run duration_datetime.dart Now: 2025-05-25 14:30:45.123456 Future: 2025-06-01 17:30:45.123456 Past: 2025-05-18 11:30:45.123456 Difference: 336:00:00.000000 Days until event: 214
计时器实现
Timer 类利用 Duration 来调度任务,从而实现在指定延迟后或以固定间隔执行。这对于在 Dart 应用程序中实现周期性操作或超时特别有用。
import 'dart:async';
void main() {
Duration interval = Duration(seconds: 1);
int count = 0;
Timer.periodic(interval, (timer) {
count++;
print('Tick $count');
if (count >= 5) {
timer.cancel();
print('Timer stopped');
}
});
}
此示例创建了一个周期性计时器,该计时器每秒触发一次,打印一个滴答计数,直到达到五次,此时计时器将被取消。
延迟执行
Future.delayed 构造函数与 Duration 结合使用,允许开发人员暂停代码执行指定的时间。此方法非常适合模拟延迟、实现超时或协调 Dart 应用程序中的异步操作。
Future<void> main() async {
print('Starting...');
await Future.delayed(Duration(seconds: 2));
print('After 2 seconds');
}
此示例使用 Future.delayed 引入两秒延迟,然后打印一条消息,演示了处理异步延迟的常用模式。
测量执行时间
Stopwatch 类与 Duration 一起使用,可以精确测量代码段的执行时间。这对于性能分析、基准测试和优化 Dart 应用程序非常有价值。
void main() {
Stopwatch stopwatch = Stopwatch()..start();
// Simulate work
int sum = 0;
for (int i = 0; i < 100_000_000; i++) {
sum += i;
}
stopwatch.stop();
print('Sum: $sum');
print('Computation took: ${stopwatch.elapsed}');
}
此示例测量使用 Stopwatch 计算总和所花费的时间,展示了其在性能分析中的实用性。
Rate Limiting 中的 Duration
Duration 类可用于在应用程序中实现速率限制,控制操作(如 API 调用或用户交互)的频率。通过强制操作之间设置最小时间间隔,开发人员可以防止过度使用并确保系统稳定性。
import 'dart:async';
void main() async {
Duration rateLimit = Duration(milliseconds: 500);
int actionCount = 0;
Future<void> performAction() async {
actionCount++;
print('Action $actionCount at ${DateTime.now()}');
await Future.delayed(rateLimit);
}
for (int i = 0; i < 5; i++) {
await performAction();
}
}
此示例实现了一个简单的速率限制器,可确保操作之间至少间隔 500 毫秒。每个操作都使用 Future.delayed 和 Duration 进行延迟,演示了如何在 Dart 应用程序中控制操作的频率。
来源
Dart Duration 类文档
Dart 库之旅:日期和时间
Duration 类是 Dart 核心库的基石,对于管理基于时间的操作至关重要。掌握其创建、操作和格式化对于构建健壮高效的 Dart 应用程序至关重要。
作者
列出 所有 Dart 教程。