Skip to content

Commit 327e2d4

Browse files
authored
Merge pull request #118 from dh-tech/release/0.4
Release v0.4
2 parents 397ee12 + 6098361 commit 327e2d4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2052
-672
lines changed

.github/workflows/check.yml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,28 @@ jobs:
1717
uses: actions/setup-python@v5
1818
with:
1919
python-version: "3.12"
20-
cache: 'pip'
21-
cache-dependency-path: '**/pyproject.toml'
22-
- name: Install package with development dependencies
23-
run: pip install -e ".[dev]"
20+
21+
- name: Install uv
22+
uses: astral-sh/setup-uv@v5
23+
with:
24+
enable-cache: true
25+
cache-dependency-glob: "pyproject.toml"
26+
27+
- name: Install package with check dependencies
28+
run: uv sync --extra check
2429

2530
# check with ruff
2631
- name: Run ruff
27-
run: ruff check
32+
run: uv run ruff check
2833

2934
# check docs build
3035
- name: Check that documentation builds with no errors or warnings
31-
run: sphinx-build docs docs/_build --fail-on-warning
36+
run: uv run sphinx-build docs docs/_build --fail-on-warning
3237

3338
# check types with mypy
3439
- name: Check types in python src directory; install needed types
35-
run: mypy --install-types --non-interactive src
40+
run: uv run mypy --install-types --non-interactive src
3641

3742
# use treon to make sure that example notebooks run
3843
- name: Check jupyter notebooks with treon
39-
run: treon
44+
run: uv run treon

.github/workflows/unit_tests.yml

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ on:
88
- 'undate/**'
99
- 'tests/**'
1010
pull_request:
11+
branches:
12+
- "**"
1113

1214
env:
1315
# python version used to calculate and submit code coverage
@@ -18,30 +20,37 @@ jobs:
1820
runs-on: ubuntu-latest
1921
strategy:
2022
matrix:
21-
python: ["3.9", "3.10", "3.11", "3.12", "3.13"]
23+
python: ["3.10", "3.11", "3.12", "3.13"]
2224
defaults:
2325
run:
2426
working-directory: .
2527

2628
steps:
27-
- uses: actions/checkout@v3
28-
- name: Set up Python ${{ matrix.python-version }}
29-
uses: actions/setup-python@v4
29+
- uses: actions/checkout@v4
30+
31+
# use github python action instead of uv to take advantage of caching
32+
- name: Set up Python ${{ matrix.python }}
33+
uses: actions/setup-python@v5
3034
with:
3135
python-version: ${{ matrix.python }}
32-
cache: 'pip'
33-
cache-dependency-path: '**/pyproject.toml'
34-
- name: Install package with dependencies
35-
run: pip install -e ".[test]"
36+
37+
- name: Install uv
38+
uses: astral-sh/setup-uv@v5
39+
with:
40+
enable-cache: true
41+
cache-dependency-glob: "pyproject.toml"
42+
43+
- name: Install package with dev and test dependencies
44+
run: uv sync --extra test
3645

3746
# for all versions but the one we use for code coverage, run normally
3847
- name: Run unit tests normally
39-
run: pytest
48+
run: uv run pytest
4049
if: ${{ matrix.python != env.COV_PYTHON_VERSION }}
4150

4251
# run code coverage in one version only
4352
- name: Run unit tests with code coverage reporting
44-
run: pytest --cov=undate
53+
run: uv run pytest --cov=undate
4554
if: ${{ matrix.python == env.COV_PYTHON_VERSION }}
4655
- name: Upload test coverage to Codecov
4756
uses: codecov/codecov-action@v3

CHANGELOG.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Change Log
22

3+
## 0.4
4+
5+
- Undate is now Calendar aware / Calendar explicit; default is Gregorian
6+
- New `BaseCalendarConverter` class, with additional methods required for calendar converters
7+
- `HebrewDateConverter`: Parsing and calendar conversion for Hebrew/Anno Mundi
8+
- `IslamicDateConverter`: Parsing and calendar conversion for Islamic/Hijri
9+
- `GregorianDateConverter`: basic Gregorian calendar logic
10+
- `undate.Calendar` class to track `Undate` object calendar, and match with calendar converters
11+
- BaseDateConverter class now includes nested/descendant subclasses when looking
12+
for available converters
13+
- `Undate.to_undate` method to convert supported date objects to `Undate` (`datetime.date`, `datetime.datetime`, and internal `undate.date.Date` class)
14+
- `UndateInterval` improvements
15+
- Can be initialized with `Undate` objects or any type supported by `Undate.to_undate`
16+
- New method for contains (`in`), to determine if another interval or date is contained by an interval
17+
- New method `intersection` to determine the overlap between two `UndateInterval` objects
18+
- EDTF parser : fixed day parsing for some unsupported cases
19+
- Dropped support for Python 3.9
20+
- Reorganized examples folder to avoid unnecessary nesting
21+
- ISMI data has been updated from older JSON data to examples in RDF (turtle)
22+
23+
324
## 0.3.1
425

526
Update readthedocs config for current installation
@@ -14,7 +35,7 @@ Update readthedocs config for current installation
1435
- Support 5+ digit years with leading Y (thanks to numpy.datetime64)
1536
- Jupyter notebook demonstrating / validating EDTF support
1637
- Full support for Level 0 Date and Time Interval (no Date and Time support)
17-
- Level 1:
38+
- Level 1:
1839
- Letter-prefixed calendar year
1940
- Unspecified digit from the right
2041
- Partial support for extended interval

README.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
**undate** is a python library for working with uncertain or partially known dates.
66

77
> [!WARNING]
8-
> This is pre-alpha software and is **NOT** feature complete! Use with caution.
9-
> Currently it only supports parsing and formatting dates in ISO8601 format and
10-
> some portions of EDTF (Extended Date Time Format).
8+
> This is alpha software and is not yet feature complete! Use with caution and give us feedback.
9+
> Currently `undate` supports parsing and formatting dates in ISO8601, some
10+
portions of EDTF (Extended Date Time Format), and parsing and conversion for dates in Hebrew Anno Mundi and Islamic Hijri calendars
1111

1212
*Undate was initially created as part of a [DH-Tech](https://dh-tech.github.io/) hackathon in November 2022.*
1313

14-
---
14+
* * *
1515

1616
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.11068867.svg)](https://doi.org/10.5281/zenodo.11068867)
1717
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
@@ -140,7 +140,7 @@ An `UndateInterval` is a date range between two `Undate` objects. Intervals can
140140
```
141141

142142
You can initialize `Undate` or `UndateInterval` objects by parsing a date string with a specific converter, and you can also output an `Undate` object in those formats.
143-
Available converters are "ISO8601" and "EDTF" (but only)
143+
Currently available converters are "ISO8601" and "EDTF" and supported calendars.
144144

145145
```python
146146
>>> from undate import Undate
@@ -156,7 +156,34 @@ Available converters are "ISO8601" and "EDTF" (but only)
156156
<UndateInterval 1800/1900>
157157
```
158158

159-
For more examples, refer to the [example notebooks](https://github.com/dh-tech/undate-python/tree/main/examples/notebooks/) included in this repository.
159+
### Calendars
160+
161+
All `Undate` objects are calendar aware, and date converters include support for parsing and working with dates from other calendars. The Gregorian calendar is used by default; currently `undate` supports the Islamic Hijri calendar and the Hebrew Anno Mundi calendar based on calendar conversion logic implemented in the [convertdate](https://convertdate.readthedocs.io/en/latest/) package.
162+
163+
Dates are stored with the year, month, day and appropriate precision for the original calendar; internally, earliest and latest dates are calculated in Gregorian / Proleptic Gregorian calendar for standardized comparison across dates from different calendars.
164+
165+
```python
166+
>>> from undate import Undate
167+
>>> tammuz4816 = Undate.parse("26 Tammuz 4816", "Hebrew")
168+
>>> tammuz4816
169+
<Undate '26 Tammuz 4816 Anno Mundi' 4816-04-26 (Hebrew)>
170+
>>> rajab495 = Undate.parse("Rajab 495", "Islamic")
171+
>>> rajab495
172+
<Undate 'Rajab 495 Hijrī' 0495-07 (Islamic)>
173+
>>> y2k = Undate.parse("2001", "EDTF")
174+
>>> y2k
175+
<Undate 2001 (Gregorian)>
176+
>>> [str(d.earliest) for d in [rajab495, tammuz4816, y2k]]
177+
['1102-04-28', '1056-07-17', '2001-01-01']
178+
>>> [str(d.precision) for d in [rajab495, tammuz4816, y2k]]
179+
['MONTH', 'DAY', 'YEAR']
180+
>>> sorted([rajab495, tammuz4816, y2k])
181+
[<Undate '26 Tammuz 4816 Anno Mundi' 4816-04-26 (Hebrew)>, <Undate 'Rajab 495 Hijrī' 0495-07 (Islamic)>, <Undate 2001 (Gregorian)>]
182+
```
183+
184+
* * *
185+
186+
For more examples, refer to the code notebooks included in the [examples](https://github.com/dh-tech/undate-python/tree/main/examples/) in this repository.
160187

161188
## Documentation
162189

docs/undate/converters.rst

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
Converters
22
==========
33

4+
Overview
5+
--------
6+
47
.. automodule:: undate.converters.base
58
:members:
69
:undoc-members:
710

11+
Formats
12+
--------
13+
814
ISO8601
9-
-------
15+
^^^^^^^
1016

1117
.. automodule:: undate.converters.iso8601
1218
:members:
1319
:undoc-members:
1420

1521
Extended Date-Time Format (EDTF)
16-
--------------------------------
22+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1723

1824
.. automodule:: undate.converters.edtf.converter
1925
:members:
@@ -23,8 +29,25 @@ Extended Date-Time Format (EDTF)
2329
:members:
2430
:undoc-members:
2531

26-
.. transformer is more of an internal, probably doesn't make sense to include
27-
.. .. automodule:: undate.converters.edtf.transformer
28-
.. :members:
29-
.. :undoc-members:
32+
33+
Calendars
34+
---------
35+
36+
Gregorian
37+
^^^^^^^^^
38+
39+
.. automodule:: undate.converters.calendars.gregorian
40+
:members:
41+
42+
Hebrew Anno Mundi calendar
43+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44+
45+
.. automodule:: undate.converters.calendars.hebrew.converter
46+
:members:
47+
48+
Islamic Hijri calendar
49+
^^^^^^^^^^^^^^^^^^^^^^^^
50+
51+
.. automodule:: undate.converters.calendars.islamic.converter
52+
:members:
3053

docs/undate/core.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
Undate objects
22
==============
33

4-
undates and undate intervals
4+
dates, intervals, and calendar
55
------------------------------
66

77
.. autoclass:: undate.undate.Undate
88
:members:
99

10-
.. autoclass:: undate.undate.UndateInterval
10+
.. autoclass:: undate.undate.Calendar
11+
:members:
12+
13+
.. autoclass:: undate.interval.UndateInterval
1114
:members:
1215

1316
date, timedelta, and date precision

examples/README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
# undate examples
22

3-
Example data and projects with use cases for uncertain date logic and
4-
example code notebooks using undate.
5-
6-
- [use cases](use-cases) - examples from projects or specific data with use cases for undate
7-
- [notebooks](notebooks) - code notebooks showing how undate can be used on a specific dataset or for a specific problem
3+
This folder contains code notebooks demonstrating how `undate` can be
4+
used on a specific dataset, problem, or format, as well as example
5+
data from projects with use cases for uncertain date logic.
6+
7+
## Contents
8+
9+
- [EDTF support](edtf-support.ipynb) - demonstrate and validate supported portions of the Extended Date Time Format (EDTF) specification (jupyter notebook)
10+
- [ISMI](ismi) - Sample data from the Islamic Scientific Manuscript Initiative project
11+
- [Shakespeare and Company Project](shakespeare-and-company-project) - data, description of partial date implementation, and example notebook
12+
- Events data from version 1.2 of Shakespeare and Company Project datasets
13+
- [Partial date duration logic](shakespeare-and-company-project/shxco_partial_date_durations.ipynb) - compare `undate` partial date range duration logic with a previous implementation in the _Shakespeare and Company Project_ (jupyter notebook)

examples/notebooks/edtf-support.ipynb renamed to examples/edtf-support.ipynb

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
},
5656
{
5757
"cell_type": "code",
58-
"execution_count": 2,
58+
"execution_count": 1,
5959
"id": "9c6b7379-b2a7-4ec1-afa5-2cd9832c8a5d",
6060
"metadata": {},
6161
"outputs": [],
@@ -92,7 +92,7 @@
9292
},
9393
{
9494
"cell_type": "code",
95-
"execution_count": 3,
95+
"execution_count": 2,
9696
"id": "923476ff-344a-4018-a02e-6e5f80ea76a8",
9797
"metadata": {},
9898
"outputs": [],
@@ -159,7 +159,7 @@
159159
},
160160
{
161161
"cell_type": "code",
162-
"execution_count": 4,
162+
"execution_count": 3,
163163
"id": "6ed422de-34a2-4324-b254-f62db00563f7",
164164
"metadata": {},
165165
"outputs": [],
@@ -212,7 +212,7 @@
212212
},
213213
{
214214
"cell_type": "code",
215-
"execution_count": 5,
215+
"execution_count": 4,
216216
"id": "8d98a139-627b-40bd-b1c5-d0028e538a53",
217217
"metadata": {},
218218
"outputs": [],
@@ -255,7 +255,7 @@
255255
},
256256
{
257257
"cell_type": "code",
258-
"execution_count": 6,
258+
"execution_count": 5,
259259
"id": "532470db-851e-4f91-9242-cd93d35054cf",
260260
"metadata": {},
261261
"outputs": [],
@@ -320,7 +320,7 @@
320320
},
321321
{
322322
"cell_type": "code",
323-
"execution_count": 7,
323+
"execution_count": 6,
324324
"id": "a5abd0e4-0b26-49b0-bf78-3e1fe6c046d8",
325325
"metadata": {},
326326
"outputs": [],
@@ -425,7 +425,7 @@
425425
},
426426
{
427427
"cell_type": "code",
428-
"execution_count": 8,
428+
"execution_count": 7,
429429
"id": "e47f3fff-d35c-4c2e-9568-214763f6511a",
430430
"metadata": {},
431431
"outputs": [],
@@ -481,7 +481,7 @@
481481
},
482482
{
483483
"cell_type": "code",
484-
"execution_count": 9,
484+
"execution_count": 8,
485485
"id": "39143c1f-932a-450c-9b2d-ffbe3e1416b0",
486486
"metadata": {},
487487
"outputs": [],
@@ -535,7 +535,7 @@
535535
},
536536
{
537537
"cell_type": "code",
538-
"execution_count": 10,
538+
"execution_count": 9,
539539
"id": "95965f17-0bd5-446f-bc09-9503eaed68e2",
540540
"metadata": {},
541541
"outputs": [],
@@ -589,7 +589,7 @@
589589
},
590590
{
591591
"cell_type": "code",
592-
"execution_count": 11,
592+
"execution_count": 10,
593593
"id": "c6c2d1a1-39f1-45eb-ac08-1de4fadbe842",
594594
"metadata": {},
595595
"outputs": [],
@@ -640,7 +640,7 @@
640640
},
641641
{
642642
"cell_type": "code",
643-
"execution_count": 12,
643+
"execution_count": 11,
644644
"id": "f24fd31a-176a-40b5-bff4-d72b68f32a18",
645645
"metadata": {},
646646
"outputs": [],
@@ -688,7 +688,7 @@
688688
},
689689
{
690690
"cell_type": "code",
691-
"execution_count": 13,
691+
"execution_count": 12,
692692
"id": "5910caab-eada-4715-b863-9bbbb15b9c5c",
693693
"metadata": {},
694694
"outputs": [],

0 commit comments

Comments
 (0)