-
Notifications
You must be signed in to change notification settings - Fork 128
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
make_all_day() issues #155
Comments
Hi @perette ! Half a year later, i'm answering to your post, sorry about the delay :/ Changing the behaviour looks to me the way to go, after all, we are not yet in 1.0, breaking changes can and will happen :) |
The issue I found in #174 (comment) would probably be fixed by your PR. As the exact behaviour of the all-day is already quite blurry (see your proposed code changes and my comment on rounding), we maybe should agree on some expected behaviour first and then do the implementation accordingly. It might be useful to formulate the assumptions on the semantics of start = arrow.Arrow(2019, 5, 29, tzinfo="%+03d:00" % tz).shift(hours=hour)
precission_hour = Event(begin=start, duration=td(hours=duration))
precission_day = precission_hour.clone()
precission_day.make_all_day() The now following is my opinion/suggestion on how this should work to follow the principle of least surprise. Generally, the resulting timespan should be the shortest timespan from midnight to midnight (i.e. day resultion) that completely encompasses the previous event. This means that the new start time must be less than or equal to the initial start time, the end time and duration bigger than or equal to the initial ones. Formally: self.assertTrue(precission_day.includes(precission_hour))
self.assertLessEqual(precission_day.begin, precission_hour.begin)
self.assertGreaterEqual(precission_day.end, precission_hour.end)
self.assertGreaterEqual(precission_day.duration, precission_hour.duration)
# to ensure minimality
self.assertLess(precission_hour.begin - precission_day.begin, td(hours=24))
self.assertLess(precission_day.end - precission_hour.end, td(hours=24))
self.assertLess(precission_day.duration - precission_hour.duration, td(hours=24 * 2)) There is a conflict: if the start time is very late (e.g. 22:00) and the end time is very early (e.g. 03:00) we need to add more than 24 hours (here precission_hour2 = Event(begin=start, end=start.shift(hours=duration))
precission_day2 = precission_hour2.clone()
precission_day2.make_all_day()
self.assertEqual(str(precission_hour), str(precission_hour2))
self.assertEqual(str(precission_day), str(precission_day2)) Additionally, if we have an event with a duration being a multiple of 24, but starting in the middle of the day, we can shift the start time to the beginning of the day, but we will have to add another 24 hours of duration (which was already divisible by 24) to also encompass the initial end-time. So here, we need to change an already valid duration to keep up with the basic assumption of always encompassing the initial timespan. But as the duration can only grow in this way, I'd say this is less surprising to the developer/user than suddenly decreasing the end-time and thus having an all-day event that doesn't include it's initial event. Note: if the start- or end-times are already aligned to midnight, I would assume that they can't change: if precission_hour.begin == precission_hour.begin.floor("day"):
self.assertEqual(precission_day.begin, precission_hour.begin)
if precission_hour.end == precission_hour.end.floor("day"):
self.assertEqual(precission_day.end, precission_hour.end) But due the problem mentioned above, the following will not hold: if precission_hour.duration % td(days=1) == td(0): # is duration a multiple of 24 hours?
self.assertEqual(precission_day.duration, precission_hour.duration) |
Hi @N-Coder ! If i can find some time i'll try all those cases on google calendar to see how they handle it and what tradeoff they make to see if ours look the same. |
It seems that there a quite a few issues here revolving around the topic of all-day events.
VTIMEZONEs might also influence this, so I'm also linking #129 (esp. with regard to #161). Regarding the assumptions in my post above (and also the ones in #161 (comment)), we should check that the tests cover all the problems in the linked issues/PRs. Once they all pass, we can close all those issues together. 😊 Now that we have #222 to tackle all these issues, I'm also linking the timezone/timestamp parsing/serialization related issues #181, #182, and #188 to be closed with the above issues. |
…() issues" This reverts commit ed14cde. See discussion here: #222 (comment) We want to only include simple changes in the directly next release and wait with the complicated all-day and event timestamp handling issues for the then following dedicated release, which is prepared in #222.
…() issues" (#231) This reverts commit ed14cde. See discussion here: #222 (comment) We want to only include simple changes in the directly next release and wait with the complicated all-day and event timestamp handling issues for the then following dedicated release, which is prepared in #222.
Support for all-day events is ugly and confusing.
make_all_day
treats an event's begin/end times as an inclusive date range, and converts it to half-open. Forbegin
, it's set to the start of its day, but forend
it's bumped to the start of the next day, even if it's already at the start of a day. Additionally, if the begin time is subsequently changed, the event unexpectedly reverts to a not-full-day event. This is not documented and has a side effect that callingmake_all_day
again causes the end to be bumped up by one, as it is re-converted from inclusive to half-open range. However, setting the end time does not effect the all-day status, nor is the value rounded or bumped; you can make an all-day event that's 1 day, 3 hours and 5 minutes.I'd like to suggest a combination of behavioral and documentation improvements. I'm willing to commit time to make these happen, but want to gather input and confirm I'm sane in my approach:
Definite code changes:
make_all_day
should round the duration up to the next 24-hour interval. If it's already an even day, the duration should be unchanged. (Currently, a duration is converted to a fixed end-time, subject to bumping on successivemake_all_day
.)Definite documentation changes:
make_all_day
.Possible code changes:
begin
's setter implicitly change events to non-all-day event, instead have it round the provided begin time to the start of day when it's an all-day event.end
's setter to also round, but round up rather than down. Setting to start of day should not increment to next day (to retain compatibility with current behavior), but that should be clearly documented.make_all_day(ad = True)
, with default True which would make the event all-day. If the parameter is false, revert to a non-all-day event.That seems sane to me, as it's changing already-blurry areas for behavior. But it's still changing behavior and risks breaking code using the library. Alternately, there's the documentation route:
make_all_day()
can be called to restore all-day status, but doing so will bump the end date again. Assuming the change for all-day durations is in place, suggest using duration instead of end date to avoid bumping.Thoughts?
The text was updated successfully, but these errors were encountered: