From 4757d983b8f9739d4eef84e2d6ef6b4bddbd6121 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Wed, 22 Jul 2020 10:56:46 -0700 Subject: [PATCH] FIX: update num2julian and julian2num Apply suggestions from code review Co-authored-by: Elliott Sales de Andrade --- .../deprecations/17983-JMK.rst | 14 ++++++-- lib/matplotlib/dates.py | 33 ++++++++++++++----- lib/matplotlib/tests/test_dates.py | 14 ++++++++ 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/doc/api/next_api_changes/deprecations/17983-JMK.rst b/doc/api/next_api_changes/deprecations/17983-JMK.rst index 4559b9919e6a..9d6500125bd9 100644 --- a/doc/api/next_api_changes/deprecations/17983-JMK.rst +++ b/doc/api/next_api_changes/deprecations/17983-JMK.rst @@ -1,8 +1,16 @@ -Reverted deprecation of `~.dates.num2epoch` and `~.dates.epoch2num` +Reverted deprecation of ``num2epoch`` and ``epoch2num`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These two functions were deprecated in 3.3.0, and did not return an accurate Matplotlib datenum relative to the new Matplotlib epoch handling (`~.dates.get_epoch` and :rc:`date.epoch`). This version -reverts the deprecation and fixes those functions to work with -`~.dates.get_epoch`. +reverts the deprecation. + +Functions ``epoch2num`` and ``dates.julian2num`` use ``date.epoch`` rcParam +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now `~.dates.epoch2num` and (undocumented) ``julian2num`` return floating point +days since `~.dates.get_epoch` as set by :rc:`date.epoch`, instead of +floating point days since the old epoch of "0000-12-31T00:00:00". If +needed, you can translate from the new to old values as +``old = new + mdates.date2num(np.datetime64('0000-12-31'))`` diff --git a/lib/matplotlib/dates.py b/lib/matplotlib/dates.py index 2dd2a0e9fb79..19a7f9087cf4 100644 --- a/lib/matplotlib/dates.py +++ b/lib/matplotlib/dates.py @@ -197,7 +197,13 @@ def _get_rc_timezone(): Time-related constants. """ EPOCH_OFFSET = float(datetime.datetime(1970, 1, 1).toordinal()) -JULIAN_OFFSET = 1721424.5 # Julian date at 0001-01-01 +# EPOCH_OFFSET is not used by matplotlib +JULIAN_OFFSET = 1721424.5 # Julian date at 0000-12-31 +# note that the Julian day epoch is achievable w/ +# np.datetime64('-4713-11-24T12:00:00'); datetime64 is proleptic +# Gregorian and BC has a one-year offset. So +# np.datetime64('0000-12-31') - np.datetime64('-4713-11-24T12:00') = 1721424.5 +# Ref: https://en.wikipedia.org/wiki/Julian_day MICROSECONDLY = SECONDLY + 1 HOURS_PER_DAY = 24. MIN_PER_HOUR = 60. @@ -445,14 +451,20 @@ def julian2num(j): Parameters ---------- j : float or sequence of floats - Julian date(s) + Julian dates (days relative to 4713 BC Jan 1, 12:00:00 Julian + calendar or 4714 BC Nov 24, 12:00:00, proleptic Gregorian calendar). Returns ------- float or sequence of floats - Matplotlib date(s) + Matplotlib dates (days relative to `.get_epoch`). """ - return np.subtract(j, JULIAN_OFFSET) # Handles both scalar & nonscalar j. + ep = np.datetime64(get_epoch(), 'h').astype(float) / 24. + ep0 = np.datetime64('0000-12-31T00:00:00', 'h').astype(float) / 24. + # Julian offset defined above is relative to 0000-12-31, but we need + # relative to our current epoch: + dt = JULIAN_OFFSET - ep0 + ep + return np.subtract(j, dt) # Handles both scalar & nonscalar j. def num2julian(n): @@ -462,14 +474,19 @@ def num2julian(n): Parameters ---------- n : float or sequence of floats - Matplotlib date(s) + Matplotlib dates (days relative to `.get_epoch`). Returns ------- float or sequence of floats - Julian date(s) - """ - return np.add(n, JULIAN_OFFSET) # Handles both scalar & nonscalar j. + Julian dates (days relative to 4713 BC Jan 1, 12:00:00). + """ + ep = np.datetime64(get_epoch(), 'h').astype(float) / 24. + ep0 = np.datetime64('0000-12-31T00:00:00', 'h').astype(float) / 24. + # Julian offset defined above is relative to 0000-12-31, but we need + # relative to our current epoch: + dt = JULIAN_OFFSET - ep0 + ep + return np.add(n, dt) # Handles both scalar & nonscalar j. def num2date(x, tz=None): diff --git a/lib/matplotlib/tests/test_dates.py b/lib/matplotlib/tests/test_dates.py index a446d3fd3c5c..59ad50fdb086 100644 --- a/lib/matplotlib/tests/test_dates.py +++ b/lib/matplotlib/tests/test_dates.py @@ -1010,3 +1010,17 @@ def test_epoch2num(): mdates.set_epoch('1970-01-01T00:00:00') assert mdates.epoch2num(86400) == 1.0 assert mdates.num2epoch(2.0) == 86400 * 2 + + +def test_julian2num(): + mdates._reset_epoch_test_example() + mdates.set_epoch('0000-12-31') + # 2440587.5 is julian date for 1970-01-01T00:00:00 + # https://en.wikipedia.org/wiki/Julian_day + assert mdates.julian2num(2440588.5) == 719164.0 + assert mdates.num2julian(719165.0) == 2440589.5 + # set back to the default + mdates._reset_epoch_test_example() + mdates.set_epoch('1970-01-01T00:00:00') + assert mdates.julian2num(2440588.5) == 1.0 + assert mdates.num2julian(2.0) == 2440589.5 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy