diff options
author | CoprDistGit <infra@openeuler.org> | 2023-05-05 13:09:42 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-05-05 13:09:42 +0000 |
commit | aaf413e33d64ddebe345420217360b54e00780ab (patch) | |
tree | 7c73f65bbff3eb3570a058b55c5b3c743db86833 | |
parent | 33a875eddce88ac74c88a60654735cc0a53c72f0 (diff) |
automatic import of python-edtfopeneuler20.03
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-edtf.spec | 678 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 680 insertions, 0 deletions
@@ -0,0 +1 @@ +/edtf-4.0.1.tar.gz diff --git a/python-edtf.spec b/python-edtf.spec new file mode 100644 index 0000000..6c4addb --- /dev/null +++ b/python-edtf.spec @@ -0,0 +1,678 @@ +%global _empty_manifest_terminate_build 0 +Name: python-edtf +Version: 4.0.1 +Release: 1 +Summary: Python implementation of Library of Congress EDTF (Extended Date Time Format) specification +License: MIT +URL: https://github.com/ixc/python-edtf +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/a9/5f/1e2e40520f60ac4d0faed04aa2f4fd1fbf82fbb779a1a26188668c611762/edtf-4.0.1.tar.gz +BuildArch: noarch + +Requires: python3-dateutil +Requires: python3-pyparsing +Requires: python3-six +Requires: python3-django +Requires: python3-nose +Requires: python3-tox + +%description +An implementation of EDTF format in Python, together with utility functions for parsing natural language date texts, and converting EDTF dates to related Python `date` objects. +See http://www.loc.gov/standards/datetime/ for the current draft specification. +## To install + pip install edtf +## To use + >>> from edtf import parse_edtf + # Parse an EDTF string to an EDTFObject + >>> e = parse_edtf("1979-08~") # approx August 1979 + >>> e + UncertainOrApproximate: '1979-08~' + # normalised string representation (some different EDTF strings have identical meanings) + >>> unicode(e) + u'1979-08~' + # Derive Python date objects + # lower and upper bounds that strictly adhere to the given range + >>> e.lower_strict()[:3], e.upper_strict()[:3] + ((1979, 8, 1), (1979, 8, 31)) + # lower and upper bounds that are padded if there's indicated uncertainty + >>> e.lower_fuzzy()[:3], e.upper_fuzzy()[:3] + ((1979, 7, 1), (1979, 9, 30)) + # Date intervals + >>> interval = parse_edtf("1979-08~/open") + >>> interval + Level1Interval: '1979-08~/open' + # Intervals have lower and upper EDTF objects. + >>> interval.lower, interval.upper + (UncertainOrApproximate: '1979-08~', UncertainOrApproximate: 'open') + >>> interval.lower.upper_strict()[:3] + (1979, 8, 31) + >>> interval.upper.lower_strict() # 'open' is interpreted to mean 'still happening'. + [Today's date] + # Date collections + >>> coll = parse_edtf('{1667,1668, 1670..1672}') + >>> coll + MultipleDates: '{1667, 1668, 1670..1672}' + >>> coll.objects + (Date: '1667', Date: '1668', Consecutives: '1670..1672') +The object returned by `parse_edtf()` is an instance of an `edtf.parser.parser_classes.EDTFObject` subclass, depending on the type of date that was parsed. These classes are: + # Level 0 + Date + DateAndTime + Interval + # Level 1 + UncertainOrApproximate + Unspecified + Level1Interval + LongYear + Season + # Level 2 + PartialUncertainOrApproximate + PartialUnspecified + OneOfASet + MultipleDates + MaskedPrecision + Level2Interval + ExponentialYear +All of these implement `upper/lower_strict/fuzzy()` methods to derive Python `date` objects. +The `*Interval` instances have `upper` and `lower` properties that are themselves `EDTFObject` instances. +`OneOfASet` and `MultipleDates` instances have an `objects` property that is a list of all of the EDTF dates parsed in the set or list. +## EDTF Specification Inclusions +The library includes implementation of levels 0, 1 and 2 of the EDTF spec. +Test coverage includes every example given in the spec table of features. +### Level 0 ISO 8601 Features +* Date: + >>> parse_edtf('1979-08') # August 1979 + Date: '1979-08' +* Date and Time: + >>> parse_edtf('2004-01-01T10:10:10+05:00') + DateAndTime: '2004-01-01T10:10:10+05:00' +* Interval (start/end): + >>> parse_edtf('1979-08-28/1979-09-25') # From August 28 to September 25 1979 + Interval: '1979-08-28/1979-09-25' +### Level 1 Extensions +* Uncertain/Approximate dates: + >>> parse_edtf('1979-08-28~') # Approximately August 28th 1979 + UncertainOrApproximate: '1979-08-28~' +* Unspecified dates: + >>> parse_edtf('1979-08-uu') # An unknown day in August 1979 + Unspecified: '1979-08-uu' + >>> parse_edtf('1979-uu') # Some month in 1979 + Unspecified: '1979-uu' +* Extended intervals: + >>> parse_edtf('1984-06-02?/2004-08-08~') + Level1Interval: '1984-06-02?/2004-08-08~' +* Years exceeding four digits: + >>> parse_edtf('y-12000') # 12000 years BCE + LongYear: 'y-12000' +* Season: + >>> parse_edtf('1979-22') # Summer 1979 + Season: '1979-22' +### Level 2 Extensions +* Partial uncertain/approximate: + >>> parse_edtf('(2011)-06-04~') # year certain, month/day approximate. + # Note that the result text is normalized + PartialUncertainOrApproximate: '2011-(06-04)~' +* Partial unspecified: + >>> parse_edtf('1979-uu-28') # The 28th day of an uncertain month in 1979 + PartialUnspecified: '1979-uu-28' +* One of a set: + >>> parse_edtf("[..1760-12-03,1762]") + OneOfASet: '[..1760-12-03, 1762]' +* Multiple dates: + >>> parse_edtf('{1667,1668, 1670..1672}') + MultipleDates: '{1667, 1668, 1670..1672}' +* Masked precision: + >>> parse_edtf('197x') # A date in the 1970s. + MaskedPrecision: '197x' +* Level 2 Extended intervals: + >>> parse_edtf('2004-06-(01)~/2004-06-(20)~') + Level2Interval: '2004-06-(01)~/2004-06-(20)~' +* Year requiring more than 4 digits - exponential form: + >>> parse_edtf('y-17e7') + ExponentialYear: 'y-17e7' +### Natural language representation +The library includes a basic English natural language parser (it's not yet smart enough to work with occasions such as 'Easter', or in other languages): + >>> from edtf import text_to_edtf + >>> text_to_edtf("circa August 1979") + '1979-08~' +Note that the result is a string, not an `ETDFObject`. +The parser can parse strings such as: + 'January 12, 1940' => '1940-01-12' + '90' => '1990' #implied century + 'January 2008' => '2008-01' + 'the year 1800' => '1800' + '10/7/2008' => '2008-10-07' # in a full-specced date, assume US ordering + # uncertain/approximate + '1860?' => '1860?' + '1862 (uncertain)' => '1862?' + 'circa Feb 1812' => '1812-02~' + 'c.1860' => '1860~' #with or without . + 'ca1860' => '1860~' + 'approx 1860' => '1860~' + # masked precision + '1860s' => '186x' #186x has decade precision, 186u has year precision. + '1800s' => '18xx' # without uncertainty indicators, assume century + # masked precision + uncertainty + 'ca. 1860s' => '186x~' + 'circa 1840s' => '184x~' + 'ca. 1860s?' => '186x?~' + 'c1800s?' => '180x?~' # with uncertainty indicators, use the decade + # unspecified parts + 'January 12' => 'uuuu-01-12' + 'January' => 'uuuu-01' + '7/2008' => '2008-07' + #seasons + 'Autumn 1872' => '1872-23' + 'Fall 1872' => '1872-23' + # before/after + 'earlier than 1928' => 'unknown/1928' + 'later than 1928' => '1928/unknown' + 'before January 1928' => 'unknown/1928-01' + 'after about the 1920s' => '192x~/unknown' + # unspecified + 'year in the 1860s' => '186u' #186x has decade precision, 186u has year precision. + ('year in the 1800s', '18xu') + 'month in 1872' => '1872-uu' + 'day in January 1872' => '1872-01-uu' + 'day in 1872' => '1872-uu-uu' + #centuries + '1st century' => '00xx' + '10c' => '09xx' + '19th century?' => '18xx?' + # just showing off now... + 'a day in about Spring 1849?' => '1849-21-uu?~' + # simple ranges, which aren't as accurate as they could be. The parser is + limited to only picking the first year range it finds. + '1851-1852' => '1851/1852' + '1851-1852; printed 1853-1854' => '1851/1852' + '1851-52' => '1851/1852' + '1856-ca. 1865' => '1856/1865~' + '1860s-1870s' => '186x/187x' + '1920s -early 1930s' => '192x/193x' + '1938, printed 1940s-1950s' => '1938' +Generating natural text from an EDTF representation is a future goal. +### What assumptions does the natural text parser make when interpreting an ambiguous date? +* "1800s" is ambiguously a century or decade. If the given date is either uncertain or approximate, the decade interpretation is used. If the date is certain and precise, the century interpretation is used. +* If the century isn't specified (`EDTF(natural_text="the '70s")`), we imply the century to be "19" if the year is greater than the current year, otherwise we imply the century to be the current century. +* US-ordered dates (mm/dd/yyyy) are assumed by default in natural language. To change this, set `DAY_FIRST` to True in settings. +* If a natural language groups dates with a '/', it's interpreted as "or" rather than "and". The resulting EDTF text is a list bracketed by `[]` ("one of these dates") rather than `{}` (all of these dates). +## Converting to and from Python dates +Since EDTF dates are often regions, and often imprecise, we need to use a few different Python dates, depending on the circumstance. Generally, Python dates are used for sorting and filtering, and are not displayed directly to users. +### `struct_time` date representation +Because Python's `datetime` module does not support dates out side the range 1 AD to 9999 AD we return dates as `time.struct_time` objects by default instead of the `datetime.date` or `datetime.datetime` objects you might expect. +The `struct_time` representation is more difficult to work with, but can be sorted as-is which is the primary use-case, and can be converted relatively easily to `date` or `datetime` objects (provided the year is within 1 to 9999 AD) or to date objects in more flexible libraries like [astropy.time](http://docs.astropy.org/en/stable/time/index.html) for years outside these bounds. +If you are sure you are working with dates within the range supported by Python's `datetime` module, you can get these more convenient objects using the `edtf.struct_time_to_date` and `edtf.struct_time_to_datetime` functions. +NOTE: This library previously did return `date` and `datetime` objects from methods by default before we switched to `struct_time`. See ticket https://github.com/ixc/python-edtf/issues/26. +### `lower_strict` and `upper_strict` +These dates indicate the earliest and latest dates that are __strictly__ in the date range, ignoring uncertainty or approximation. One way to think about this is 'if you had to pick a single date to sort by, what would it be?'. +In an ascending sort (most recent last), sort by `lower_strict` to get a natural sort order. In a descending sort (most recent first), sort by `upper_strict`: + >>> e = parse_edtf('1912-04~') + >>> e.lower_strict() # Returns struct_time + >>> time.struct_time(tm_year=1912, tm_mon=4, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=0, tm_isdst=-1) + >>> e.lower_strict()[:3] # Show only interesting parts of struct_time + (1912, 4, 01) + >>> from edtf import struct_time_to_date + >>> struct_time_to_date(e.lower_strict()) # Convert to date + datetime.date(1912, 4, 01) + >>> e.upper_strict()[:3] + (1912, 4, 30) + >>> struct_time_to_date(e.upper_strict()) + datetime.date(1912, 4, 30) + +%package -n python3-edtf +Summary: Python implementation of Library of Congress EDTF (Extended Date Time Format) specification +Provides: python-edtf +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-edtf +An implementation of EDTF format in Python, together with utility functions for parsing natural language date texts, and converting EDTF dates to related Python `date` objects. +See http://www.loc.gov/standards/datetime/ for the current draft specification. +## To install + pip install edtf +## To use + >>> from edtf import parse_edtf + # Parse an EDTF string to an EDTFObject + >>> e = parse_edtf("1979-08~") # approx August 1979 + >>> e + UncertainOrApproximate: '1979-08~' + # normalised string representation (some different EDTF strings have identical meanings) + >>> unicode(e) + u'1979-08~' + # Derive Python date objects + # lower and upper bounds that strictly adhere to the given range + >>> e.lower_strict()[:3], e.upper_strict()[:3] + ((1979, 8, 1), (1979, 8, 31)) + # lower and upper bounds that are padded if there's indicated uncertainty + >>> e.lower_fuzzy()[:3], e.upper_fuzzy()[:3] + ((1979, 7, 1), (1979, 9, 30)) + # Date intervals + >>> interval = parse_edtf("1979-08~/open") + >>> interval + Level1Interval: '1979-08~/open' + # Intervals have lower and upper EDTF objects. + >>> interval.lower, interval.upper + (UncertainOrApproximate: '1979-08~', UncertainOrApproximate: 'open') + >>> interval.lower.upper_strict()[:3] + (1979, 8, 31) + >>> interval.upper.lower_strict() # 'open' is interpreted to mean 'still happening'. + [Today's date] + # Date collections + >>> coll = parse_edtf('{1667,1668, 1670..1672}') + >>> coll + MultipleDates: '{1667, 1668, 1670..1672}' + >>> coll.objects + (Date: '1667', Date: '1668', Consecutives: '1670..1672') +The object returned by `parse_edtf()` is an instance of an `edtf.parser.parser_classes.EDTFObject` subclass, depending on the type of date that was parsed. These classes are: + # Level 0 + Date + DateAndTime + Interval + # Level 1 + UncertainOrApproximate + Unspecified + Level1Interval + LongYear + Season + # Level 2 + PartialUncertainOrApproximate + PartialUnspecified + OneOfASet + MultipleDates + MaskedPrecision + Level2Interval + ExponentialYear +All of these implement `upper/lower_strict/fuzzy()` methods to derive Python `date` objects. +The `*Interval` instances have `upper` and `lower` properties that are themselves `EDTFObject` instances. +`OneOfASet` and `MultipleDates` instances have an `objects` property that is a list of all of the EDTF dates parsed in the set or list. +## EDTF Specification Inclusions +The library includes implementation of levels 0, 1 and 2 of the EDTF spec. +Test coverage includes every example given in the spec table of features. +### Level 0 ISO 8601 Features +* Date: + >>> parse_edtf('1979-08') # August 1979 + Date: '1979-08' +* Date and Time: + >>> parse_edtf('2004-01-01T10:10:10+05:00') + DateAndTime: '2004-01-01T10:10:10+05:00' +* Interval (start/end): + >>> parse_edtf('1979-08-28/1979-09-25') # From August 28 to September 25 1979 + Interval: '1979-08-28/1979-09-25' +### Level 1 Extensions +* Uncertain/Approximate dates: + >>> parse_edtf('1979-08-28~') # Approximately August 28th 1979 + UncertainOrApproximate: '1979-08-28~' +* Unspecified dates: + >>> parse_edtf('1979-08-uu') # An unknown day in August 1979 + Unspecified: '1979-08-uu' + >>> parse_edtf('1979-uu') # Some month in 1979 + Unspecified: '1979-uu' +* Extended intervals: + >>> parse_edtf('1984-06-02?/2004-08-08~') + Level1Interval: '1984-06-02?/2004-08-08~' +* Years exceeding four digits: + >>> parse_edtf('y-12000') # 12000 years BCE + LongYear: 'y-12000' +* Season: + >>> parse_edtf('1979-22') # Summer 1979 + Season: '1979-22' +### Level 2 Extensions +* Partial uncertain/approximate: + >>> parse_edtf('(2011)-06-04~') # year certain, month/day approximate. + # Note that the result text is normalized + PartialUncertainOrApproximate: '2011-(06-04)~' +* Partial unspecified: + >>> parse_edtf('1979-uu-28') # The 28th day of an uncertain month in 1979 + PartialUnspecified: '1979-uu-28' +* One of a set: + >>> parse_edtf("[..1760-12-03,1762]") + OneOfASet: '[..1760-12-03, 1762]' +* Multiple dates: + >>> parse_edtf('{1667,1668, 1670..1672}') + MultipleDates: '{1667, 1668, 1670..1672}' +* Masked precision: + >>> parse_edtf('197x') # A date in the 1970s. + MaskedPrecision: '197x' +* Level 2 Extended intervals: + >>> parse_edtf('2004-06-(01)~/2004-06-(20)~') + Level2Interval: '2004-06-(01)~/2004-06-(20)~' +* Year requiring more than 4 digits - exponential form: + >>> parse_edtf('y-17e7') + ExponentialYear: 'y-17e7' +### Natural language representation +The library includes a basic English natural language parser (it's not yet smart enough to work with occasions such as 'Easter', or in other languages): + >>> from edtf import text_to_edtf + >>> text_to_edtf("circa August 1979") + '1979-08~' +Note that the result is a string, not an `ETDFObject`. +The parser can parse strings such as: + 'January 12, 1940' => '1940-01-12' + '90' => '1990' #implied century + 'January 2008' => '2008-01' + 'the year 1800' => '1800' + '10/7/2008' => '2008-10-07' # in a full-specced date, assume US ordering + # uncertain/approximate + '1860?' => '1860?' + '1862 (uncertain)' => '1862?' + 'circa Feb 1812' => '1812-02~' + 'c.1860' => '1860~' #with or without . + 'ca1860' => '1860~' + 'approx 1860' => '1860~' + # masked precision + '1860s' => '186x' #186x has decade precision, 186u has year precision. + '1800s' => '18xx' # without uncertainty indicators, assume century + # masked precision + uncertainty + 'ca. 1860s' => '186x~' + 'circa 1840s' => '184x~' + 'ca. 1860s?' => '186x?~' + 'c1800s?' => '180x?~' # with uncertainty indicators, use the decade + # unspecified parts + 'January 12' => 'uuuu-01-12' + 'January' => 'uuuu-01' + '7/2008' => '2008-07' + #seasons + 'Autumn 1872' => '1872-23' + 'Fall 1872' => '1872-23' + # before/after + 'earlier than 1928' => 'unknown/1928' + 'later than 1928' => '1928/unknown' + 'before January 1928' => 'unknown/1928-01' + 'after about the 1920s' => '192x~/unknown' + # unspecified + 'year in the 1860s' => '186u' #186x has decade precision, 186u has year precision. + ('year in the 1800s', '18xu') + 'month in 1872' => '1872-uu' + 'day in January 1872' => '1872-01-uu' + 'day in 1872' => '1872-uu-uu' + #centuries + '1st century' => '00xx' + '10c' => '09xx' + '19th century?' => '18xx?' + # just showing off now... + 'a day in about Spring 1849?' => '1849-21-uu?~' + # simple ranges, which aren't as accurate as they could be. The parser is + limited to only picking the first year range it finds. + '1851-1852' => '1851/1852' + '1851-1852; printed 1853-1854' => '1851/1852' + '1851-52' => '1851/1852' + '1856-ca. 1865' => '1856/1865~' + '1860s-1870s' => '186x/187x' + '1920s -early 1930s' => '192x/193x' + '1938, printed 1940s-1950s' => '1938' +Generating natural text from an EDTF representation is a future goal. +### What assumptions does the natural text parser make when interpreting an ambiguous date? +* "1800s" is ambiguously a century or decade. If the given date is either uncertain or approximate, the decade interpretation is used. If the date is certain and precise, the century interpretation is used. +* If the century isn't specified (`EDTF(natural_text="the '70s")`), we imply the century to be "19" if the year is greater than the current year, otherwise we imply the century to be the current century. +* US-ordered dates (mm/dd/yyyy) are assumed by default in natural language. To change this, set `DAY_FIRST` to True in settings. +* If a natural language groups dates with a '/', it's interpreted as "or" rather than "and". The resulting EDTF text is a list bracketed by `[]` ("one of these dates") rather than `{}` (all of these dates). +## Converting to and from Python dates +Since EDTF dates are often regions, and often imprecise, we need to use a few different Python dates, depending on the circumstance. Generally, Python dates are used for sorting and filtering, and are not displayed directly to users. +### `struct_time` date representation +Because Python's `datetime` module does not support dates out side the range 1 AD to 9999 AD we return dates as `time.struct_time` objects by default instead of the `datetime.date` or `datetime.datetime` objects you might expect. +The `struct_time` representation is more difficult to work with, but can be sorted as-is which is the primary use-case, and can be converted relatively easily to `date` or `datetime` objects (provided the year is within 1 to 9999 AD) or to date objects in more flexible libraries like [astropy.time](http://docs.astropy.org/en/stable/time/index.html) for years outside these bounds. +If you are sure you are working with dates within the range supported by Python's `datetime` module, you can get these more convenient objects using the `edtf.struct_time_to_date` and `edtf.struct_time_to_datetime` functions. +NOTE: This library previously did return `date` and `datetime` objects from methods by default before we switched to `struct_time`. See ticket https://github.com/ixc/python-edtf/issues/26. +### `lower_strict` and `upper_strict` +These dates indicate the earliest and latest dates that are __strictly__ in the date range, ignoring uncertainty or approximation. One way to think about this is 'if you had to pick a single date to sort by, what would it be?'. +In an ascending sort (most recent last), sort by `lower_strict` to get a natural sort order. In a descending sort (most recent first), sort by `upper_strict`: + >>> e = parse_edtf('1912-04~') + >>> e.lower_strict() # Returns struct_time + >>> time.struct_time(tm_year=1912, tm_mon=4, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=0, tm_isdst=-1) + >>> e.lower_strict()[:3] # Show only interesting parts of struct_time + (1912, 4, 01) + >>> from edtf import struct_time_to_date + >>> struct_time_to_date(e.lower_strict()) # Convert to date + datetime.date(1912, 4, 01) + >>> e.upper_strict()[:3] + (1912, 4, 30) + >>> struct_time_to_date(e.upper_strict()) + datetime.date(1912, 4, 30) + +%package help +Summary: Development documents and examples for edtf +Provides: python3-edtf-doc +%description help +An implementation of EDTF format in Python, together with utility functions for parsing natural language date texts, and converting EDTF dates to related Python `date` objects. +See http://www.loc.gov/standards/datetime/ for the current draft specification. +## To install + pip install edtf +## To use + >>> from edtf import parse_edtf + # Parse an EDTF string to an EDTFObject + >>> e = parse_edtf("1979-08~") # approx August 1979 + >>> e + UncertainOrApproximate: '1979-08~' + # normalised string representation (some different EDTF strings have identical meanings) + >>> unicode(e) + u'1979-08~' + # Derive Python date objects + # lower and upper bounds that strictly adhere to the given range + >>> e.lower_strict()[:3], e.upper_strict()[:3] + ((1979, 8, 1), (1979, 8, 31)) + # lower and upper bounds that are padded if there's indicated uncertainty + >>> e.lower_fuzzy()[:3], e.upper_fuzzy()[:3] + ((1979, 7, 1), (1979, 9, 30)) + # Date intervals + >>> interval = parse_edtf("1979-08~/open") + >>> interval + Level1Interval: '1979-08~/open' + # Intervals have lower and upper EDTF objects. + >>> interval.lower, interval.upper + (UncertainOrApproximate: '1979-08~', UncertainOrApproximate: 'open') + >>> interval.lower.upper_strict()[:3] + (1979, 8, 31) + >>> interval.upper.lower_strict() # 'open' is interpreted to mean 'still happening'. + [Today's date] + # Date collections + >>> coll = parse_edtf('{1667,1668, 1670..1672}') + >>> coll + MultipleDates: '{1667, 1668, 1670..1672}' + >>> coll.objects + (Date: '1667', Date: '1668', Consecutives: '1670..1672') +The object returned by `parse_edtf()` is an instance of an `edtf.parser.parser_classes.EDTFObject` subclass, depending on the type of date that was parsed. These classes are: + # Level 0 + Date + DateAndTime + Interval + # Level 1 + UncertainOrApproximate + Unspecified + Level1Interval + LongYear + Season + # Level 2 + PartialUncertainOrApproximate + PartialUnspecified + OneOfASet + MultipleDates + MaskedPrecision + Level2Interval + ExponentialYear +All of these implement `upper/lower_strict/fuzzy()` methods to derive Python `date` objects. +The `*Interval` instances have `upper` and `lower` properties that are themselves `EDTFObject` instances. +`OneOfASet` and `MultipleDates` instances have an `objects` property that is a list of all of the EDTF dates parsed in the set or list. +## EDTF Specification Inclusions +The library includes implementation of levels 0, 1 and 2 of the EDTF spec. +Test coverage includes every example given in the spec table of features. +### Level 0 ISO 8601 Features +* Date: + >>> parse_edtf('1979-08') # August 1979 + Date: '1979-08' +* Date and Time: + >>> parse_edtf('2004-01-01T10:10:10+05:00') + DateAndTime: '2004-01-01T10:10:10+05:00' +* Interval (start/end): + >>> parse_edtf('1979-08-28/1979-09-25') # From August 28 to September 25 1979 + Interval: '1979-08-28/1979-09-25' +### Level 1 Extensions +* Uncertain/Approximate dates: + >>> parse_edtf('1979-08-28~') # Approximately August 28th 1979 + UncertainOrApproximate: '1979-08-28~' +* Unspecified dates: + >>> parse_edtf('1979-08-uu') # An unknown day in August 1979 + Unspecified: '1979-08-uu' + >>> parse_edtf('1979-uu') # Some month in 1979 + Unspecified: '1979-uu' +* Extended intervals: + >>> parse_edtf('1984-06-02?/2004-08-08~') + Level1Interval: '1984-06-02?/2004-08-08~' +* Years exceeding four digits: + >>> parse_edtf('y-12000') # 12000 years BCE + LongYear: 'y-12000' +* Season: + >>> parse_edtf('1979-22') # Summer 1979 + Season: '1979-22' +### Level 2 Extensions +* Partial uncertain/approximate: + >>> parse_edtf('(2011)-06-04~') # year certain, month/day approximate. + # Note that the result text is normalized + PartialUncertainOrApproximate: '2011-(06-04)~' +* Partial unspecified: + >>> parse_edtf('1979-uu-28') # The 28th day of an uncertain month in 1979 + PartialUnspecified: '1979-uu-28' +* One of a set: + >>> parse_edtf("[..1760-12-03,1762]") + OneOfASet: '[..1760-12-03, 1762]' +* Multiple dates: + >>> parse_edtf('{1667,1668, 1670..1672}') + MultipleDates: '{1667, 1668, 1670..1672}' +* Masked precision: + >>> parse_edtf('197x') # A date in the 1970s. + MaskedPrecision: '197x' +* Level 2 Extended intervals: + >>> parse_edtf('2004-06-(01)~/2004-06-(20)~') + Level2Interval: '2004-06-(01)~/2004-06-(20)~' +* Year requiring more than 4 digits - exponential form: + >>> parse_edtf('y-17e7') + ExponentialYear: 'y-17e7' +### Natural language representation +The library includes a basic English natural language parser (it's not yet smart enough to work with occasions such as 'Easter', or in other languages): + >>> from edtf import text_to_edtf + >>> text_to_edtf("circa August 1979") + '1979-08~' +Note that the result is a string, not an `ETDFObject`. +The parser can parse strings such as: + 'January 12, 1940' => '1940-01-12' + '90' => '1990' #implied century + 'January 2008' => '2008-01' + 'the year 1800' => '1800' + '10/7/2008' => '2008-10-07' # in a full-specced date, assume US ordering + # uncertain/approximate + '1860?' => '1860?' + '1862 (uncertain)' => '1862?' + 'circa Feb 1812' => '1812-02~' + 'c.1860' => '1860~' #with or without . + 'ca1860' => '1860~' + 'approx 1860' => '1860~' + # masked precision + '1860s' => '186x' #186x has decade precision, 186u has year precision. + '1800s' => '18xx' # without uncertainty indicators, assume century + # masked precision + uncertainty + 'ca. 1860s' => '186x~' + 'circa 1840s' => '184x~' + 'ca. 1860s?' => '186x?~' + 'c1800s?' => '180x?~' # with uncertainty indicators, use the decade + # unspecified parts + 'January 12' => 'uuuu-01-12' + 'January' => 'uuuu-01' + '7/2008' => '2008-07' + #seasons + 'Autumn 1872' => '1872-23' + 'Fall 1872' => '1872-23' + # before/after + 'earlier than 1928' => 'unknown/1928' + 'later than 1928' => '1928/unknown' + 'before January 1928' => 'unknown/1928-01' + 'after about the 1920s' => '192x~/unknown' + # unspecified + 'year in the 1860s' => '186u' #186x has decade precision, 186u has year precision. + ('year in the 1800s', '18xu') + 'month in 1872' => '1872-uu' + 'day in January 1872' => '1872-01-uu' + 'day in 1872' => '1872-uu-uu' + #centuries + '1st century' => '00xx' + '10c' => '09xx' + '19th century?' => '18xx?' + # just showing off now... + 'a day in about Spring 1849?' => '1849-21-uu?~' + # simple ranges, which aren't as accurate as they could be. The parser is + limited to only picking the first year range it finds. + '1851-1852' => '1851/1852' + '1851-1852; printed 1853-1854' => '1851/1852' + '1851-52' => '1851/1852' + '1856-ca. 1865' => '1856/1865~' + '1860s-1870s' => '186x/187x' + '1920s -early 1930s' => '192x/193x' + '1938, printed 1940s-1950s' => '1938' +Generating natural text from an EDTF representation is a future goal. +### What assumptions does the natural text parser make when interpreting an ambiguous date? +* "1800s" is ambiguously a century or decade. If the given date is either uncertain or approximate, the decade interpretation is used. If the date is certain and precise, the century interpretation is used. +* If the century isn't specified (`EDTF(natural_text="the '70s")`), we imply the century to be "19" if the year is greater than the current year, otherwise we imply the century to be the current century. +* US-ordered dates (mm/dd/yyyy) are assumed by default in natural language. To change this, set `DAY_FIRST` to True in settings. +* If a natural language groups dates with a '/', it's interpreted as "or" rather than "and". The resulting EDTF text is a list bracketed by `[]` ("one of these dates") rather than `{}` (all of these dates). +## Converting to and from Python dates +Since EDTF dates are often regions, and often imprecise, we need to use a few different Python dates, depending on the circumstance. Generally, Python dates are used for sorting and filtering, and are not displayed directly to users. +### `struct_time` date representation +Because Python's `datetime` module does not support dates out side the range 1 AD to 9999 AD we return dates as `time.struct_time` objects by default instead of the `datetime.date` or `datetime.datetime` objects you might expect. +The `struct_time` representation is more difficult to work with, but can be sorted as-is which is the primary use-case, and can be converted relatively easily to `date` or `datetime` objects (provided the year is within 1 to 9999 AD) or to date objects in more flexible libraries like [astropy.time](http://docs.astropy.org/en/stable/time/index.html) for years outside these bounds. +If you are sure you are working with dates within the range supported by Python's `datetime` module, you can get these more convenient objects using the `edtf.struct_time_to_date` and `edtf.struct_time_to_datetime` functions. +NOTE: This library previously did return `date` and `datetime` objects from methods by default before we switched to `struct_time`. See ticket https://github.com/ixc/python-edtf/issues/26. +### `lower_strict` and `upper_strict` +These dates indicate the earliest and latest dates that are __strictly__ in the date range, ignoring uncertainty or approximation. One way to think about this is 'if you had to pick a single date to sort by, what would it be?'. +In an ascending sort (most recent last), sort by `lower_strict` to get a natural sort order. In a descending sort (most recent first), sort by `upper_strict`: + >>> e = parse_edtf('1912-04~') + >>> e.lower_strict() # Returns struct_time + >>> time.struct_time(tm_year=1912, tm_mon=4, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=0, tm_isdst=-1) + >>> e.lower_strict()[:3] # Show only interesting parts of struct_time + (1912, 4, 01) + >>> from edtf import struct_time_to_date + >>> struct_time_to_date(e.lower_strict()) # Convert to date + datetime.date(1912, 4, 01) + >>> e.upper_strict()[:3] + (1912, 4, 30) + >>> struct_time_to_date(e.upper_strict()) + datetime.date(1912, 4, 30) + +%prep +%autosetup -n edtf-4.0.1 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-edtf -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Fri May 05 2023 Python_Bot <Python_Bot@openeuler.org> - 4.0.1-1 +- Package Spec generated @@ -0,0 +1 @@ +7d1ca11ae8eea6ca7fd4b4c7fab76b52 edtf-4.0.1.tar.gz |