undate

A Python library for working with fuzzy, partial, or otherwise uncertain dates

https://github.com/dh-tech/undate-python

Science Score: 77.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 3 DOI reference(s) in README
  • Academic publication links
    Links to: zenodo.org
  • Committers with academic emails
    4 of 8 committers (50.0%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (16.2%) to scientific vocabulary

Keywords

date digital-humanities python3 uncertainty

Keywords from Contributors

degoogle
Last synced: 4 months ago · JSON representation ·

Repository

A Python library for working with fuzzy, partial, or otherwise uncertain dates

Basic Info
Statistics
  • Stars: 16
  • Watchers: 4
  • Forks: 1
  • Open Issues: 18
  • Releases: 6
Topics
date digital-humanities python3 uncertainty
Created about 3 years ago · Last pushed 5 months ago
Metadata Files
Readme Changelog Contributing License Citation Authors

README.md

undate overview

undate

undate is a python library for working with uncertain or partially known dates.

[!WARNING] This is beta software and is not yet feature complete! Use with caution and give us feedback. Currently undate supports parsing and formatting dates in ISO8601, some portions of EDTF (Extended Date Time Format), and parsing and conversion for dates in Hebrew Anno Mundi and Islamic Hijri calendars.

Undate was initially created as part of a DH-Tech hackathon in November 2022.


DOI License Documentation Status unit tests codecov Ruff

All Contributors

Read Contributors for detailed contribution information.

Installation

Recommended: use pip to install the latest published version from PyPI:

console pip install undate

To install a development version or specific tag or branch, you can install from GitHub. Use the @name notation to specify the branch or tag; e.g., to install development version:

console pip install git+https://github.com/dh-tech/undate-python@develop#egg=undate

Example Usage

Often humanities and cultural data include imprecise or uncertain temporal information. We want to store that information but also work with it in a structured way, not just treat it as text for display. Different projects may need to work with or convert between different date formats or even different calendars.

An undate.Undate is analogous to python’s builtin datetime.date object, but with support for varying degrees of precision and unknown information. You can initialize an Undate with either strings or numbers for whichever parts of the date are known or partially known. An Undate can take an optional label.

```python from undate import Undate

november7 = Undate(2000, 11, 7) november = Undate(2000, 11) year2k = Undate(2000) november7someyear = Undate(month=11, day=7)

partiallyknownyear = Undate("19XX") partiallyknownmonth = Undate(2022, "1X")

easter1916 = Undate(1916, 4, 23, label="Easter 1916") ```

You can convert an Undate to string using a date formatter (current default is ISO8601):

```python

[str(d) for d in [november7, november, year2k, november7someyear]] ['2000-11-07', '2000-11', '2000', '--11-07'] ```

If enough information is known, an Undate object can report on its duration:

```python

december = Undate(2000, 12) febleapyear = Undate(2024, 2) febregularyear = Undate(2023, 2) for d in [november7, november, december, year2k, november7someyear, febregularyear, febleapyear]: ... print(f"{d} - duration in days: {d.duration().days}") ... 2000-11-07 - duration in days: 1 2000-11 - duration in days: 30 2000-12 - duration in days: 31 2000 - duration in days: 366 --11-07 - duration in days: 1 2023-02 - duration in days: 28 2024-02 - duration in days: 29 ```

If enough of the date is known and the precision supports it, you can check if one date falls within another date:

```python

november7 = Undate(2000, 11, 7) november2000 = Undate(2000, 11) year2k = Undate(2000) ad100 = Undate(100) november7 in november True november2000 in year2k True november7 in year2k True november2000 in ad100 False november7 in ad100 False ```

For dates that are imprecise or partially known, undate calculates earliest and latest possible dates for comparison purposes so you can sort dates and compare with equals, greater than, and less than. You can also compare with python datetime.date objects.

```python

november72020 = Undate(2020, 11, 7) november2001 = Undate(2001, 11) year2k = Undate(2000) ad100 = Undate(100) sorted([november72020, november2001, year2k, ad100]) [, , , ] november72020 > november2001 True year2k < ad100 False from datetime import date year2k > date(2001, 1, 1) False ```

When dates cannot be compared due to ambiguity or precision, comparison methods raise a NotImplementedError.

```python

november2020 = Undate(2020, 11) november72020 > november2020 Traceback (most recent call last): File "", line 1, in File "/Users/rkoeser/workarea/github/undate-python/src/undate/undate.py", line 262, in _gt__ return not (self < other or self == other) File "/Users/rkoeser/workarea/github/undate-python/src/undate/undate.py", line 245, in lt raise NotImplementedError( NotImplementedError: Can't compare when one date falls within the other ```

An UndateInterval is a date range between two Undate objects. Intervals can be open-ended, allow for optional labels, and can calculate duration if enough information is known. UndateIntervals are inclusive (i.e., a closed interval), and include both the earliest and latest date as part of the range.

```python

from undate import UndateInterval UndateInterval(Undate(1900), Undate(2000)) UndateInterval(Undate(1801), Undate(1900), label="19th century") UndateInterval(Undate(1801), Undate(1900), label="19th century").duration().days 36524 UndateInterval(Undate(1901), Undate(2000), label="20th century") UndateInterval(latest=Undate(2000)) # before 2000 UndateInterval(Undate(1900)) # after 1900 UndateInterval(Undate(1900), Undate(2000), label="19th century").duration().days 36890 UndateInterval(Undate(2000, 1, 1), Undate(2000, 1,31)).duration().days 31 ```

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. Currently available converters are "ISO8601" and "EDTF" and supported calendars.

```python

from undate import Undate Undate.parse("2002", "ISO8601") Undate.parse("2002-05", "EDTF") Undate.parse("--05-03", "ISO8601") Undate.parse("--05-03", "ISO8601").format("EDTF") 'XXXX-05-03' Undate.parse("1800/1900") ```

Calendars

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 package.

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.

```python

from undate import Undate tammuz4816 = Undate.parse("26 Tammuz 4816", "Hebrew") tammuz4816 rajab495 = Undate.parse("Rajab 495", "Islamic") rajab495 y2k = Undate.parse("2001", "EDTF") y2k [str(d.earliest) for d in [rajab495, tammuz4816, y2k]] ['1102-04-28', '1056-07-17', '2001-01-01'] [str(d.precision) for d in [rajab495, tammuz4816, y2k]] ['MONTH', 'DAY', 'YEAR'] sorted([rajab495, tammuz4816, y2k]) [, , ] ```


For more examples, refer to the code notebooks included in theexamples in this repository.

Documentation

Project documentation is available on ReadTheDocs.

For instructions on setting up for local development, see Developer Notes.

License

This software is licensed under the Apache 2.0 License.

Owner

  • Name: DHtech
  • Login: dh-tech
  • Kind: organization

A group of Digital Humanities Developers

Citation (CITATION.cff)

# 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

GitHub Events

Total
  • Create event: 39
  • Release event: 4
  • Issues event: 19
  • Watch event: 8
  • Delete event: 28
  • Member event: 1
  • Issue comment event: 103
  • Push event: 138
  • Pull request review event: 113
  • Pull request review comment event: 134
  • Pull request event: 56
Last Year
  • Create event: 39
  • Release event: 4
  • Issues event: 19
  • Watch event: 8
  • Delete event: 28
  • Member event: 1
  • Issue comment event: 103
  • Push event: 138
  • Pull request review event: 113
  • Pull request review comment event: 134
  • Pull request event: 56

Committers

Last synced: almost 2 years ago

All Time
  • Total Commits: 51
  • Total Committers: 8
  • Avg Commits per committer: 6.375
  • Development Distribution Score (DDS): 0.745
Past Year
  • Commits: 51
  • Committers: 8
  • Avg Commits per committer: 6.375
  • Development Distribution Score (DDS): 0.745
Top Committers
Name Email Commits
rlskoeser r****r@p****u 13
allcontributors[bot] 4****] 13
Rebecca Sutton Koeser r****r 9
Cole Crawford c****d@f****u 6
Julia Damerow j****w 5
Cole Crawford 1****d 2
Malte Vogl m****l@m****e 2
Robert Casties c****s@m****e 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 4 months ago

All Time
  • Total issues: 51
  • Total pull requests: 99
  • Average time to close issues: 6 months
  • Average time to close pull requests: 22 days
  • Total issue authors: 5
  • Total pull request authors: 6
  • Average comments per issue: 1.51
  • Average comments per pull request: 1.8
  • Merged pull requests: 76
  • Bot issues: 0
  • Bot pull requests: 16
Past Year
  • Issues: 13
  • Pull requests: 54
  • Average time to close issues: 4 days
  • Average time to close pull requests: 16 days
  • Issue authors: 3
  • Pull request authors: 3
  • Average comments per issue: 0.31
  • Average comments per pull request: 2.17
  • Merged pull requests: 32
  • Bot issues: 0
  • Bot pull requests: 2
Top Authors
Issue Authors
  • rlskoeser (39)
  • jdamerow (7)
  • ColeDCrawford (4)
  • robcast (2)
  • corneliusroemer (1)
Pull Request Authors
  • rlskoeser (95)
  • allcontributors[bot] (16)
  • jdamerow (4)
  • robcast (3)
  • maltevogl (2)
  • ColeDCrawford (1)
Top Labels
Issue Labels
resolved (3) bug (3)
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 67 last-month
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 7
  • Total maintainers: 3
pypi.org: undate

library for working with uncertain, fuzzy, or partially unknown dates and date intervals

  • Versions: 7
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 67 Last month
Rankings
Dependent packages count: 6.6%
Downloads: 13.7%
Average: 19.2%
Stargazers count: 21.8%
Forks count: 23.2%
Dependent repos count: 30.6%
Maintainers (3)
Last synced: 4 months ago

Dependencies

requirements-dev.txt pypi
  • black ==22.10.0 development
  • pre-commit ==2.20.0 development
  • pytest ==7.2.0 development