Esempio n. 1
0
 def validate_timeprecision(value, name):
     if self.precision == "day":
         if floor_datetime_to_midnight(value) != value:
             raise ValueError(
                 "%s time value %s has higher precision than set precision %s"
                 % (name, value, self.precision))
         if value.tzinfo is not None:
             raise ValueError(
                 "all-day timespan %s time %s can't have a timezone" %
                 (name, value))
Esempio n. 2
0
    def on(self,
           instant: DatetimeLike,
           strict: bool = False) -> Iterator[Event]:
        """
        Iterates (in chronological order) over all events that occurs on `day`.

        :param strict: if True events will be returned only if they are strictly *included* in `day`
        """
        begin = floor_datetime_to_midnight(ensure_datetime(instant))
        end = ceil_datetime_to_midnight(
            ensure_datetime(instant) + timedelta(seconds=1))
        query = self.__normalize_timespan(begin, end)
        if strict:
            return self.included(query)
        else:
            return self.overlapping(query)
Esempio n. 3
0
    def make_all_day(self) -> "Timespan":
        if self.is_all_day():
            return self  # Do nothing if we already are a all day timespan

        begin = self.begin_time
        if begin is not None:
            begin = floor_datetime_to_midnight(begin).replace(tzinfo=None)

        end = self.get_effective_end()
        if end is not None:
            end = ceil_datetime_to_midnight(end).replace(tzinfo=None)
            if end == begin:  # we also add another day if the duration would be 0 otherwise
                end = end + TIMEDELTA_DAY

        if self.get_end_representation() == "duration":
            assert end is not None
            assert begin is not None
            return self.replace(begin, None, end - begin, "day")
        else:
            return self.replace(begin, end, None, "day")
Esempio n. 4
0
    def assert_make_all_day_valid(self, ts_secs: EventTimespan,
                                  ts_days: EventTimespan):
        # check resolution for all_day
        assert ts_days.get_effective_duration() % td(days=1) == td(0)
        assert floor_datetime_to_midnight(
            ts_days.get_begin()) == ts_days.get_begin()
        assert floor_datetime_to_midnight(
            ts_days.get_effective_end()) == ts_days.get_effective_end()

        # minimum duration is 0s / 1d
        assert ts_secs.get_effective_duration() >= td()
        assert ts_days.get_effective_duration() >= td(days=1)

        # test inclusion and boundaries
        ts_days_begin_wtz = ts_days.get_begin().replace(
            tzinfo=ts_secs.get_begin().tzinfo)
        ts_days_eff_end_wtz = ts_days.get_effective_end().replace(
            tzinfo=ts_secs.get_effective_end().tzinfo)
        assert ts_days_begin_wtz <= ts_secs.get_begin()
        assert ts_days_eff_end_wtz >= ts_secs.get_effective_end()
        assert ts_days.get_effective_duration(
        ) >= ts_secs.get_effective_duration()

        # test that we didn't decrease anything
        begin_earlier = ts_secs.get_begin() - ts_days_begin_wtz
        end_later = ts_days_eff_end_wtz - ts_secs.get_effective_end()
        duration_bigger = ts_days.get_effective_duration(
        ) - ts_secs.get_effective_duration()
        assert begin_earlier >= td()
        assert end_later >= td()
        assert duration_bigger >= td()

        # test that we didn't drift too far
        assert begin_earlier < td(hours=24)
        instant_to_one_day = (ts_secs.get_begin().hour == 0
                              and ts_secs.get_effective_duration() == td())
        if instant_to_one_day:
            assert end_later == td(hours=24)
        else:
            assert end_later < td(hours=24)
        # NOTICE: duration might grow by 48h, not only 24, as we floor the begin time (which might be 23:59)
        # and ceil the end time (which might be 00:01)
        assert duration_bigger < td(hours=24 * 2)

        # test that we made no unnecessary modification
        if ts_secs.get_begin() == floor_datetime_to_midnight(
                ts_secs.get_begin()):
            assert ts_days.get_begin() == ts_secs.get_begin().replace(
                tzinfo=None)
        if ts_secs.get_effective_end() == floor_datetime_to_midnight(
                ts_secs.get_effective_end()):
            if instant_to_one_day:
                # here we need to convert duration=0 to duration=1d
                assert ts_days.get_effective_end(
                ) == ts_secs.get_effective_end().replace(tzinfo=None) + td(
                    days=1)
            else:
                assert ts_days.get_effective_end(
                ) == ts_secs.get_effective_end().replace(tzinfo=None)

        # the following won't hold for events that don't start at 00:00, compare NOTICE above
        if ts_secs.get_begin().hour == 0:
            if instant_to_one_day:
                # here we need to convert duration=0 to duration=1d
                assert duration_bigger == td(hours=24)
            else:
                # if we start at midnight, only the end time is ceiled, which can only add up to 24h instead of 48h
                assert duration_bigger < td(hours=24)

            mod_duration = (ts_secs.get_effective_duration() % td(days=1))
            if ts_secs.get_effective_duration() <= td(days=1):
                # here we need to convert duration<1d to duration=1d
                assert ts_days.get_effective_duration() == td(days=1)
            elif mod_duration == td():
                assert ts_days.get_effective_duration(
                ) == ts_secs.get_effective_duration()
            else:
                assert ts_days.get_effective_duration(
                ) == ts_secs.get_effective_duration() + td(
                    days=1) - mod_duration

        # log data
        if self.data is not None:
            self.data.append((
                str(ts_secs),
                ts_secs.get_effective_duration().days * 24 +
                ts_secs.get_effective_duration().seconds / 3600,
                str(ts_days),
                ts_days.get_effective_duration().days * 24 +
                ts_days.get_effective_duration().seconds / 3600,
                begin_earlier,
                end_later,
                duration_bigger,
            ))