Example #1
0
    def subinterval_starting_at_or_after( self, a_datetime ):
        """Returns the intersection between this TimeInterval and the
        interval which includes the microsecond represented by
        a_datetime and all time after it.

        Raises a ValueError when a_datetime is in the future and
        is_ongoing is true.

        a_datetime - a timezone aware datetime object

        The new first instant will be the later of a_datetime and self.first
        """
        # Note that this will raise the required ValueError if
        # a_datetime is in the future
        if not self.contains(a_datetime):
            return EmptyTimeInterval()
        
        # Since the split point is not in the future, we can make the
        # required ongoing interval by taking the union of the time
        # that has already occurred at or after the split point with
        # all future time.
        up_to_now = BoundedTimeInterval(self.first, LocalTimezone.now())
        intersection_up_to_now = (
            up_to_now.subinterval_starting_at_or_after(a_datetime))

        return OngoingTimeInterval(intersection_up_to_now.first)
Example #2
0
    def intersection_with( self, a_TimeInterval ):
        """Returns an interval representing the times that are in both this interval and a_TimeInterval

        Note: this is fragile and depends on knowing what all the
           subclasses of TimeInterval are (see my note on this method
           in the TimeInterval docstring)

        Raises a ValueError when this time interval contains instants
        in the future and a_TimeInterval is ongoing (since you don't
        know when the ongoing interval will stop.)

        """
        # Detect if someone has implemented a subclass not known at
        # the time of this writing and tried to find the
        # intersection. Fail so this will be caught in testing.
        assert(isinstance(
            a_TimeInterval, 
            (EmptyTimeInterval, BoundedTimeInterval, OngoingTimeInterval)))

        if a_TimeInterval.is_ongoing():
            if LocalTimezone.in_future(self.last):
                raise ValueError(
                    "Cannot determine the intersection between {} and {} "
                    "because the first includes the future and the second is "
                    "ongoing, so we don't know when it will stop.".format(
                        self, a_TimeInterval))
            else:
                # Here I assume that all objects with is_ongoing true
                # have a first member
                return (intersection_with(
                    self, BoundedTimeInterval(
                        a_TimeInterval.first, LocalTimezone.now()
                        )))
        elif hasattr(a_TimeInterval, 'first'): #Assume BoundedTimeInterval
            if ( # The two intervals overlap
                     a_TimeInterval.first <= self.last and 
                     self.first <= a_TimeInterval.last): 
                return BoundedTimeInterval(
                    max(self.first, a_TimeInterval.first),
                    min(self.last, a_TimeInterval.last))
            else:
                return EmptyTimeInterval()
        else: # We can assume EmptyTimeInterval due to the assert at the
              # beginning of the method
            return EmptyTimeInterval()
Example #3
0
    def contains( self, a_datetime ):
        """Return True iff the interval includes the microsecond represented by a_datetime

        Raises a ValueError when a_datetime is in the future and
        is_ongoing is true.

        """
        if LocalTimezone.in_future(a_datetime):
            raise ValueError(
                "It is unknown whether the ongoing interval {} contains "
                "the datetime object {} because it is in the future."
                .format(str(self), str(a_datetime))
                )
        return self.first <= a_datetime
Example #4
0
    def __new__(cls, first):
        """Set the cooresponding members to the provided values

        (See class docstring for member description)
        """

        if first is None:
            raise ValueError("The starting time of a fogbugz "
                             "OngoingTimeInterval must be defined.")

        if tzutil.is_naive(first):
            raise ValueError("Starting time of a fogbugz "
               "OngoingTimeInterval must be timezone aware")

        if LocalTimezone.in_future(first):
            raise ValueError(
                "The starting time of a fogbugz OngoingTimeInterval must not "
                "be in the future. ({})".format(str(first)))
        
        return cls.__bases__[0].__new__(cls, copy.copy(first))
Example #5
0
    def subinterval_before(self, a_datetime):
        """Returns the intersection between this TimeInterval and the
        interval containing all time up to but not including the
        microsecond represented by a_datetime

        Raises a ValueError when a_datetime is in the future and
        is_ongoing is true. Thus cannot return a TimeInterval object
        that is ongoing.

        a_datetime - a timezone aware datetime object

        """

        # Note that this will raise the required ValueError if
        # a_datetime is in the future
        if not self.contains(a_datetime):
            return EmptyTimeInterval()
        
        # If the split point is not in the future, the time in this
        # interval before a_datetime is just the time before
        # a_datetime in the bounded subinterval of this ongoing
        # interval that measures the time that has already occurred
        up_to_now = BoundedTimeInterval(self.first, LocalTimezone.now())
        return up_to_now.subinterval_before(a_datetime)