Line data Source code
1 : import 'package:localization/localization.dart';
2 :
3 : enum DurationScale { SECONDS, MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEARS }
4 :
5 : class DurationUnit {
6 : final DurationScale scale;
7 : final int value;
8 : final double limit;
9 :
10 0 : DurationUnit(this.scale, this.value, this.limit);
11 : }
12 :
13 : extension TimeNotation on Duration {
14 0 : static Map<DurationScale, String> defaultFormats = {
15 : DurationScale.SECONDS: "%SS",
16 : DurationScale.MINUTES: "%mm",
17 : DurationScale.HOURS: "%HH.",
18 : DurationScale.DAYS: "%DD.",
19 : DurationScale.MONTHS: "%MM",
20 : DurationScale.YEARS: "%YY"
21 : };
22 :
23 0 : String durationFormat({Map<DurationScale, String>? formats}) {
24 0 : final thresholds = [
25 0 : DurationUnit(DurationScale.SECONDS, inSeconds, 60),
26 0 : DurationUnit(DurationScale.MINUTES, inMinutes, 60),
27 0 : DurationUnit(DurationScale.HOURS, inHours, 24),
28 0 : DurationUnit(DurationScale.DAYS, inDays, 30),
29 0 : DurationUnit(DurationScale.MONTHS, inDays ~/ 30, 12),
30 0 : DurationUnit(
31 0 : DurationScale.YEARS, (inDays / 365.25).floor(), double.infinity),
32 : ];
33 :
34 0 : for (final unit in thresholds) {
35 0 : if (unit.value < unit.limit) {
36 0 : final format = formats?[unit.scale] ?? defaultFormats[unit.scale]!;
37 : return format
38 0 : .replaceAll(RegExp("%SS"),
39 0 : "${inSeconds.toString().i18n()} ${"acronym.datetime.seconds".i18n()}")
40 0 : .replaceAll(RegExp("%mm"),
41 0 : "${inMinutes.toString()} ${"acronym.datetime.minutes".i18n()}")
42 0 : .replaceAll(RegExp("%HH"),
43 0 : "${inHours.toString()} ${"acronym.datetime.hours".i18n()}")
44 0 : .replaceAll(RegExp("%DD"),
45 0 : "${inDays.toString()} ${"acronym.datetime.days".i18n()}")
46 0 : .replaceAll(
47 0 : RegExp("%MM"),
48 0 : "${(inDays ~/ 30).toString()} ${"acronym.datetime.months".i18n([], [
49 0 : (inDays ~/ 30) > 1
50 0 : ])}")
51 0 : .replaceAll(
52 0 : RegExp("%YY"),
53 0 : "${(inDays / 365.25).floor().toString()} ${'acronym.datetime.years'.i18n([], [
54 0 : (inDays / 365.25).floor() > 1
55 0 : ])}");
56 : }
57 : }
58 :
59 0 : throw Exception("The impossible has happened");
60 : }
61 : }
|