-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Period
and PeriodList
to work with EXDATE
and RDATE
#684
base: main
Are you sure you want to change the base?
Conversation
9d19aa8
to
f09b049
Compare
@minichma The code changes became more than expected, because it was necessary to revisit |
I'm pretty sure it is. I see the challenges that come with introducing separate types for lists of Periods and IDateTimes - redundant code, challenges with type safety, inheritance. At the same time I remember the challenges I had when starting with ical.net and not knowing much about the details of RFC 5545. The ExDate property being a list of Periods was not exactly easy to understand at that time. So yes, doc comments will certainly be helpful in this respect. We can still continue thinking about alternatives in the future (maybe not v5 though once it has been released). |
Oops, just noticed that |
76a047e
to
9eef103
Compare
Creating |
@axunonb Wish you a great 2025! Hope I will find some time for a review this afternoon when I'll be on a train or otherwise tomorrow. |
9eef103
to
f762d8f
Compare
@minichma Happy New Year and thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a challenging one! Left a few comments but they might not be fully consistent. Just take what you think makes sense. Unfortunately I don't have the time right now to go into all the detail that would be required.
f762d8f
to
b54ca8c
Compare
@minichma Looks like the failing tests for .Net Framework go back to GitHub upgrading to |
0842c10
to
e190317
Compare
Improve reliability and usability for `Period` and `PeriodList` to become less error-prone by enforcing timezones being used consistently Period - Make parameterless CTOR `internal` to ensure proper initialization by users - A period can be defined 1. by a start time and an end time, 2. by a start time and a duration, 3. by a start time only, with the duration unspecified. This is for EXDATE and RDATE date-only and date/time. - For cosistency, either the `EndTime` or the `Duration` can be set at a time. The last one set with a value not `null` will prevail, while the other will become `null`. - Timezones of `StartTime`and (optional) `EndTime` must be the same - `CompareTo` uses `AsUtc` for comparing the `StartTime` - Remove returning a "magic" duration of 1 day, if `EndTime` is null and `StartTime` is date-only. This broke `EXDATE` and `RDATE` of an event, when the only a start time exists. - Added `EffectiveEndTime` and `EffectiveDuration` properties to provide calculated values based on the set values. - Update the `EndTime` and `Duration` properties to directly return the set values. - Change the access modifiers of `GetEffectiveDuration()` and `GetEffectiveEndTime` methods from internal to private. PeriodList - `TzId`: `public` setter changed to `private` - `EnsureConsistentTimezones`: The first period determines the timezone of the `PeriodList` and all other `Period`s added must have the same timezone - Add `SetService(new PeriodListEvaluator(this))` for `StringReader` CTOR overload - Add `static PeriodList FromStringReader(StringReader)` - Add `static PeriodList FromDateTime(IDateTime)` - Add `PeriodList AddPeriod(Period)` for chaining - Add `PeriodList Add(IDateTime)` for chaining - nullable enable EventEvaluator: - `EventEvaluator.WithEndTime(Period)` only sets the `EndTime`, as `Period.EffectiveDuration` returns the duration. TodoEvaluator: - Remove method `PeriodWithDuration(Period)` as it became redudant with the refactored `Period` class. DataTypeSerializer and other serializers, CalendarObjectBase: - `Activator.CreateInstance(TargetType, true)` allows for not `public` CTORs, so that parameterless CTORs can be excluded from the public API, if proper initialization can't be assured (like with `Period`). PropertySerializer: - TBD: Never set the UTC timezone ID (use appending 'Z') - Resolves ical-org#590 - Resolves ical-org#591 - Resolves ical-org#614 - Resolves ical-org#676
PeriodKind - Add new enum Period: - Add internal `property string TzId` - Add internal method `PeriodKind GetPeriodKind()` - Ensure timeone consistence for setters of StartTime / EndTime PeriodList: - Add internal `property string TzId` - Add internal property ``PeriodKind PeriodListKind`m - Ensure added `Period`s have the same `TzId`and `PeriodKind` as the first one added PeriodListSerialilzer - Serializes TZID - Serializes value type PERIOD
- Introduced `ExceptionDateCollection`, `RecurrencePeriodCollection` and PeriodCollectionBase` classes. - Updated serializers to handle the modified `PeriodList` implementation. These classes are an abstraction layer for creating `List<PeriodList>` objects. `Period`s and `CalDateTime`s are accepted without having to care for RFC 5545 rules regarding serialization: `ToRecurrenceDates` and `ToRecurrenceDates` methods aggregate and convert the exception or recurrence `CalDateTime` and `Period` objects into a list of `PeriodList` objects. Periods are grouped by their timezone IDs and period kinds in a way, that each `PeriodList` contains only distinct periods ready to serialize.
- Adjust code in ' EventEvaluator` and `PeriodSerializer` - Method `GetPeriodKind()` is replace with internal property `PeriodKind` - Add internal `Period.Create` to centralize logic if end time and duration exist - Modified unit test
Remove solution for RDATE/ESDATE introduced earlier in this PE The commit removes several test and source files related to period and exception date collections in calendar events. Specifically, the following files have been completely removed: - `PeriodCollectionBase.cs` - `ExceptionDateCollection.cs` - `RecurrencePeriodCollection.cs` - `PeriodCollectionTests.cs` - `RecurrenceWithExDateTests.cs` - `RecurrenceWithRDateTests.cs`
66a1611
to
fca144a
Compare
- Add internal properties `PeriodKind` and `TzId` to `PeriodList`. - Modify `Period` indexer and `Insert` to ensure consistency for timezone and `PeriodKind` - Prepare for `PeriodList` to become `internal` - Update `PeriodListSerializer` and `PeriodSerializer` classes for `Period` serialization - Introduce `ExceptionDates`, `RecurrenceDates`, and `PeriodListWrapperBase` to become wrappers around these properties of `RecurringComponent` - Add unit tests in `PeriodListWrapperTests` for `ExceptionDates` and `RecurrenceDates`. Note: The wrappers are not yet implemented for `IRecurringComponent`s.
fca144a
to
3800f1c
Compare
…nceDates` `IRecurrable` - Change the type of `ExceptionDates` from `IList<PeriodList>` to `ExceptionDates`. - Change the type of `RecurrenceDates` from `IList<PeriodList>` to `RecurrenceDates`. `RecurringComponent`, `VTimeZoneInfo` - Rename `IList<PeriodList> ExceptionDates` to `ExceptionDatesPeriodLists`. This serves as the backing storage for the new `ExceptionDates` class/property. - Rename `IList<PeriodList> RecurrenceDates` to `RecurrenceDatesPeriodLists`. This serves as the backing storage for the new `RecurrenceDates` class/property. - Add the creation of instances of `ExceptionDates` and `RecurrenceDates` to the `Initialize()` method. `PeriodList` and `PeriodListEvaluator` - Change the access modifier to `internal`. `RecurringEvaluator` and `TodoEvaluator` - Implement the new `ExceptionDates` and `RecurrenceDates` classes. `VTimeZone` - Enhanced serialization: - Before: Each `RDATE` date/time was serialized as a separate `RDATE` propery - Now: `RDATE` date/times which can be clustered go into one single `RDATE` property Unit tests - Refactor tests, using `ExceptionDates` and `RecurrenceDates` instead of `IList<PeriodList>` - Remove the duplicate `SimpleDeserializationTests.RecurrenceDates1()` method, which exists in `DeserializationTests.RecurrenceDates1()`. Todo: - Replace the use of `PeriodList.GetGroupedPeriods` in `CalendarEvent.Equals()`.
9f7d6ef
to
3817d85
Compare
Quality Gate passedIssues Measures |
@minichma Also a long story has end... |
Improve reliability and usability for
Period
andPeriodList
to become less error-prone by enforcing timezones being used consistentlyPeriod
internal
to ensure proper initialization by usersPeriodKind
to identify the period kind asUndefined
,DateTime
,DateOnly
orPeriod
and add methodPeriodKind GetPeriodKind()
EndTime
or theDuration
can be set at a time. The last one set with a value notnull
will prevail, while the other will becomenull
.StartTime
and (optional)EndTime
must be the sameCompareTo
usesAsUtc
for comparing theStartTime
EndTime
is null andStartTime
is date-only. This brokeEXDATE
andRDATE
of an event, when only a start time exists. Full day is handled byPeriodSerializer
.EffectiveEndTime
andEffectiveDuration
properties to provide calculated values based on the set values.EndTime
andDuration
properties to directly return the set values.GetEffectiveDuration()
andGetEffectiveEndTime
methods from internal to private.PeriodList
TzId
: Removed, as the timezone is enforced to be theTzId
of the firstPeriod
added.EnsureConsistentTimezoneAndPeriodKind
: The first period determines theTzId
andPeriodKind
of thePeriodList
and all otherPeriod
s added must these set as well.SetService(new PeriodListEvaluator(this))
forStringReader
CTOR overloadstatic PeriodList FromStringReader(StringReader)
Add(IDateTime)
EventEvaluator:
EventEvaluator.WithEndTime(Period)
only sets theEndTime
, asPeriod.EffectiveDuration
returns the duration.TodoEvaluator:
PeriodWithDuration(Period)
as it became redudant with the refactoredPeriod
class.DataTypeSerializer and other serializers, CalendarObjectBase:
Activator.CreateInstance(TargetType, true)
allows for notpublic
CTORs, so that parameterless CTORs can be excluded from the public API, if proper initialization can't be assured (like withPeriod
).Abstraction layer to create
EXDATE
andRDATE
ExceptionDateCollection
,RecurrencePeriodCollection
and PeriodCollectionBase` classes.PeriodList
implementation.These classes are an abstraction layer for creating
List<PeriodList>
objects.Period
s andCalDateTime
s are accepted without having to care for RFC 5545 rules regarding serialization:ToRecurrenceDates
andToRecurrenceDates
methods aggregate and convert the exception or recurrenceCalDateTime
andPeriod
objects into a list ofPeriodList
objects. Periods are grouped by their timezone IDs and period kinds in a way, that eachPeriodList
contains only distinct periods ready to serialize.PeriodSerializer, DateTimeSerializer:
Resolves #590
Resolves #591
Resolves #614
Resolves #676