Test date/time against a time period expressed in a simple grammar
Project description
# Timeswitch: Time Period Expression Language #
Timeswitch allows dates to be tested against a time range to see if they are contained within the
time range. Time ranges are expressed using a simple grammar that supports absolute dates and
times, repeating periods, greater, less than, between and exact match comparisons, and combinations
of brackets and infix notation logical operators.
A time is made up of the following ordered components, with sensible defaults for
components when omitted:
* *year:* range expression with values 1-9999
* *month:* range expression with integer values 1-12 or case insensitive jan, feb, mar, apr, may,
jun, jul, aug, sep, oct, nov, dec
* *day:* range expression with either integer values 1-31 or case insensitive mon, tue, wed, thu,
fri, sat, sun. When used with a month a weekday has an optional ordinal 1st, 2nd, 3rd, 4th or
5th prefix to indicate nth weekday in the month
* *hour-minute:* range expression with two integer values separated by a colon 0-23:0-59
* *compound:* range expression with all or partial non ambiguous sequences of year month day
hour-minute values
The expected month, weekday and ordinal strings can be overriden if necessary using the API.
A time range expression is similar to Python array syntax:
* `-` is any value
* `x` is a value = x
* `x-y` is a value x ≤ value ≤ y. Note that:
* The expressions on either side of the `-` must specify the same rightmost elements, e.g
`2017 jan - feb` not `2017 jan - feb 12`
* The repeat period of the right hand side must be the same as or more frequent thant the first
e.g `jan - 2017 feb` is not valid
* For weekday ranges, Monday is considered the start of the week
* `-x` is a value less than or equal to x
* `x-` is a value greater than or equal to x
Time range expressions can be combined using `and`, `or`, `not` and `( )` to form nested
expressions.
The empty string is always off. A dash is always on:
```-```
Always on from 1:30am on the 3rd of April 2017:
```2017 apr 3 1:30 -```
Always on every Friday on or after the 3rd of April 2017 (year and month can be omitted because
'fri' is unambiguously a weekday):
```fri and 2017 apr 3 -```
Always on every 1st Friday of the month on or after the 3rd of April 2017:
```1st fri and 2017 apr 3 -```
Always on every 1st or 3rd Friday of the month on or after the 3rd of April 2017:
```(1st fri or 3rd fri) and 2017 apr 3 -```
First Friday of the month between 6:30pm and 9:50pm:
```1st fri 18:30-21:50```
Thanksgiving, Christmas, Boxing Day and New Year's Day:
```nov 4th thu or dec 25 or dec 26 or jan 1```
Normal operator precedence is `not`, `and`, `or`. Parenthesis can be used to change this:
```not((jun or aug) and 2017)```
## Usage ##
A command line interface for timeswitch is available:
```bash
$ timeswitch
usage: timeswitch [-h] [-d] [-w] [-y] [-a] [-p] expression [date]
timeswitch: error: too few arguments
$ timeswitch "2017 jan 20 -"
on
$ echo $?
0
$ timeswitch "1972 dec 5 - 1975 nov 11"
off
$ echo $?
1
$
```
The `--year`, `--week`, and `--day` options provide helpful visualisations when developing and
debugging timeswitch expressions.
To use the library directly in Python:
```python
from timeswitch import timeswitch
from datetime import datetime
ts = timeswitch('2017 may 4 20:20 - 20:30')
print ts(datetime(2017, 5, 4, 20, 21)) # True
print ts(datetime(2017, 5, 4, 20, 31)) # False
```
`timeswitch()` accepts optional named `months`, `weekdays` and `ordinal` arguments. Each is an
array of alternative literal strings used when parsing the corresponding date part, for example if
you want to write 'first wed' instead of '1st wed':
```python
ts = timeswitch('first wed', ordinals='first second third fourth fifth'.split(' '))
```
## Contributing ##
You may contribute to the project by logging issues through the project issue tracker or by
submitting a pull request.
### Development ###
A development environment may be setup like this:
```bash
git clone https://bitbucket.org/rocketboots/timeswitch.git
cd timeswitch
pip install -e .[test]
python setup.py nosetests
```
Contributions should include passing unit tests.
Timeswitch allows dates to be tested against a time range to see if they are contained within the
time range. Time ranges are expressed using a simple grammar that supports absolute dates and
times, repeating periods, greater, less than, between and exact match comparisons, and combinations
of brackets and infix notation logical operators.
A time is made up of the following ordered components, with sensible defaults for
components when omitted:
* *year:* range expression with values 1-9999
* *month:* range expression with integer values 1-12 or case insensitive jan, feb, mar, apr, may,
jun, jul, aug, sep, oct, nov, dec
* *day:* range expression with either integer values 1-31 or case insensitive mon, tue, wed, thu,
fri, sat, sun. When used with a month a weekday has an optional ordinal 1st, 2nd, 3rd, 4th or
5th prefix to indicate nth weekday in the month
* *hour-minute:* range expression with two integer values separated by a colon 0-23:0-59
* *compound:* range expression with all or partial non ambiguous sequences of year month day
hour-minute values
The expected month, weekday and ordinal strings can be overriden if necessary using the API.
A time range expression is similar to Python array syntax:
* `-` is any value
* `x` is a value = x
* `x-y` is a value x ≤ value ≤ y. Note that:
* The expressions on either side of the `-` must specify the same rightmost elements, e.g
`2017 jan - feb` not `2017 jan - feb 12`
* The repeat period of the right hand side must be the same as or more frequent thant the first
e.g `jan - 2017 feb` is not valid
* For weekday ranges, Monday is considered the start of the week
* `-x` is a value less than or equal to x
* `x-` is a value greater than or equal to x
Time range expressions can be combined using `and`, `or`, `not` and `( )` to form nested
expressions.
The empty string is always off. A dash is always on:
```-```
Always on from 1:30am on the 3rd of April 2017:
```2017 apr 3 1:30 -```
Always on every Friday on or after the 3rd of April 2017 (year and month can be omitted because
'fri' is unambiguously a weekday):
```fri and 2017 apr 3 -```
Always on every 1st Friday of the month on or after the 3rd of April 2017:
```1st fri and 2017 apr 3 -```
Always on every 1st or 3rd Friday of the month on or after the 3rd of April 2017:
```(1st fri or 3rd fri) and 2017 apr 3 -```
First Friday of the month between 6:30pm and 9:50pm:
```1st fri 18:30-21:50```
Thanksgiving, Christmas, Boxing Day and New Year's Day:
```nov 4th thu or dec 25 or dec 26 or jan 1```
Normal operator precedence is `not`, `and`, `or`. Parenthesis can be used to change this:
```not((jun or aug) and 2017)```
## Usage ##
A command line interface for timeswitch is available:
```bash
$ timeswitch
usage: timeswitch [-h] [-d] [-w] [-y] [-a] [-p] expression [date]
timeswitch: error: too few arguments
$ timeswitch "2017 jan 20 -"
on
$ echo $?
0
$ timeswitch "1972 dec 5 - 1975 nov 11"
off
$ echo $?
1
$
```
The `--year`, `--week`, and `--day` options provide helpful visualisations when developing and
debugging timeswitch expressions.
To use the library directly in Python:
```python
from timeswitch import timeswitch
from datetime import datetime
ts = timeswitch('2017 may 4 20:20 - 20:30')
print ts(datetime(2017, 5, 4, 20, 21)) # True
print ts(datetime(2017, 5, 4, 20, 31)) # False
```
`timeswitch()` accepts optional named `months`, `weekdays` and `ordinal` arguments. Each is an
array of alternative literal strings used when parsing the corresponding date part, for example if
you want to write 'first wed' instead of '1st wed':
```python
ts = timeswitch('first wed', ordinals='first second third fourth fifth'.split(' '))
```
## Contributing ##
You may contribute to the project by logging issues through the project issue tracker or by
submitting a pull request.
### Development ###
A development environment may be setup like this:
```bash
git clone https://bitbucket.org/rocketboots/timeswitch.git
cd timeswitch
pip install -e .[test]
python setup.py nosetests
```
Contributions should include passing unit tests.
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.
Source Distribution
timeswitch-1.0.0.tar.gz
(12.8 kB
view hashes)
Built Distribution
Close
Hashes for timeswitch-1.0.0-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1eeb56b50de0871a37816ace3b21336fdffc9f5624aa951c7f5b9ed30bc55314 |
|
MD5 | bdf17a00fe55f152ad1497b428def867 |
|
BLAKE2b-256 | 6d09ce9be3ac91080fe26f3a1e092272cc4670a89dfa0cdc4993b9c46c2edbfc |