From 8653e384ba3054d05ded6076065f8da7dbb4b43e Mon Sep 17 00:00:00 2001 From: Paolo Lammens Date: Wed, 26 Apr 2023 15:26:48 +0200 Subject: [PATCH] feat: Text encoding for BYHOUR, BYMINUTE, BYSECOND --- lib/src/codecs/text/encoder.dart | 30 +++++++++++++++++++++++++++--- lib/src/codecs/text/l10n/en.dart | 19 +++++++++++++++++++ lib/src/codecs/text/l10n/l10n.dart | 4 ++++ test/codecs/text/daily_test.dart | 6 ++++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/lib/src/codecs/text/encoder.dart b/lib/src/codecs/text/encoder.dart index ac0ee03..5f25426 100644 --- a/lib/src/codecs/text/encoder.dart +++ b/lib/src/codecs/text/encoder.dart @@ -120,7 +120,9 @@ class RecurrenceRuleToTextEncoder extends Converter { combination: input.hasByWeekDays ? ListCombination.disjunctive : ListCombination.conjunctiveShort, - )); + )) + // [at 8:00 & 12:00] + ..add(_formatByTime(input)); } void _convertWeekly(RecurrenceRule input, StringBuffer output) { @@ -137,7 +139,9 @@ class RecurrenceRuleToTextEncoder extends Converter { variant: input.hasBySetPositions ? InOnVariant.instanceOf : InOnVariant.simple, - )); + )) + // [at 8:00 & 12:00] + ..add(_formatByTime(input)); } void _convertMonthly(RecurrenceRule input, StringBuffer output) { @@ -176,7 +180,9 @@ class RecurrenceRuleToTextEncoder extends Converter { combination: input.hasByWeekDays ? ListCombination.disjunctive : ListCombination.conjunctiveShort, - )); + )) + // [at 8:00 & 12:00] + ..add(_formatByTime(input)); } void _convertYearly(RecurrenceRule input, StringBuffer output) { @@ -283,6 +289,8 @@ class RecurrenceRuleToTextEncoder extends Converter { if (limits.isNotEmpty) { output.add(l10n.list(limits, ListCombination.conjunctiveLong)); } + + output.add(_formatByTime(input)); } String? _formatBySetPositions(RecurrenceRule input) { @@ -378,6 +386,22 @@ class RecurrenceRuleToTextEncoder extends Converter { variant: variant, ); } + + String? _formatByTime(RecurrenceRule input) { + final byHours = input.hasByHours ? input.byHours : {null}; + final byMinutes = input.hasByMinutes ? input.byMinutes : {null}; + final bySeconds = input.hasBySeconds ? input.bySeconds : {null}; + + final timesOfDay = [ + for (var hour in byHours) + for (var minute in byMinutes) + for (var second in bySeconds) + if (!(hour == null && minute == null && second == null)) + l10n.timeOfDay(hour, minute, second) + ]; + + return timesOfDay.isEmpty ? null : l10n.atTimesOfDay(timesOfDay); + } } extension on StringBuffer { diff --git a/lib/src/codecs/text/l10n/en.dart b/lib/src/codecs/text/l10n/en.dart index 3cda0d7..8b90417 100644 --- a/lib/src/codecs/text/l10n/en.dart +++ b/lib/src/codecs/text/l10n/en.dart @@ -181,4 +181,23 @@ class RruleL10nEn extends RruleL10n { return number < 0 ? '$string-to-last' : string; } + + @override + String timeOfDay(int? hour, int? minute, int? second) { + final minutesFormat = NumberFormat('00'); + final secondsFormat = minutesFormat; + + final parts = [ + if (hour != null) hour.toString(), + if (minute != null) ':${minutesFormat.format(minute)}', + if (minute == null && second != null) ':', + if (second != null) ':${secondsFormat.format(second)}' + ]; + return parts.join(); + } + + @override + String atTimesOfDay(List timesOfDay) { + return 'at ${list(timesOfDay, ListCombination.conjunctiveShort)}'; + } } diff --git a/lib/src/codecs/text/l10n/l10n.dart b/lib/src/codecs/text/l10n/l10n.dart index 98d2b1f..558e2df 100644 --- a/lib/src/codecs/text/l10n/l10n.dart +++ b/lib/src/codecs/text/l10n/l10n.dart @@ -103,6 +103,10 @@ abstract class RruleL10n { } String ordinal(int number); + + String timeOfDay(int? hour, int? minute, int? second); + + String atTimesOfDay(List timesOfDay); } enum InOnVariant { simple, also, instanceOf } diff --git a/test/codecs/text/daily_test.dart b/test/codecs/text/daily_test.dart index f168338..382b02f 100644 --- a/test/codecs/text/daily_test.dart +++ b/test/codecs/text/daily_test.dart @@ -107,4 +107,10 @@ void main() { string: 'RRULE:FREQ=DAILY;BYSETPOS=1,-2;BYMONTH=1,12;BYMONTHDAY=1,-1;BYDAY=MO,TH', ); + + // Time of day. + testText( + 'Daily at 8:30 & 12:30', + string: 'RRULE:FREQ=DAILY;BYHOUR=8,12;BYMINUTE=30', + ); }