timespan and scheduling helpers for Python
Project description
>>> import datetime >>> from timelines import timespan, timelayer
A timespan object has a start time and an end time. It can be created either by specifying a start time and an elapsed time, or by specifying both start and end times:
>>> span1 = timespan(datetime.datetime(1984, 11, 26), datetime.timedelta(1)) >>> span2 = timespan(datetime.datetime(1984, 11, 26) + datetime.timedelta(2), datetime.datetime(1984, 11, 26) + datetime.timedelta(2, 50)) >>> span1.start datetime.datetime(1984, 11, 26, 0, 0) >>> span1.elapsed datetime.timedelta(1)
The elapsed time of a timespan is the timedelta between its start and end times:
>>> span1.elapsed == span1.end - span1.start True
A timelayer object is a sorted bag of non-overlapping timespans which know the order in which they occur:
>>> layer = timelayer(span2, span1) >>> list(layer) == [span1, span2] True
Just like a timespan, a timelayer knows its own start and end times:
>>> layer.start == span1.start True >>> layer.end == span2.end True
The elapsed duration of a timelayer is the sum of the elapsed durations of the timespans it contains, NOT the delta between its start and end times:
>>> layer.elapsed == span1.elapsed + span2.elapsed True >>> layer.elapsed == layer.end - layer.start False
You can add new timespans to a timelayer:
>>> layer.start datetime.datetime(1984, 11, 26, 0, 0) >>> layer.end datetime.datetime(1984, 11, 28, 0, 0, 50)
>>> layer.add(timespan(datetime.datetime(1984, 11, 26) - datetime.timedelta(1), datetime.timedelta(0, 600))) >>> layer.start datetime.datetime(1984, 11, 25, 0, 0) >>> layer.end datetime.datetime(1984, 11, 28, 0, 0, 50)
However, you cannot add new timespans which overlap any existing timespans:
>>> layer.add(timespan(datetime.datetime(1984, 11, 26) - datetime.timedelta(2), datetime.timedelta(2))) Traceback (most recent call last): ... RuntimeError: <timelayer datetime.datetime(1984, 11, 24, 0, 0) => datetime.datetime(1984, 11, 26, 0, 0) (contains 1 timespans)> overlaps <timespan datetime.datetime(1984, 11, 25, 0, 0) => datetime.datetime(1984, 11, 25, 0, 10)>
>>> layer.add(timespan(datetime.datetime(1984, 11, 26) - datetime.timedelta(1) + datetime.timedelta(0, 300), datetime.timedelta(0, 600))) Traceback (most recent call last): ... RuntimeError: <timelayer datetime.datetime(1984, 11, 25, 0, 5) => datetime.datetime(1984, 11, 25, 0, 15) (contains 1 timespans)> overlaps <timespan datetime.datetime(1984, 11, 25, 0, 0) => datetime.datetime(1984, 11, 25, 0, 10)>
>>> layer.add(timespan(datetime.datetime(1984, 11, 26) + datetime.timedelta(0, 300), datetime.timedelta(0, 1200))) Traceback (most recent call last): ... RuntimeError: <timelayer datetime.datetime(1984, 11, 26, 0, 5) => datetime.datetime(1984, 11, 26, 0, 25) (contains 1 timespans)> overlaps <timespan datetime.datetime(1984, 11, 26, 0, 0) => datetime.datetime(1984, 11, 27, 0, 0)>
You can also add constraints to a timelayer. Constraints allow you to freeze the start time and/or end time of a timelayer, or to put an upper bound on the total elapsed time of a layer. New timespans cannot be added to a layer if they fail its constraints:
>>> layer.freeze_start() >>> layer.add(timespan(datetime.datetime(1984, 11, 26) - datetime.timedelta(4), datetime.timedelta(2))) Traceback (most recent call last): ... RuntimeError: datetime.datetime(1984, 11, 22, 0, 0) is earlier than frozen start datetime.datetime(1984, 11, 25, 0, 0)
>>> layer.freeze_elapsed(datetime.timedelta(3)) >>> layer.add(timespan(datetime.datetime(1985, 11, 26), datetime.datetime(1985, 11, 29))) Traceback (most recent call last): ... RuntimeError: Total elapsed time datetime.timedelta(4, 650) is greater than frozen allowed elapsed time datetime.timedelta(3)
>>> layer.freeze_end(datetime.datetime(1985, 11, 27)) >>> layer.add(timespan(datetime.datetime(1985, 11, 26, 23), datetime.datetime(1985, 11, 27, 1))) Traceback (most recent call last): ... RuntimeError: datetime.datetime(1985, 11, 27, 1, 0) is later than frozen end datetime.datetime(1985, 11, 27, 0, 0)
Changelog
0.2 (2012-06-15)
- Implement timelayer.freeze_elapsed constraint, allowing the user to cap the total allowed elapsed time of a layer to a given timedelta
- Fix a bug in the guaranteed-sortedness of timelayers, by implementing timespan.__cmp___
- Fix a bug in the collision detection of timelayer.add, by checking collisions against each timespan in the existing layer independently, instead of just checking against the layer’s boundaries
- Exceptions during timelayer.add now provide more information about why the operation failed
0.1 (2012-06-13)
- Initial release, everything is new!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.