Skip to content

Commit

Permalink
apply UTC date times and render UTC times
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-virkus committed Aug 3, 2021
1 parent febdf33 commit 8c99c35
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 56 deletions.
2 changes: 1 addition & 1 deletion lib/src/text/l10n/de.dart
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class RruleL10nDe extends RruleL10n {
DaysOfVariant daysOfVariant = DaysOfVariant.dayAndFrequency,
InOnVariant variant = InOnVariant.simple,
}) {
print('onDaysOfMonth days=$days, variant=$variant');
//print('onDaysOfMonth days=$days, variant=$variant');
final suffix = {
DaysOfVariant.simple: '',
DaysOfVariant.day: ' Tag',
Expand Down
12 changes: 10 additions & 2 deletions lib/src/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -856,8 +856,8 @@ class TimeOfDayWithSeconds {
}

static TimeOfDayWithSeconds parse(String content) {
final hour = int.tryParse(content.substring(0, 2));
final minute = int.tryParse(content.substring(2, 4));
var hour = int.tryParse(content.substring(0, 2));
var minute = int.tryParse(content.substring(2, 4));
final second = int.tryParse(content.substring(4, 6));
if (hour == null || minute == null || second == null) {
throw FormatException('Invalid time definition: $content');
Expand Down Expand Up @@ -969,6 +969,11 @@ class DateHelper {
}
final date = DateHelper.parseDate(content.substring(0, 4 + 2 + 2));
final time = TimeOfDayWithSeconds.parse(content.substring(tIndex + 1));
final isUtc = content.endsWith('Z');
if (isUtc) {
return DateTime.utc(
date.year, date.month, date.day, time.hour, time.minute, time.second);
}
return DateTime(
date.year, date.month, date.day, time.hour, time.minute, time.second);
}
Expand Down Expand Up @@ -997,6 +1002,9 @@ class DateHelper {
renderDate(value, buffer);
buffer.write('T');
TimeOfDayWithSeconds.renderTime(value, buffer);
if (value.isUtc) {
buffer.write('Z');
}
return buffer.toString();
}
}
Expand Down
116 changes: 80 additions & 36 deletions test/components_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ END:VCALENDAR''';
expect(event, isInstanceOf<VEvent>());
expect((event as VEvent).summary, 'Bastille Day Party');
expect(event.uid, '[email protected]');
expect(event.timeStamp, DateTime(1997, 06, 10, 17, 23, 45));
expect(event.start, DateTime(1997, 07, 14, 17, 00, 00));
expect(event.end, DateTime(1997, 07, 15, 04, 00, 00));
expect(event.timeStamp, DateTime.utc(1997, 06, 10, 17, 23, 45));
expect(event.start, DateTime.utc(1997, 07, 14, 17, 00, 00));
expect(event.end, DateTime.utc(1997, 07, 15, 04, 00, 00));
});

test('Private event', () {
Expand All @@ -277,9 +277,9 @@ END:VEVENT''';
expect(event, isInstanceOf<VEvent>());
expect((event as VEvent).summary, 'Annual Employee Review');
expect(event.uid, '[email protected]');
expect(event.timeStamp, DateTime(1997, 09, 01, 13, 00, 00));
expect(event.start, DateTime(1997, 09, 03, 16, 30, 00));
expect(event.end, DateTime(1997, 09, 03, 19, 00, 00));
expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00));
expect(event.start, DateTime.utc(1997, 09, 03, 16, 30, 00));
expect(event.end, DateTime.utc(1997, 09, 03, 19, 00, 00));
expect(event.classification, Classification.private);
expect(event.categories, ['BUSINESS', 'HUMAN RESOURCES']);
});
Expand All @@ -302,9 +302,9 @@ END:VEVENT
expect((event as VEvent).summary,
'Laurel is in sensitivity awareness class.');
expect(event.uid, '[email protected]');
expect(event.timeStamp, DateTime(1997, 09, 01, 13, 00, 00));
expect(event.start, DateTime(1997, 04, 01, 16, 30, 00));
expect(event.end, DateTime(1997, 04, 02, 1, 00, 00));
expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00));
expect(event.start, DateTime.utc(1997, 04, 01, 16, 30, 00));
expect(event.end, DateTime.utc(1997, 04, 02, 1, 00, 00));
expect(event.classification, Classification.public);
expect(event.categories, ['BUSINESS', 'HUMAN RESOURCES']);
expect(event.timeTransparency, TimeTransparency.transparent);
Expand All @@ -327,7 +327,7 @@ END:VEVENT\r
expect(event, isInstanceOf<VEvent>());
expect((event as VEvent).summary, 'Our Blissful Anniversary');
expect(event.uid, '[email protected]');
expect(event.timeStamp, DateTime(1997, 09, 01, 13, 00, 00));
expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00));
expect(event.start, DateTime(1997, 11, 02));
expect(event.classification, Classification.confidential);
expect(event.categories, ['ANNIVERSARY', 'PERSONAL', 'SPECIAL OCCASION']);
Expand All @@ -352,7 +352,7 @@ END:VEVENT
expect((event as VEvent).summary,
'Festival International de Jazz de Montreal');
expect(event.uid, '[email protected]');
expect(event.timeStamp, DateTime(2007, 04, 23, 12, 34, 32));
expect(event.timeStamp, DateTime.utc(2007, 04, 23, 12, 34, 32));
expect(event.start, DateTime(2007, 06, 28));
expect(event.end, DateTime(2007, 07, 09));
expect(event.timeTransparency, TimeTransparency.transparent);
Expand Down Expand Up @@ -390,9 +390,9 @@ END:VCALENDAR\r
final event = calendar.children.first;
expect(event, isInstanceOf<VEvent>());
expect((event as VEvent).uid, '[email protected]');
expect(event.timeStamp, DateTime(1996, 07, 04, 12, 00, 00));
expect(event.start, DateTime(1996, 09, 18, 14, 30, 00));
expect(event.end, DateTime(1996, 09, 20, 22, 00, 00));
expect(event.timeStamp, DateTime.utc(1996, 07, 04, 12, 00, 00));
expect(event.start, DateTime.utc(1996, 09, 18, 14, 30, 00));
expect(event.end, DateTime.utc(1996, 09, 20, 22, 00, 00));
expect(event.categories, ['CONFERENCE']);
expect(event.status, EventStatus.confirmed);
expect(event.organizer?.email, '[email protected]');
Expand Down Expand Up @@ -434,9 +434,9 @@ END:VCALENDAR
final event = calendar.children.first;
expect(event, isInstanceOf<VEvent>());
expect((event as VEvent).uid, '[email protected]');
expect(event.timeStamp, DateTime(1996, 07, 04, 12, 00, 00));
expect(event.start, DateTime(1996, 09, 18, 14, 30, 00));
expect(event.end, DateTime(1996, 09, 20, 22, 00, 00));
expect(event.timeStamp, DateTime.utc(1996, 07, 04, 12, 00, 00));
expect(event.start, DateTime.utc(1996, 09, 18, 14, 30, 00));
expect(event.end, DateTime.utc(1996, 09, 20, 22, 00, 00));
expect(event.categories, ['CONFERENCE']);
expect(event.status, EventStatus.confirmed);
expect(event.organizer?.email, '[email protected]');
Expand Down Expand Up @@ -493,8 +493,8 @@ END:VCALENDAR
final event = calendar.children[1];
expect(event, isInstanceOf<VEvent>());
expect((event as VEvent).uid, 'guid-1.example.com');
expect(event.timeStamp, DateTime(1998, 03, 09, 23, 10, 00));
expect(event.created, DateTime(1998, 03, 09, 13, 00, 00));
expect(event.timeStamp, DateTime.utc(1998, 03, 09, 23, 10, 00));
expect(event.created, DateTime.utc(1998, 03, 09, 13, 00, 00));
expect(event.start, DateTime(1998, 03, 12, 08, 30, 00));
expect(event.end, DateTime(1998, 03, 12, 09, 30, 00));
expect(event.location, '1CP Conference Room 4350');
Expand Down Expand Up @@ -569,9 +569,9 @@ END:VCALENDAR
final event = calendar.children.first;
expect(event, isInstanceOf<VEvent>());
expect((event as VEvent).uid, '[email protected]');
expect(event.timeStamp, DateTime(1997, 03, 24, 12, 00, 00));
expect(event.start, DateTime(1997, 03, 24, 12, 30, 00));
expect(event.end, DateTime(1997, 03, 24, 21, 00, 00));
expect(event.timeStamp, DateTime.utc(1997, 03, 24, 12, 00, 00));
expect(event.start, DateTime.utc(1997, 03, 24, 12, 30, 00));
expect(event.end, DateTime.utc(1997, 03, 24, 21, 00, 00));
expect(event.organizer?.email, '[email protected]');
expect(event.attendees.length, 1);
expect(event.attendees[0].rsvp, isTrue);
Expand Down Expand Up @@ -601,7 +601,7 @@ SEQUENCE:2
UID:[email protected]
ORGANIZER:mailto:[email protected]
ATTENDEE;PARTSTAT=ACCEPTED:mailto:[email protected]
DUE:19980415T000000
DUE:19980415T000000Z
STATUS:NEEDS-ACTION
SUMMARY:Submit Income Taxes
BEGIN:VALARM
Expand All @@ -626,7 +626,7 @@ END:VCALENDAR
final todo = calendar.children.first;
expect(todo, isInstanceOf<VTodo>());
expect((todo as VTodo).uid, '[email protected]');
expect(todo.timeStamp, DateTime(1998, 01, 30, 13, 45, 00));
expect(todo.timeStamp, DateTime.utc(1998, 01, 30, 13, 45, 00));
expect(todo.sequence, 2);
expect(todo.organizer?.email, '[email protected]');
expect(todo.attendees.length, 1);
Expand All @@ -635,14 +635,14 @@ END:VCALENDAR
expect(todo.attendees[0].email, '[email protected]');
expect(todo.summary, 'Submit Income Taxes');
expect(todo.status, TodoStatus.needsAction);
expect(todo.due, DateTime(1998, 04, 15, 00, 00, 00));
expect(todo.due, DateTime.utc(1998, 04, 15, 00, 00, 00));
expect(todo.children, isNotEmpty);
expect(todo.children.length, 1);
final alarm = todo.children.first;
expect(alarm, isInstanceOf<VAlarm>());
expect((alarm as VAlarm).componentType, VComponentType.alarm);
expect(alarm.action, AlarmAction.audio);
expect(alarm.triggerDate, DateTime(1998, 04, 03, 12, 00, 00));
expect(alarm.triggerDate, DateTime.utc(1998, 04, 03, 12, 00, 00));
expect(alarm.repeat, 4);
expect(alarm.duration, IsoDuration(hours: 1));
expect(alarm.attachments, isNotEmpty);
Expand Down Expand Up @@ -681,33 +681,33 @@ END:VCALENDAR
final freebusy = calendar.children.first;
expect(freebusy, isInstanceOf<VFreeBusy>());
expect((freebusy as VFreeBusy).organizer?.email, '[email protected]');
expect(freebusy.timeStamp, DateTime(1997, 09, 01, 12, 00, 00));
expect(freebusy.timeStamp, DateTime.utc(1997, 09, 01, 12, 00, 00));
expect(freebusy.uid, '[email protected]');
expect(freebusy.organizer?.email, '[email protected]');
expect(freebusy.start, DateTime(1998, 03, 13, 14, 17, 11));
expect(freebusy.end, DateTime(1998, 04, 10, 14, 17, 11));
expect(freebusy.start, DateTime.utc(1998, 03, 13, 14, 17, 11));
expect(freebusy.end, DateTime.utc(1998, 04, 10, 14, 17, 11));
expect(freebusy.url,
Uri.parse('http://www.example.com/calendar/busytime/jsmith.ifb'));
expect(freebusy.freeBusyProperties, isNotEmpty);
expect(freebusy.freeBusyProperties.length, 3);
expect(freebusy.freeBusyProperties[0].periods, isNotEmpty);
expect(freebusy.freeBusyProperties[0].periods.length, 1);
expect(freebusy.freeBusyProperties[0].periods[0].startDate,
DateTime(1998, 03, 14, 23, 30, 00));
DateTime.utc(1998, 03, 14, 23, 30, 00));
expect(freebusy.freeBusyProperties[0].periods[0].endDate,
DateTime(1998, 03, 15, 00, 30, 00));
DateTime.utc(1998, 03, 15, 00, 30, 00));
expect(
freebusy.freeBusyProperties[0].freeBusyType, FreeBusyTimeType.busy);
expect(freebusy.freeBusyProperties[1].periods.length, 1);
expect(freebusy.freeBusyProperties[1].periods[0].startDate,
DateTime(1998, 03, 16, 15, 30, 00));
DateTime.utc(1998, 03, 16, 15, 30, 00));
expect(freebusy.freeBusyProperties[1].periods[0].endDate,
DateTime(1998, 03, 16, 16, 30, 00));
DateTime.utc(1998, 03, 16, 16, 30, 00));
expect(freebusy.freeBusyProperties[2].periods.length, 1);
expect(freebusy.freeBusyProperties[2].periods[0].startDate,
DateTime(1998, 03, 18, 03, 00, 00));
DateTime.utc(1998, 03, 18, 03, 00, 00));
expect(freebusy.freeBusyProperties[2].periods[0].endDate,
DateTime(1998, 03, 18, 04, 00, 00));
DateTime.utc(1998, 03, 18, 04, 00, 00));
});

test('free busy example', () {
Expand Down Expand Up @@ -747,7 +747,7 @@ END:VCALENDAR\r
final journal = calendar.children.first;
expect(journal, isInstanceOf<VJournal>());
expect((journal as VJournal).uid, '[email protected]');
expect(journal.timeStamp, DateTime(1997, 03, 24, 12, 00, 00));
expect(journal.timeStamp, DateTime.utc(1997, 03, 24, 12, 00, 00));
expect(journal.organizer?.email, '[email protected]');
expect(journal.classification, Classification.public);
expect(journal.status, JournalStatus.draft);
Expand Down Expand Up @@ -930,5 +930,49 @@ END:VCALENDAR\r
expect(event.organizer, isNotNull);
expect(event.organizer?.email, '[email protected]');
});

test('Simple event with UTC timing', () {
final invite = VCalendar.createEvent(
organizerEmail: '[email protected]',
attendeeEmails: ['[email protected]', '[email protected]', '[email protected]'],
rsvp: true,
start: DateTime.utc(2021, 07, 21, 10, 00),
end: DateTime.utc(2021, 07, 21, 11, 00),
location: 'Big meeting room',
url: Uri.parse('https://enough.de'),
summary: 'Discussion',
description:
'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?',
productId: 'enough_icalendar/v1',
);
// print(invite);
invite.checkValidity();
expect(invite.isVersion2, isTrue);
expect(invite.isGregorian, isTrue);
expect(invite.productId, 'enough_icalendar/v1');
expect(invite.children, isNotEmpty);
final event = invite.children.first;
event.checkValidity();
expect(event, isInstanceOf<VEvent>());
expect((event as VEvent).start, DateTime.utc(2021, 07, 21, 10, 00));
expect(event['DTSTART']?.textValue, '20210721T100000Z');
expect(event.end, DateTime.utc(2021, 07, 21, 11, 00));
expect(event['DTEND']?.textValue, '20210721T110000Z');
expect(event.location, 'Big meeting room');
expect(event.url, Uri.parse('https://enough.de'));
expect(event.summary, 'Discussion');
expect(event.description,
'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?');
expect(event.attendees, isNotEmpty);
expect(event.attendees.length, 3);
expect(event.attendees[0].rsvp, isTrue);
expect(event.attendees[0].email, '[email protected]');
expect(event.attendees[1].rsvp, isTrue);
expect(event.attendees[1].email, '[email protected]');
expect(event.attendees[2].rsvp, isTrue);
expect(event.attendees[2].email, '[email protected]');
expect(event.organizer, isNotNull);
expect(event.organizer?.email, '[email protected]');
});
});
}
25 changes: 17 additions & 8 deletions test/properties_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ void main() {
});

group('Indirect Property Instantiation', () {
test('UTC Start Date', () {
final prop = Property.parseProperty('DTSTART:20210803T080000Z');
expect(prop, isInstanceOf<DateTimeProperty>());
expect(prop.name, 'DTSTART');
expect(prop.textValue, '20210803T080000Z');
expect((prop as DateTimeProperty).dateTime.isUtc, isTrue);
expect(prop.dateTime, DateTime.utc(2021, 08, 03, 08, 00));
});
test('GeoProperty', () {
final prop = Property.parseProperty('GEO:37.386013;-122.082932');
expect(prop, isInstanceOf<GeoProperty>());
Expand All @@ -105,7 +113,7 @@ void main() {
expect(prop.rule.byMonth, isNotEmpty);
expect(prop.rule.byMonth!.length, 1);
expect(prop.rule.byMonth![0], 4);
expect(prop.rule.until, DateTime(1998, 04, 04, 07));
expect(prop.rule.until, DateTime.utc(1998, 04, 04, 07));
});

test('RRULE:FREQ=UNKNOWN;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z', () {
Expand Down Expand Up @@ -150,7 +158,8 @@ void main() {
expect(prop.periods, isNotNull);
expect(prop.periods, isNotEmpty);
expect(prop.periods.length, 1);
expect(prop.periods.first.startDate, DateTime(1997, 03, 08, 16, 00, 00));
expect(
prop.periods.first.startDate, DateTime.utc(1997, 03, 08, 16, 00, 00));
expect(prop.periods.first.duration, IsoDuration(hours: 8, minutes: 30));
});

Expand All @@ -162,9 +171,9 @@ void main() {
expect((prop as FreeBusyProperty).freeBusyType, FreeBusyTimeType.free);
expect(prop.periods, isNotEmpty);
expect(prop.periods.length, 2);
expect(prop.periods[0].startDate, DateTime(1997, 03, 08, 16, 00, 00));
expect(prop.periods[0].startDate, DateTime.utc(1997, 03, 08, 16, 00, 00));
expect(prop.periods[0].duration, IsoDuration(hours: 3));
expect(prop.periods[1].startDate, DateTime(1997, 03, 08, 20, 00, 00));
expect(prop.periods[1].startDate, DateTime.utc(1997, 03, 08, 20, 00, 00));
expect(prop.periods[1].duration, IsoDuration(hours: 1));
});

Expand All @@ -179,14 +188,14 @@ void main() {
expect((prop as FreeBusyProperty).freeBusyType, FreeBusyTimeType.free);
expect(prop.periods, isNotEmpty);
expect(prop.periods.length, 3);
expect(prop.periods[0].startDate, DateTime(1997, 03, 08, 16, 00, 00));
expect(prop.periods[0].startDate, DateTime.utc(1997, 03, 08, 16, 00, 00));
expect(prop.periods[0].duration, IsoDuration(hours: 3));
expect(prop.periods[0].endDate, isNull);
expect(prop.periods[1].startDate, DateTime(1997, 03, 08, 20, 00, 00));
expect(prop.periods[1].startDate, DateTime.utc(1997, 03, 08, 20, 00, 00));
expect(prop.periods[1].duration, IsoDuration(hours: 1));
expect(prop.periods[0].endDate, isNull);
expect(prop.periods[2].startDate, DateTime(1997, 03, 08, 23, 00, 00));
expect(prop.periods[2].startDate, DateTime.utc(1997, 03, 08, 23, 00, 00));
expect(prop.periods[2].duration, isNull);
expect(prop.periods[2].endDate, DateTime(1997, 03, 09, 00, 00, 00));
expect(prop.periods[2].endDate, DateTime.utc(1997, 03, 09, 00, 00, 00));
});
}
Loading

0 comments on commit 8c99c35

Please sign in to comment.