Source code for irfpy.util.timeinterval

''' Time inteval module.

.. codeauthor:: Yoshifumi Futaana

It provides :class:`timeinterval` class.
'''
import copy
import datetime

import sympy
from irfpy.util.utc import date2num, num2date


[docs]class timeinterval: ''' Time interval class. Time interval and some calculation. Time interval can be defined. A simple interval (continuous one block) is instance as follows. >>> t0 = datetime.datetime(2010, 1, 1, 12, 0, 0) >>> t1 = datetime.datetime(2010, 1, 5, 12, 0, 0) >>> tint = timeinterval(t0, t1) >>> print(tint) Interval(733773.500000000, 733777.500000000) The ``print`` function print out in the matplotlib's floating point format (*date2num*). One can check if the specific time is inside or outside of the interval as follows. >>> t0 in tint True >>> t1 in tint True >>> datetime.datetime(2010, 1, 3) in tint True You can add the intervals using "plus" operator. >>> t2 = datetime.datetime(2010, 2, 1, 12, 0, 0) >>> t3 = datetime.datetime(2010, 2, 5, 12, 0, 0) >>> tint2 = tint + timeinterval(t2, t3) >>> t0 in tint2 True >>> t1 in tint2 True >>> t2 in tint2 True >>> t3 in tint2 True >>> t2 in tint False >>> t3 in tint False You can subtract the specific interval using minus operator. >>> tint3 = tint2 - tint >>> t0 in tint3 False >>> t1 in tint3 False >>> t2 in tint3 True >>> t3 in tint3 True The earliest/latest time in the interval can be obtained by :meth:`left_time` and :meth:`right_time` methods. >>> print(tint.left_time()) 2010-01-01 12:00:00 >>> print(tint.right_time()) 2010-01-05 12:00:00 The interval can be converted to the discrete tuple of times using :meth:`sampling` method. >>> t_sample = tint2.sampling(datetime.timedelta(days=1)) >>> for t in t_sample: print(t) 2010-01-01 12:00:00 2010-01-02 12:00:00 2010-01-03 12:00:00 2010-01-04 12:00:00 2010-01-05 12:00:00 2010-02-01 12:00:00 2010-02-02 12:00:00 2010-02-03 12:00:00 2010-02-04 12:00:00 2010-02-05 12:00:00 *Developer information* Delegate to the :class:`sympy:sympy.Interval`. ''' def __init__(self, start, end, left_open=False, right_open=False): t0 = date2num(start) t1 = date2num(end) self.interval = sympy.Interval(t0, t1, left_open=left_open, right_open=right_open) def __contains__(self, t_datetime): d = date2num(t_datetime) return d in self.interval def __add__(self, other): ret = copy.copy(self) ret.interval += other.interval return ret def __sub__(self, other): ret = copy.copy(self) ret.interval -= other.interval return ret def __repr__(self): return str(self.interval) def __str__(self): return str(self.interval)
[docs] def left(self): """ Return the left-most time (in float). """ return min(self.interval.boundary)
[docs] def right(self): """ Return the right-most time (in float). """ return max(self.interval.boundary)
[docs] def left_time(self): """ Return the left-most time """ return num2date(float(self.left())).replace(tzinfo=None)
[docs] def right_time(self): """ Return the right-most time """ return num2date(float(self.right())).replace(tzinfo=None)
[docs] def sampling(self, dt, t0=None): """ Return the list of the time with sampling time *dt*. :param dt: :class:`datetime.timedelta` object that specifies the sampling time. :keyword t0: If given in :class:`datetime.datetime` object, the start time of the sampling can be specified. Default start time is :meth:`left_time`. :return: Tuple of the time that in inside the interval. >>> tint = timeinterval(datetime.datetime(2010, 3, 10, 1, 30), datetime.datetime(2010, 3, 10, 1, 40)) >>> tint = tint - timeinterval(datetime.datetime(2010, 3, 10, 1, 31, 30), datetime.datetime(2010, 3, 10, 1, 37, 30)) >>> tint = tint - timeinterval(datetime.datetime(2010, 3, 10, 1, 38, 30), datetime.datetime(2010, 3, 10, 1, 39, 30)) >>> print(tint) Union(Interval.Ropen(733841.062500000, 733841.063541667), Interval.open(733841.067708333, 733841.068402778), Interval.Lopen(733841.069097222, 733841.069444444)) >>> print(tint.sampling(datetime.timedelta(minutes=1))) (datetime.datetime(2010, 3, 10, 1, 30), datetime.datetime(2010, 3, 10, 1, 31), datetime.datetime(2010, 3, 10, 1, 38), datetime.datetime(2010, 3, 10, 1, 40)) """ if t0 is None: t0 = self.left_time() t1 = self.right_time() from irfpy.util import utc tlist = utc.dtrange(t0, t1 + dt, dt) t_true = tuple([t for t in tlist if t in self]) return t_true
[docs]def empty_interval(): ''' Return :class:`timeinterval` object with empty interval. >>> empty = empty_interval() >>> print(empty) EmptySet >>> intvl0 = timeinterval(datetime.datetime(1975, 10, 10), datetime.datetime(1998, 1, 10)) >>> intvl1 = empty + intvl0 >>> print(intvl0) Interval(721271.000000000, 729399.000000000) >>> print(intvl1) Interval(721271.000000000, 729399.000000000) ''' # Quick-durty way. t0 > t1, then returning empty for sympy.Interval. return timeinterval(datetime.datetime(2000, 1, 1), datetime.datetime(1999, 1, 1))