8000 Merge pull request #18053 from jklymak/auto-backport-of-pr-18021-on-v… · matplotlib/matplotlib@daf999e · GitHub
[go: up one dir, main page]

Skip to content

Commit daf999e

Browse files
authored
Merge pull request #18053 from jklymak/auto-backport-of-pr-18021-on-v3.3.x
Backport PR #18021: FIX: update num2julian and julian2num
2 parents d517420 + f4606b1 commit daf999e

File tree

3 files changed

+50
-11
lines changed

3 files changed

+50
-11
lines changed
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
Deprecations
22
------------
33

4-
Reverted deprecation of `~.dates.num2epoch` and `~.dates.epoch2num`
5-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4+
Reverted deprecation of ``num2epoch`` and ``epoch2num``
5+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66

77
These two functions were deprecated in 3.3.0, and did not return
88
an accurate Matplotlib datenum relative to the new Matplotlib epoch
99
handling (`~.dates.get_epoch` and :rc:`date.epoch`). This version
10-
reverts the deprecation and fixes those functions to work with
11-
`~.dates.get_epoch`.
10+
reverts the deprecation.
11+
12+
Functions ``epoch2num`` and ``dates.julian2num`` use ``date.epoch`` rcParam
13+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14+
15+
Now `~.dates.epoch2num` and (undocumented) ``julian2num`` return floating point
16+
days since `~.dates.get_epoch` as set by :rc:`date.epoch`, instead of
17+
floating point days since the old epoch of "0000-12-31T00:00:00". If
18+
needed, you can translate from the new to old values as
19+
``old = new + mdates.date2num(np.datetime64('0000-12-31'))``

lib/matplotlib/dates.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,13 @@ def _get_rc_timezone():
197197
Time-related constants.
198198
"""
199199
EPOCH_OFFSET = float(datetime.datetime(1970, 1, 1).toordinal())
200-
JULIAN_OFFSET = 1721424.5 # Julian date at 0001-01-01
200+
# EPOCH_OFFSET is not used by matplotlib
201+
JULIAN_OFFSET = 1721424.5 # Julian date at 0000-12-31
202+
# note that the Julian day epoch is achievable w/
203+
# np.datetime64('-4713-11-24T12:00:00'); datetime64 is proleptic
204+
# Gregorian and BC has a one-year offset. So
205+
# np.datetime64('0000-12-31') - np.datetime64('-4713-11-24T12:00') = 1721424.5
206+
# Ref: https://en.wikipedia.org/wiki/Julian_day
201207
MICROSECONDLY = SECONDLY + 1
202208
HOURS_PER_DAY = 24.
203209
MIN_PER_HOUR = 60.
@@ -445,14 +451,20 @@ def julian2num(j):
445451
Parameters
446452
----------
447453
j : float or sequence of floats
448-
Julian date(s)
454+
Julian dates (days relative to 4713 BC Jan 1, 12:00:00 Julian
455+
calendar or 4714 BC Nov 24, 12:00:00, proleptic Gregorian calendar).
449456
450457
Returns
451458
-------
452459
float or sequence of floats
453-
Matplotlib date(s)
460+
Matplotlib dates (days relative to `.get_epoch`).
454461
"""
455-
return np.subtract(j, JULIAN_OFFSET) # Handles both scalar & nonscalar j.
462+
ep = np.datetime64(get_epoch(), 'h').astype(float) / 24.
463+
ep0 = np.datetime64('0000-12-31T00:00:00', 'h').astype(float) / 24.
464+
# Julian offset defined above is relative to 0000-12-31, but we need
465+
# relative to our current epoch:
466+
dt = JULIAN_OFFSET - ep0 + ep
467+
return np.subtract(j, dt) # Handles both scalar & nonscalar j.
456468

457469

458470
def num2julian(n):
@@ -462,14 +474,19 @@ def num2julian(n):
462474
Parameters
463475
----------
464476
n : float or sequence of floats
465-
Matplotlib date(s)
477+
Matplotlib dates (days relative to `.get_epoch`).
466478
467479
Returns
468480
-------
469481
float or sequence of floats
470-
Julian date(s)
482+
Julian dates (days relative to 4713 BC Jan 1, 12:00:00).
471483
"""
472-
return np.add(n, JULIAN_OFFSET) # Handles both scalar & nonscalar j.
484+
ep = np.datetime64(get_epoch(), 'h').astype(float) / 24.
485+
ep0 = np.datetime64('0000-12-31T00:00:00', 'h').astype(float) / 24.
486+
# Julian offset defined above is relative to 0000-12-31, but we need
487+
# relative to our current epoch:
488+
dt = JULIAN_OFFSET - ep0 + ep
489+
return np.add(n, dt) # Handles both scalar & nonscalar j.
473490

474491

475492
def num2date(x, tz=None):

lib/matplotlib/tests/test_dates.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,3 +959,17 @@ def test_epoch2num():
959959
mdates.set_epoch('1970-01-01T00:00:00')
960960
assert mdates.epoch2num(86400) == 1.0
961961
assert mdates.num2epoch(2.0) == 86400 * 2
962+
963+
964+
def test_julian2num():
965+
mdates._reset_epoch_test_example()
966+
mdates.set_epoch('0000-12-31')
967+
# 2440587.5 is julian date for 1970-01-01T00:00:00
968+
# https://en.wikipedia.org/wiki/Julian_day
969+
assert mdates.julian2num(2440588.5) == 719164.0
970+
assert mdates.num2julian(719165.0) == 2440589.5
971+
# set back to the default
972+
mdates._reset_epoch_test_example()
973+
mdates.set_epoch('1970-01-01T00:00:00')
974+
assert mdates.julian2num(2440588.5) == 1.0
975+
assert mdates.num2julian(2.0) == 2440589.5

0 commit comments

Comments
 (0)
0