Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: dh-tech/undate-python
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.2
Choose a base ref
...
head repository: dh-tech/undate-python
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 45,630 additions and 1,461 deletions.
  1. +21 −5 .all-contributorsrc
  2. +25 −16 .github/workflows/check.yml
  3. +24 −15 .github/workflows/unit_tests.yml
  4. +3 −0 .gitignore
  5. +11 −4 .pre-commit-config.yaml
  6. +1 −0 .pythonversion
  7. +6 −3 .readthedocs.yaml
  8. +69 −0 CHANGELOG.md
  9. +31 −0 CITATION.cff
  10. +41 −6 CONTRIBUTING.md
  11. +52 −0 CONTRIBUTORS.md
  12. +91 −0 DEVELOPER_NOTES.md
  13. +199 −111 README.md
  14. BIN _static/undate_logo.png
  15. +14 −0 codecov.yml
  16. +2 −0 docs/CONTRIBUTING.md
  17. +2 −0 docs/CONTRIBUTORS.md
  18. +2 −0 docs/DEVELOPER_NOTES.md
  19. +4 −0 docs/LICENSE.md
  20. +7 −0 docs/_static/custom.css
  21. BIN docs/_static/dhtech-logo.png
  22. +32 −0 docs/_static/dhtech-logo.svg
  23. BIN docs/_static/logo.png
  24. BIN docs/_static/undate_logo.png
  25. +8 −0 docs/_templates/sidebar_dhtech.html
  26. +0 −1 docs/authors.rst
  27. +35 −7 docs/conf.py
  28. +7 −5 docs/index.rst
  29. +0 −3 docs/license.rst
  30. +4 −0 docs/readme.md
  31. +0 −3 docs/readme.rst
  32. +0 −4 docs/requirements.txt
  33. +0 −11 docs/undate.rst
  34. +53 −0 docs/undate/converters.rst
  35. +25 −0 docs/undate/core.rst
  36. +9 −0 docs/undate/index.rst
  37. +13 −0 examples/README.md
  38. +799 −0 examples/edtf-support.ipynb
  39. +16 −18 examples/ismi/README.md
  40. +104 −0 examples/ismi/data/ismi-crm-date-samples.ttl
  41. +0 −186 examples/ismi/data/ismi-om4-date-samples.json
  42. +4,406 −0 examples/pgp_dates.ipynb
  43. +24 −0 examples/shakespeare-and-company-project/README.md
  44. +35,525 −0 examples/shakespeare-and-company-project/SCoData_events_v1.2_2022-01.csv
  45. +286 −352 examples/{notebooks → shakespeare-and-company-project}/shxco_partial_date_durations.ipynb
  46. +90 −4 pyproject.toml
  47. +0 −4 pytest.ini
  48. +0 −115 setup.cfg
  49. +0 −4 setup.py
  50. +7 −1 src/undate/__init__.py
  51. +1 −0 src/undate/converters/__init__.py
  52. +206 −0 src/undate/converters/base.py
  53. +11 −0 src/undate/converters/calendars/__init__.py
  54. +81 −0 src/undate/converters/calendars/gregorian.py
  55. +3 −0 src/undate/converters/calendars/hebrew/__init__.py
  56. +113 −0 src/undate/converters/calendars/hebrew/converter.py
  57. +62 −0 src/undate/converters/calendars/hebrew/hebrew.lark
  58. +9 −0 src/undate/converters/calendars/hebrew/parser.py
  59. +42 −0 src/undate/converters/calendars/hebrew/transformer.py
  60. +3 −0 src/undate/converters/calendars/islamic/__init__.py
  61. +104 −0 src/undate/converters/calendars/islamic/converter.py
  62. +61 −0 src/undate/converters/calendars/islamic/islamic.lark
  63. +9 −0 src/undate/converters/calendars/islamic/parser.py
  64. +40 −0 src/undate/converters/calendars/islamic/transformer.py
  65. +28 −0 src/undate/converters/calendars/seleucid.py
  66. +1 −0 src/undate/converters/edtf/__init__.py
  67. +105 −0 src/undate/converters/edtf/converter.py
  68. +9 −5 src/undate/{dateformat → converters}/edtf/edtf.lark
  69. +8 −0 src/undate/converters/edtf/parser.py
  70. +11 −6 src/undate/{dateformat → converters}/edtf/transformer.py
  71. +109 −0 src/undate/converters/iso8601.py
  72. +308 −0 src/undate/date.py
  73. +0 −3 src/undate/dateformat/__init__.py
  74. +0 −72 src/undate/dateformat/base.py
  75. 0 src/undate/dateformat/edtf/__init__.py
  76. +0 −46 src/undate/dateformat/edtf/parser.py
  77. +0 −70 src/undate/dateformat/iso8601.py
  78. +183 −0 src/undate/interval.py
  79. +350 −197 src/undate/undate.py
  80. +12 −3 tests/{test_dateformat → test_converters}/edtf/test_edtf_parser.py
  81. +14 −8 tests/{test_dateformat → test_converters}/edtf/test_edtf_transformer.py
  82. +95 −0 tests/test_converters/test_base.py
  83. +40 −0 tests/test_converters/test_calendars/test_gregorian.py
  84. +189 −0 tests/test_converters/test_calendars/test_hebrew/test_hebrew_converter.py
  85. +65 −0 tests/test_converters/test_calendars/test_hebrew/test_hebrew_parser.py
  86. +49 −0 tests/test_converters/test_calendars/test_hebrew/test_hebrew_transformer.py
  87. +174 −0 tests/test_converters/test_calendars/test_islamic/test_islamic_converter.py
  88. +78 −0 tests/test_converters/test_calendars/test_islamic/test_islamic_parser.py
  89. +50 −0 tests/test_converters/test_calendars/test_islamic/test_islamic_transformer.py
  90. +115 −0 tests/test_converters/test_calendars/test_seleucid.py
  91. +70 −0 tests/test_converters/test_edtf.py
  92. +2 −2 tests/{test_dateformat → test_converters}/test_iso8601.py
  93. +272 −0 tests/test_date.py
  94. +0 −65 tests/test_dateformat/test_base.py
  95. +236 −0 tests/test_interval.py
  96. +264 −106 tests/test_undate.py
26 changes: 21 additions & 5 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"files": [
"README.md"
"CONTRIBUTORS.md"
],
"imageSize": 100,
"commit": true,
@@ -14,7 +14,8 @@
"contributions": [
"code",
"review",
"test"
"test",
"ideas"
]
},
{
@@ -38,7 +39,9 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1488847?v=4",
"profile": "https://github.com/robcast",
"contributions": [
"data"
"data",
"ideas",
"review"
]
},
{
@@ -50,7 +53,8 @@
"code",
"review",
"test",
"eventOrganizing"
"eventOrganizing",
"ideas"
]
},
{
@@ -64,6 +68,16 @@
"test",
"doc"
]
},
{
"login": "taylor-arnold",
"name": "Taylor Arnold",
"avatar_url": "https://avatars.githubusercontent.com/u/5752184?v=4",
"profile": "http://taylorarnold.org",
"contributions": [
"review",
"ideas"
]
}
],
"contributorsPerLine": 7,
@@ -72,5 +86,7 @@
"repoType": "github",
"repoHost": "https://github.com",
"projectName": "undate-python",
"projectOwner": "dh-tech"
"projectOwner": "dh-tech",
"badgeTemplate": "![All Contributors](https://img.shields.io/github/all-contributors/dh-tech/undate-python?color=ee8449&style=flat-square)",
"commitType": "docs"
}
41 changes: 25 additions & 16 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -3,6 +3,9 @@ name: Check style + docs + types
on:
pull_request:

permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
@@ -13,26 +16,32 @@ jobs:

steps:
- uses: actions/checkout@v4
- name: Set up Python 3.10
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: 'pip'
cache-dependency-path: '**/setup.cfg'
- name: Install package with dependencies
run: pip install -e ".[dev]"
if: steps.python-cache.outputs.cache-hit != 'true'
python-version: "3.12"

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: "pyproject.toml"

# check code style
- name: Run black
run: black src --check --diff
- name: Install package with check dependencies
run: uv sync --extra check

# check docs
- name: Check that documentation can be built
run: tox -e docs
# check with ruff
- name: Run ruff
run: uv run ruff check

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

# check types with mypy
- name: Install mypy
run: pip install mypy
- name: Check types in python src directory; install needed types
run: mypy --install-types --non-interactive src
run: uv run mypy --install-types --non-interactive src

# use treon to make sure that example notebooks run
- name: Check jupyter notebooks with treon
run: uv run treon
39 changes: 24 additions & 15 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: unit tests

permissions:
contents: read
id-token: write

on:
push:
branches:
@@ -8,45 +12,50 @@ on:
- 'undate/**'
- 'tests/**'
pull_request:
branches:
- "**"

env:
# python version used to calculate and submit code coverage
COV_PYTHON_VERSION: "3.11"
COV_PYTHON_VERSION: "3.12"

jobs:
python-unit:
runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.9", "3.10", "3.11", "3.12"]
python: ["3.10", "3.11", "3.12", "3.13"]
defaults:
run:
working-directory: .

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
- uses: actions/checkout@v4

# use github python action instead of uv to take advantage of caching
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: 'pip'
cache-dependency-path: '**/setup.cfg'
cache-dependency-path: '**/pyproject.toml'

- name: Install package with dependencies
run: |
pip install -e ".[dev]"
python -m pip install tox tox-gh-actions
if: steps.python-cache.outputs.cache-hit != 'true'
run: pip install -e ".[test]"

# for all versions but the one we use for code coverage, run normally
- name: Run unit tests normally
run: tox
- name: Run unit tests without code coverage
run: pytest
if: ${{ matrix.python != env.COV_PYTHON_VERSION }}

# run code coverage in one version only
- name: Run unit tests with code coverage reporting
run: tox -e coverage
run: pytest --cov=.
if: ${{ matrix.python == env.COV_PYTHON_VERSION }}
- name: Upload test coverage to Codecov
uses: codecov/codecov-action@v3

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
if: ${{ matrix.python == env.COV_PYTHON_VERSION }}

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -39,3 +39,6 @@ venv.bak/
# code coverage
.coverage
coverage.xml

# jupyter
.ipynb_checkpoints/
15 changes: 11 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
files: \.py
repos:
- repo: https://github.com/psf/black
rev: 22.10.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.4
hooks:
- id: black
- id: ruff
args: [ --fix, --exit-non-zero-on-fix ]
- id: ruff-format
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
@@ -12,4 +14,9 @@ repos:
- id: debug-statements
- id: end-of-file-fixer
- id: mixed-line-ending
- id: trailing-whitespace
- id: trailing-whitespace
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.13.0
hooks:
- id: mypy
additional_dependencies: [numpy]
1 change: 1 addition & 0 deletions .pythonversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Python 3.12.7
9 changes: 6 additions & 3 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -5,11 +5,14 @@ version: 2
build:
os: "ubuntu-20.04"
tools:
python: "3.9"
python: "3.12"

sphinx:
configuration: docs/conf.py

python:
install:
- requirements: docs/requirements.txt
- method: pip
path: .
extra_requirements:
- docs
69 changes: 69 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,74 @@
# Change Log

## 0.5.1
- Correct license identifier in CITATION.cff so it is valid

## 0.5

- New `UnDelta` and `UnInt` classes for uncertain durations
- `Undate.duration` now returns either a `Timedelta` or an `UnDelta` if the duration is ambiguous
- New properties `possible_years` and `representative_years` on `Undate` class, used for calculating durations for uncertain years and months
- New `weekday` method on class `undate.date.Date`
- Calendar converter improvements:
- Calendar converter classes can optional provide minimum and maximum years for uncertain dates
- New calendar methods `days_in_year` and `representative_years`
- Hebrew date parser now allows for week days, along with additional month variants
- Preliminary Seleucide calendar converter class, based on Hebrew calendar with a year offset
- New method `as_calendar` on `Undate` class, to set calendar without doing any conversion
- Readme examples have been improved and extended
- New example notebook testing Hebrew, Islamic, and Seleucid date parsing and conversion with Princeton Geniza Project data
- bugfix: duration for uncertain years previously returned the duration from earliest to latest possible dates in range; now returns an `UnDelta` with the possible durations for the possible years in the given calendar

## 0.4

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

## 0.3.1

Update readthedocs config for current installation

## 0.3

- Updated to use numpy `datetime64` to support a greater range of years beyond the 4-digit years supported by python's builtin `datetime.date`
- Custom `Date` and `Timedelta` objects as shims to make numpy datetime64 and timedelta64 act more like python `datetime` objects
- Renamed formatters to converters for more flexibility / scope
- Support using different converters with new `format` and `parse` methods on `Undate`
- Improved EDTF support:
- Support 5+ digit years with leading Y (thanks to numpy.datetime64)
- Jupyter notebook demonstrating / validating EDTF support
- Full support for Level 0 Date and Time Interval (no Date and Time support)
- Level 1:
- Letter-prefixed calendar year
- Unspecified digit from the right
- Partial support for extended interval
- Level 2: unspecified digit anywhere in the date
- Improved readme with example usage and disclaimers about current functionality
- Improved documentation for adding new converters
- Improved documentation for branching guidelines in contributing
- Restructured sphinx documentation and added more code documentation
- Added a project logo
- Switch from black to ruff for pre-commit formatting

### numpy impact

Performance differences seem to be negligible, but it does increase payload size. The virtualenv for installing version 0.2 was 14MB; when installing the newer version with numpy, the virtualenv is 46MB (the numpy folder in site packages is 31MB on its own).

## 0.2

- Undate and UndateInterval now include an optional label for named dates or time periods
31 changes: 31 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# YAML 1.2
# Metadata for citation of this software according to the CFF format (https://citation-file-format.github.io/)
cff-version: 1.0.3
message: If you use this software, please cite it using these metadata.
title: undate python library
doi: 10.5281/zenodo.11068868
authors:
- given-names: Rebecca Sutton
family-names: Koeser
affiliation: Center for Digital Humanities, Princeton University
orcid: https://orcid.org/0000-0002-8762-8057
- given-names: Cole
family-names: Crawford
affiliation: Harvard University Arts and Humanities Research Computing
orcid: https://orcid.org/0000-0002-8347-0096
- given-names: Julia
family-names: Damerow
affiliation: Arizona State University
orcid: https://orcid.org/0000-0002-0874-0092
- given-names: Malte
family-names: Vogl
affiliation: Max-Planck-Institute of Geoanthropology
orcid: https://orcid.org/0000-0002-2683-6610
- given-names: Robert
family-names: Casties
affiliation: Max Planck Institute for the History of Science
orcid: https://orcid.org/0009-0008-9370-1303
version: '0.5'
date-released: 2025-06-25
repository-code: https://github.com/dh-tech/undate-python
license: Apache-2.0
Loading