Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove date limits imposed by Python's datetime module #27

Merged
merged 21 commits into from
May 31, 2018

Conversation

jmurty
Copy link
Contributor

@jmurty jmurty commented Apr 13, 2018

See #26

Permit processing and representation of years
before 1 AD and after 999 AD by removing use of
Pyhon's `datetime` and related modules, which are
limited to these years.

This changes the public API so the following
methods return `struct_time` objects instead of
`date` or `datetime` objects: `lower_strict()`,
`upper_strict()`, `lower_fuzzy()`, `upper_fuzzy()`

Details:

- stop using `datetime` modules internally when
  parsing and processing EDTF syntax
- change `_strict_date()` and all dependent
  methods to return `struct_time` instead of
  objects from the `datetime` module.
  This affects public API methods listed above
- remove deliberate coercion of out-of-date year
  values to `date.min` and `date.max` boundaries
- update tests to exercise broader date ranges
The `struct_time` fields tm_wday, tm_yday, tm_isdst
are not supported by this library because we
cannot reliably generate them for years outside
1 AD to 9999 AD, therefore we ignore these fields
in comparison methods when a `struct_time`
object is provided.
- explain the switch from `datetime` module objects
  to using `time.struct_time` as responses to
  upper/lower strict/fuzzy methods
- update example code to reflect the change
- remove reference to `date.MIN` and `date.MAX`
  restrictions.
The change to returning `struct_time` objects from
the lower/upper strict/fuzzy methods broke the
`EDTFField` implementation.

This change fixes it so it can write to derived
`DateField`s again, though this is still subject
to the 1 to 9999 AD year restrictions of Python's
`datetime` module so a better fix would be to
support or require numeric target fields instead.
Copy link
Contributor

@cogat cogat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a minor function name change - rest of the solution looks solid. Nice!

}[month]


def apply_relativedelta(op, time_struct, delta):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"relativedelta" is redundant. Suggest apply_delta. Document what the op param is expected to be.

Copy link
Contributor

@markfinger markfinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Add the python module `jdutil` with many useful
date conversions, including conversion from
arbitrary dates/times to a numerical
floating-point representation that can be easily
stored in databases and other systems where we
need easy and reliably sorting and comparison of
arbitrary dates.

Note that I chose this module over other library
options available for Python because in my testing
it did the best job of keeping accuracy for
extreme dates (like year +-999,999,999) while also
generating using a number that is easier to store
than the two-float representation often used for
Julian dates.

Source: https://gist.github.com/jiffyclub/1294443
Credit to: Matt Davis, http://github.com/jiffyclub
Update `EDTFField` to store derived upper/lower
static/float dates as float values when these
fields are defined as `DoubleField` in the target
model.

This change permits representation of arbitrary
dates not limited to 1 to 9999 AD like the
alternative `DateField` target fields.

Note that the stored value is not completely
accurate and, in my testing, may drift by a few
years for negative years in the thousands or
millions – which seems like a reasonable
limitation.
Unit test time conversion utilities, and fix a
couple of bugs surfaced by tests.
Use a better name `edtf.convert` instead of
`edtf.utils`
Add `struct_time_to_jd` and `jd_to_struct_time`
functions to `edtf.convert` module to handle
conversion to and from Julian Date numerical
float values.

These functions greatly simplify Julian Date (JD)
conversions, especially for converting from JD
values where fiddly handling may be required to
convert negative month/day/hour/minute/second
values returned by the `jdutil` module.
@jmurty jmurty merged commit dd3d082 into master May 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants