cftime 1.6.2__tar.gz → 1.6.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cftime-1.6.2 → cftime-1.6.4}/Changelog +16 -0
- {cftime-1.6.2/src/cftime.egg-info → cftime-1.6.4}/PKG-INFO +10 -3
- {cftime-1.6.2 → cftime-1.6.4}/README.md +4 -0
- cftime-1.6.4/pyproject.toml +9 -0
- {cftime-1.6.2 → cftime-1.6.4}/requirements-dev.txt +1 -1
- cftime-1.6.4/requirements.txt +2 -0
- {cftime-1.6.2 → cftime-1.6.4}/setup.py +20 -9
- {cftime-1.6.2 → cftime-1.6.4}/src/cftime/_cftime.pyx +13 -3
- {cftime-1.6.2 → cftime-1.6.4}/src/cftime/_strptime.py +4 -2
- {cftime-1.6.2 → cftime-1.6.4/src/cftime.egg-info}/PKG-INFO +10 -3
- cftime-1.6.4/src/cftime.egg-info/requires.txt +6 -0
- {cftime-1.6.2 → cftime-1.6.4}/test/test_cftime.py +131 -110
- cftime-1.6.2/pyproject.toml +0 -3
- cftime-1.6.2/requirements.txt +0 -1
- cftime-1.6.2/src/cftime.egg-info/requires.txt +0 -1
- {cftime-1.6.2 → cftime-1.6.4}/LICENSE +0 -0
- {cftime-1.6.2 → cftime-1.6.4}/MANIFEST.in +0 -0
- {cftime-1.6.2 → cftime-1.6.4}/setup.cfg +0 -0
- {cftime-1.6.2 → cftime-1.6.4}/src/cftime/__init__.py +0 -0
- {cftime-1.6.2 → cftime-1.6.4}/src/cftime.egg-info/SOURCES.txt +0 -0
- {cftime-1.6.2 → cftime-1.6.4}/src/cftime.egg-info/dependency_links.txt +0 -0
- {cftime-1.6.2 → cftime-1.6.4}/src/cftime.egg-info/top_level.txt +0 -0
- {cftime-1.6.2 → cftime-1.6.4}/test/__init__.py +0 -0
- {cftime-1.6.2 → cftime-1.6.4}/test/benchmark.py +0 -0
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
version 1.6.4 (release tag v1.6.4rel)
|
|
2
|
+
=====================================
|
|
3
|
+
* build aarch64 linux wheels (issue #333).
|
|
4
|
+
* build musllinux wheels (issue #307).
|
|
5
|
+
* return empty array if one provided to date2num (issue #315).
|
|
6
|
+
* numpy 2.0 compatibility (issue #325).
|
|
7
|
+
* handle nan/inf in num2date (issue #328).
|
|
8
|
+
|
|
9
|
+
version 1.6.3 (release tag v1.6.3rel)
|
|
10
|
+
=====================================
|
|
11
|
+
* add support for formats without separators in strptime (e.g. '20200229', issue #301).
|
|
12
|
+
This required removing support for > 4 digit years.
|
|
13
|
+
* set the c_api_binop_methods compiler directive to True to retain Cython 0.x
|
|
14
|
+
behavior for arithmetic operators for Cython >= 3.0.0 (issue #271).
|
|
15
|
+
* support for python 3.12.
|
|
16
|
+
|
|
1
17
|
version 1.6.2 (release tag v1.6.2rel)
|
|
2
18
|
=====================================
|
|
3
19
|
* num2date should not fail on an empty integer array (issue #287).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cftime
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.4
|
|
4
4
|
Summary: Time-handling functionality from netcdf4-python
|
|
5
5
|
Author: Jeff Whitaker
|
|
6
6
|
Author-email: jeffrey.s.whitaker@noaa.gov
|
|
@@ -11,15 +11,18 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
11
11
|
Classifier: Operating System :: POSIX :: Linux
|
|
12
12
|
Classifier: Programming Language :: Python
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.8
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
19
|
Classifier: Topic :: Scientific/Engineering
|
|
19
20
|
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.8
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
22
23
|
License-File: LICENSE
|
|
24
|
+
Requires-Dist: numpy>1.13.3; python_version < "3.12.0.rc1"
|
|
25
|
+
Requires-Dist: numpy>=1.26.0b1; python_version >= "3.12.0.rc1"
|
|
23
26
|
|
|
24
27
|
# cftime
|
|
25
28
|
Time-handling functionality from netcdf4-python
|
|
@@ -34,6 +37,10 @@ Time-handling functionality from netcdf4-python
|
|
|
34
37
|
|
|
35
38
|
## News
|
|
36
39
|
For details on the latest updates, see the [Changelog](https://github.com/Unidata/cftime/blob/master/Changelog).
|
|
40
|
+
|
|
41
|
+
6/7/2024: Version 1.6.4 release. Wheels for muslinux and aarch64, numpy 2.0 compatibility.
|
|
42
|
+
|
|
43
|
+
10/20/2023: Version 1.6.3 released. Support for python 3.12, cython 3.0, strptime formats without separators.
|
|
37
44
|
|
|
38
45
|
9/18/2022: Version 1.6.2 released. strptime method added, fix for num2date failure on
|
|
39
46
|
empty integer array, date2num 'longdouble' keyword added. New wheel building workflow.
|
|
@@ -11,6 +11,10 @@ Time-handling functionality from netcdf4-python
|
|
|
11
11
|
|
|
12
12
|
## News
|
|
13
13
|
For details on the latest updates, see the [Changelog](https://github.com/Unidata/cftime/blob/master/Changelog).
|
|
14
|
+
|
|
15
|
+
6/7/2024: Version 1.6.4 release. Wheels for muslinux and aarch64, numpy 2.0 compatibility.
|
|
16
|
+
|
|
17
|
+
10/20/2023: Version 1.6.3 released. Support for python 3.12, cython 3.0, strptime formats without separators.
|
|
14
18
|
|
|
15
19
|
9/18/2022: Version 1.6.2 released. strptime method added, fix for num2date failure on
|
|
16
20
|
empty integer array, date2num 'longdouble' keyword added. New wheel building workflow.
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from __future__ import print_function
|
|
2
|
-
|
|
3
1
|
import os
|
|
4
2
|
import sys
|
|
5
3
|
import numpy
|
|
@@ -16,7 +14,20 @@ except ImportError:
|
|
|
16
14
|
BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
|
17
15
|
SRCDIR = os.path.join(BASEDIR,'src')
|
|
18
16
|
CMDS_NOCYTHONIZE = ['clean','clean_cython','sdist']
|
|
19
|
-
COMPILER_DIRECTIVES = {
|
|
17
|
+
COMPILER_DIRECTIVES = {
|
|
18
|
+
# Cython 3.0.0 changes the default of the c_api_binop_methods directive to
|
|
19
|
+
# False, resulting in errors in datetime and timedelta arithmetic:
|
|
20
|
+
# https://github.com/Unidata/cftime/issues/271. We explicitly set it to
|
|
21
|
+
# True to retain Cython 0.x behavior for future Cython versions. This
|
|
22
|
+
# directive was added in Cython version 0.29.20.
|
|
23
|
+
"c_api_binop_methods": True
|
|
24
|
+
}
|
|
25
|
+
COVERAGE_COMPILER_DIRECTIVES = {
|
|
26
|
+
"linetrace": True,
|
|
27
|
+
"warn.maybe_uninitialized": False,
|
|
28
|
+
"warn.unreachable": False,
|
|
29
|
+
"warn.unused": False,
|
|
30
|
+
}
|
|
20
31
|
DEFINE_MACROS = [("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]
|
|
21
32
|
FLAG_COVERAGE = '--cython-coverage' # custom flag enabling Cython line tracing
|
|
22
33
|
NAME = 'cftime'
|
|
@@ -74,10 +85,9 @@ def description():
|
|
|
74
85
|
|
|
75
86
|
if ((FLAG_COVERAGE in sys.argv or os.environ.get('CYTHON_COVERAGE', None))
|
|
76
87
|
and cythonize):
|
|
77
|
-
COMPILER_DIRECTIVES = {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
'warn.unused': False}
|
|
88
|
+
COMPILER_DIRECTIVES = {
|
|
89
|
+
**COMPILER_DIRECTIVES, **COVERAGE_COMPILER_DIRECTIVES
|
|
90
|
+
}
|
|
81
91
|
DEFINE_MACROS += [('CYTHON_TRACE', '1'),
|
|
82
92
|
('CYTHON_TRACE_NOGIL', '1')]
|
|
83
93
|
if FLAG_COVERAGE in sys.argv:
|
|
@@ -113,7 +123,7 @@ setup(
|
|
|
113
123
|
install_requires=load('requirements.txt'),
|
|
114
124
|
tests_require=load('requirements-dev.txt'),
|
|
115
125
|
license='License :: OSI Approved :: MIT License',
|
|
116
|
-
python_requires=">=3.
|
|
126
|
+
python_requires=">=3.8",
|
|
117
127
|
classifiers=[
|
|
118
128
|
'Development Status :: 5 - Production/Stable',
|
|
119
129
|
'Operating System :: MacOS :: MacOS X',
|
|
@@ -121,10 +131,11 @@ setup(
|
|
|
121
131
|
'Operating System :: POSIX :: Linux',
|
|
122
132
|
'Programming Language :: Python',
|
|
123
133
|
'Programming Language :: Python :: 3',
|
|
124
|
-
'Programming Language :: Python :: 3.7',
|
|
125
134
|
'Programming Language :: Python :: 3.8',
|
|
126
135
|
'Programming Language :: Python :: 3.9',
|
|
127
136
|
'Programming Language :: Python :: 3.10',
|
|
137
|
+
'Programming Language :: Python :: 3.11',
|
|
138
|
+
'Programming Language :: Python :: 3.12',
|
|
128
139
|
'Topic :: Scientific/Engineering',
|
|
129
140
|
'License :: OSI Approved :: MIT License'],
|
|
130
141
|
)
|
|
@@ -7,6 +7,7 @@ from cpython.object cimport (PyObject_RichCompare, Py_LT, Py_LE, Py_EQ,
|
|
|
7
7
|
from numpy cimport int64_t, int32_t
|
|
8
8
|
import cython
|
|
9
9
|
import numpy as np
|
|
10
|
+
cimport numpy as np
|
|
10
11
|
import re
|
|
11
12
|
import time
|
|
12
13
|
from datetime import datetime as datetime_python
|
|
@@ -14,6 +15,8 @@ from datetime import timedelta, MINYEAR, MAXYEAR
|
|
|
14
15
|
import warnings
|
|
15
16
|
from ._strptime import _strptime
|
|
16
17
|
|
|
18
|
+
np.import_array()
|
|
19
|
+
|
|
17
20
|
microsec_units = ['microseconds','microsecond', 'microsec', 'microsecs']
|
|
18
21
|
millisec_units = ['milliseconds', 'millisecond', 'millisec', 'millisecs', 'msec', 'msecs', 'ms']
|
|
19
22
|
sec_units = ['second', 'seconds', 'sec', 'secs', 's']
|
|
@@ -37,7 +40,7 @@ cdef int[12] _dayspermonth_leap = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 3
|
|
|
37
40
|
cdef int[13] _cumdayspermonth = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]
|
|
38
41
|
cdef int[13] _cumdayspermonth_leap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366]
|
|
39
42
|
|
|
40
|
-
__version__ = '1.6.
|
|
43
|
+
__version__ = '1.6.4'
|
|
41
44
|
|
|
42
45
|
# Adapted from http://delete.me.uk/2005/03/iso8601.html
|
|
43
46
|
# Note: This regex ensures that all ISO8601 timezone formats are accepted - but, due to legacy support for other timestrings, not all incorrect formats can be rejected.
|
|
@@ -193,7 +196,11 @@ def date2num(dates, units, calendar=None, has_year_zero=None, longdouble=False):
|
|
|
193
196
|
try:
|
|
194
197
|
dates[0]
|
|
195
198
|
except:
|
|
196
|
-
|
|
199
|
+
if not dates:
|
|
200
|
+
# if empty list or array input, return empty array (issue #315)
|
|
201
|
+
return np.array([],dtype=float)
|
|
202
|
+
else:
|
|
203
|
+
isscalar = True
|
|
197
204
|
|
|
198
205
|
# masked array input?
|
|
199
206
|
ismasked = False
|
|
@@ -613,6 +620,9 @@ def num2date(
|
|
|
613
620
|
factor = UNIT_CONVERSION_FACTORS[unit]
|
|
614
621
|
times = np.asanyarray(times) # Allow list as input
|
|
615
622
|
times = upcast_times(times)
|
|
623
|
+
# convert to masked array if any nan or inf values present
|
|
624
|
+
if not np.isfinite(times).all():
|
|
625
|
+
times = np.ma.masked_invalid(times)
|
|
616
626
|
scaled_times = scale_times(times, factor)
|
|
617
627
|
scaled_times = cast_to_int(scaled_times,units=unit)
|
|
618
628
|
|
|
@@ -1051,7 +1061,7 @@ This class mimics datetime.datetime but support calendars other than the prolept
|
|
|
1051
1061
|
Gregorian calendar.
|
|
1052
1062
|
|
|
1053
1063
|
Supports timedelta operations by overloading +/-, and
|
|
1054
|
-
comparisons with other instances
|
|
1064
|
+
comparisons with other instances (even if they use different calendars).
|
|
1055
1065
|
|
|
1056
1066
|
Comparison with native python datetime instances is possible
|
|
1057
1067
|
for cftime.datetime instances using
|
|
@@ -30,8 +30,10 @@ class TimeRE(dict):
|
|
|
30
30
|
'M': r"(?P<M>[0-5]\d|\d)",
|
|
31
31
|
'S': r"(?P<S>6[0-1]|[0-5]\d|\d)",
|
|
32
32
|
'y': r"(?P<y>\d\d)",
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
'Y': r"(?P<Y>[+-]?\d\d\d\d)", # 4 digit years, pos or neg
|
|
34
|
+
# the next one allows for > 4 digit years, but doesn't work without separators
|
|
35
|
+
# (e.g. '%Y%m%d%H', see issue #301)
|
|
36
|
+
# 'Y': r"(?P<Y>[+-]?[0-9]+)", # handle neg and > 4 digits
|
|
35
37
|
'B': self.__seqToRE(month_name[1:], 'B'),
|
|
36
38
|
'b': self.__seqToRE(month_abbr[1:], 'b'),
|
|
37
39
|
'%': '%'})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cftime
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.4
|
|
4
4
|
Summary: Time-handling functionality from netcdf4-python
|
|
5
5
|
Author: Jeff Whitaker
|
|
6
6
|
Author-email: jeffrey.s.whitaker@noaa.gov
|
|
@@ -11,15 +11,18 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
11
11
|
Classifier: Operating System :: POSIX :: Linux
|
|
12
12
|
Classifier: Programming Language :: Python
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.8
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
19
|
Classifier: Topic :: Scientific/Engineering
|
|
19
20
|
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.8
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
22
23
|
License-File: LICENSE
|
|
24
|
+
Requires-Dist: numpy>1.13.3; python_version < "3.12.0.rc1"
|
|
25
|
+
Requires-Dist: numpy>=1.26.0b1; python_version >= "3.12.0.rc1"
|
|
23
26
|
|
|
24
27
|
# cftime
|
|
25
28
|
Time-handling functionality from netcdf4-python
|
|
@@ -34,6 +37,10 @@ Time-handling functionality from netcdf4-python
|
|
|
34
37
|
|
|
35
38
|
## News
|
|
36
39
|
For details on the latest updates, see the [Changelog](https://github.com/Unidata/cftime/blob/master/Changelog).
|
|
40
|
+
|
|
41
|
+
6/7/2024: Version 1.6.4 release. Wheels for muslinux and aarch64, numpy 2.0 compatibility.
|
|
42
|
+
|
|
43
|
+
10/20/2023: Version 1.6.3 released. Support for python 3.12, cython 3.0, strptime formats without separators.
|
|
37
44
|
|
|
38
45
|
9/18/2022: Version 1.6.2 released. strptime method added, fix for num2date failure on
|
|
39
46
|
empty integer array, date2num 'longdouble' keyword added. New wheel building workflow.
|
|
@@ -6,8 +6,6 @@ from cftime import (Datetime360Day, DatetimeAllLeap,
|
|
|
6
6
|
DatetimeProlepticGregorian, _parse_date,
|
|
7
7
|
date2index, date2num, num2date, UNIT_CONVERSION_FACTORS)
|
|
8
8
|
import copy
|
|
9
|
-
import operator
|
|
10
|
-
import sys
|
|
11
9
|
import unittest
|
|
12
10
|
import warnings
|
|
13
11
|
from collections import namedtuple
|
|
@@ -330,17 +328,17 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
330
328
|
for t in (733498.999, 733498.9999, 733498.99999, 733498.999999, 733498.9999999):
|
|
331
329
|
d = num2date(t, units='days since 0001-01-01 00:00:00')
|
|
332
330
|
t2 = date2num(d, units='days since 0001-01-01 00:00:00')
|
|
333
|
-
assert
|
|
331
|
+
assert abs(t2 - t) < 1e-5 # values should be less than second
|
|
334
332
|
# Check equality testing
|
|
335
333
|
d1 = datetimex(1979, 6, 21, 9, 23, 12, calendar='standard')
|
|
336
334
|
d2 = datetime(1979, 6, 21, 9, 23, 12)
|
|
337
|
-
assert
|
|
335
|
+
assert d1 == d2
|
|
338
336
|
# check timezone offset
|
|
339
337
|
d = datetime(2012, 2, 29, 15)
|
|
340
338
|
# mixed_tz is -6 hours from UTC, mixed is UTC so
|
|
341
339
|
# difference in elapsed time is -6 hours.
|
|
342
|
-
assert
|
|
343
|
-
d) - self.cdftime_mixed.date2num(d) == -6
|
|
340
|
+
assert self.cdftime_mixed_tz.date2num(
|
|
341
|
+
d) - self.cdftime_mixed.date2num(d) == -6
|
|
344
342
|
|
|
345
343
|
# Check comparisons with Python datetime types
|
|
346
344
|
|
|
@@ -402,7 +400,7 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
402
400
|
|
|
403
401
|
#issue 344
|
|
404
402
|
units = 'hours since 2013-12-12T12:00:00'
|
|
405
|
-
assert
|
|
403
|
+
assert 1.0 == date2num(num2date(1.0, units), units)
|
|
406
404
|
|
|
407
405
|
# test roundtrip accuracy
|
|
408
406
|
# also tests error found in issue #349
|
|
@@ -416,43 +414,49 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
416
414
|
times2 = date2num(dates1,units,calendar=calendar)
|
|
417
415
|
dates2 = num2date(times2,units,calendar=calendar)
|
|
418
416
|
err = np.abs(times1 - times2)
|
|
419
|
-
assert
|
|
417
|
+
assert np.all(err<eps)
|
|
420
418
|
dates1 = [date.strftime(dateformat) for date in dates1]
|
|
421
419
|
dates2 = [date.strftime(dateformat) for date in dates2]
|
|
422
|
-
assert
|
|
420
|
+
assert dates1==dates2
|
|
423
421
|
return err.max()
|
|
424
422
|
for calendar in calendars:
|
|
425
|
-
eps = 1
|
|
423
|
+
eps = 1.
|
|
424
|
+
delta = 1.
|
|
426
425
|
units = 'microseconds since 2000-01-30 01:01:01'
|
|
427
426
|
maxerr = roundtrip(eps,delta,units)
|
|
428
427
|
if verbose:
|
|
429
428
|
print('calendar = %s max abs err (microsecs) = %s eps = %s' % \
|
|
430
429
|
(calendar,maxerr,eps))
|
|
431
|
-
eps = 0.001
|
|
430
|
+
eps = 0.001
|
|
431
|
+
delta = 0.001
|
|
432
432
|
units = 'milliseconds since 2000-01-30 01:01:01'
|
|
433
433
|
maxerr = roundtrip(eps,delta,units)
|
|
434
434
|
if verbose:
|
|
435
435
|
print('calendar = %s max abs err (millisecs) = %s eps = %s' % \
|
|
436
436
|
(calendar,maxerr,eps))
|
|
437
|
-
eps = 1.e-5
|
|
437
|
+
eps = 1.e-5
|
|
438
|
+
delta = 0.1
|
|
438
439
|
units = 'seconds since 0001-01-30 01:01:01'
|
|
439
440
|
maxerr = roundtrip(eps,delta,units)
|
|
440
441
|
if verbose:
|
|
441
442
|
print('calendar = %s max abs err (secs) = %s eps = %s' % \
|
|
442
443
|
(calendar,maxerr,eps))
|
|
443
|
-
eps = 1.e-6
|
|
444
|
+
eps = 1.e-6
|
|
445
|
+
delta = 0.01
|
|
444
446
|
units = 'minutes since 0001-01-30 01:01:01'
|
|
445
447
|
maxerr = roundtrip(eps,delta,units)
|
|
446
448
|
if verbose:
|
|
447
449
|
print('calendar = %s max abs err (mins) = %s eps = %s' % \
|
|
448
450
|
(calendar,maxerr,eps))
|
|
449
|
-
eps = 1.e-8
|
|
451
|
+
eps = 1.e-8
|
|
452
|
+
delta = 0.001
|
|
450
453
|
units = 'hours since 0001-01-30 01:01:01'
|
|
451
454
|
maxerr = roundtrip(eps,delta,units)
|
|
452
455
|
if verbose:
|
|
453
456
|
print('calendar = %s max abs err (hours) = %s eps = %s' % \
|
|
454
457
|
(calendar,maxerr,eps))
|
|
455
|
-
eps = 1.e-9
|
|
458
|
+
eps = 1.e-9
|
|
459
|
+
delta = 0.00001
|
|
456
460
|
units = 'days since 0001-01-30 01:01:01'
|
|
457
461
|
maxerr = roundtrip(eps,delta,units)
|
|
458
462
|
if verbose:
|
|
@@ -460,20 +464,19 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
460
464
|
(calendar,maxerr,eps))
|
|
461
465
|
|
|
462
466
|
# issue 353
|
|
463
|
-
assert
|
|
464
|
-
datetime(2000,1,1,0))
|
|
467
|
+
assert num2date(0, 'hours since 2000-01-01 0') == datetime(2000,1,1,0)
|
|
465
468
|
|
|
466
469
|
# issue 354
|
|
467
470
|
num1 = np.array([[0, 1], [2, 3]])
|
|
468
471
|
num2 = np.array([[0, 1], [2, 3]])
|
|
469
472
|
dates1 = num2date(num1, 'days since 0001-01-01')
|
|
470
473
|
dates2 = num2date(num2, 'days since 2001-01-01')
|
|
471
|
-
assert
|
|
472
|
-
assert
|
|
474
|
+
assert dates1.shape == (2,2)
|
|
475
|
+
assert dates2.shape == (2,2)
|
|
473
476
|
num1b = date2num(dates1, 'days since 0001-01-01')
|
|
474
477
|
num2b = date2num(dates2, 'days since 2001-01-01')
|
|
475
|
-
assert
|
|
476
|
-
assert
|
|
478
|
+
assert num1b.shape == (2,2)
|
|
479
|
+
assert num2b.shape == (2,2)
|
|
477
480
|
assert_almost_equal(num1,num1b)
|
|
478
481
|
assert_almost_equal(num2,num2b)
|
|
479
482
|
|
|
@@ -484,8 +487,8 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
484
487
|
date = datetime(1682,10,15) # assumed UTC
|
|
485
488
|
num = date2num(date,units)
|
|
486
489
|
# UTC is 7 hours ahead of units, so num should be -7
|
|
487
|
-
assert
|
|
488
|
-
assert
|
|
490
|
+
assert num == -7
|
|
491
|
+
assert num2date(num, units) == date
|
|
489
492
|
units = 'hours since 1482-10-15 -07:00 UTC'
|
|
490
493
|
# date before gregorian switch, cftime datetime used
|
|
491
494
|
date = datetime(1482,10,15)
|
|
@@ -541,7 +544,7 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
541
544
|
d = num2date(0, units, calendar="standard")
|
|
542
545
|
#self.assertEqual(d, utc_date)
|
|
543
546
|
# tolerance of 1.e-3 secs
|
|
544
|
-
assert
|
|
547
|
+
assert np.abs((d-utc_date).total_seconds()) < 1.e-3
|
|
545
548
|
# also test with negative values to cover 2nd code path
|
|
546
549
|
d = num2date(-1, units, calendar="standard")
|
|
547
550
|
self.assertEqual(d, utc_date - timedelta(hours=1))
|
|
@@ -608,7 +611,7 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
608
611
|
# cftime issue #134
|
|
609
612
|
d = num2date(-657071, units, calendar='proleptic_gregorian',
|
|
610
613
|
only_use_cftime_datetimes=False,only_use_python_datetimes=True)
|
|
611
|
-
assert
|
|
614
|
+
assert d==datetime(1,1,1,0)
|
|
612
615
|
self.assertRaises(ValueError, num2date, \
|
|
613
616
|
-657072, units, calendar='proleptic_gregorian',
|
|
614
617
|
only_use_cftime_datetimes=False,only_use_python_datetimes=True)
|
|
@@ -619,11 +622,11 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
619
622
|
utc_date = datetime(2000,1,1,18,30)
|
|
620
623
|
for units in ("hours since 2000-01-01 22:30+04:00", "hours since 2000-01-01 11:30-07:00", "hours since 2000-01-01 15:00-03:30"):
|
|
621
624
|
d = num2date(0, units, calendar="standard")
|
|
622
|
-
assert
|
|
625
|
+
assert np.abs((d-utc_date).total_seconds()) < 1.e-3
|
|
623
626
|
# also test with negative values to cover 2nd code path
|
|
624
627
|
d = num2date(-1, units, calendar="standard")
|
|
625
|
-
assert
|
|
626
|
-
(utc_date-timedelta(hours=1))).total_seconds()) < 1.e-3
|
|
628
|
+
assert np.abs((d - \
|
|
629
|
+
(utc_date-timedelta(hours=1))).total_seconds()) < 1.e-3
|
|
627
630
|
|
|
628
631
|
n = date2num(utc_date, units, calendar="standard")
|
|
629
632
|
# n should always be 0 as all units refer to the same point in time
|
|
@@ -698,7 +701,7 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
698
701
|
d1 = datetimex(2020, 5, 20, dayofwk=8, dayofyr=9, calendar='')
|
|
699
702
|
assert (d1.dayofwk == 8)
|
|
700
703
|
assert (d1.dayofyr == 9)
|
|
701
|
-
|
|
704
|
+
|
|
702
705
|
# issue 71: negative reference years
|
|
703
706
|
# https://coastwatch.pfeg.noaa.gov/erddap/convert/time.html
|
|
704
707
|
# gives 2446433 (365 days more - is it counting year 0?)
|
|
@@ -722,17 +725,17 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
722
725
|
self.assertRaises(ValueError, utime, \
|
|
723
726
|
'months since 01-01-01', calendar='standard')
|
|
724
727
|
# issue #78 - extra digits due to roundoff
|
|
725
|
-
assert
|
|
726
|
-
assert
|
|
727
|
-
assert
|
|
728
|
+
assert cftime.date2num(cftime.datetime(1, 12, 1, 0, 0, 0, 0, -1, 1), units='days since 01-01-01',calendar='noleap') == 334.0
|
|
729
|
+
assert cftime.date2num(cftime.num2date(1.0,units='days since 01-01-01',calendar='noleap'),units='days since 01-01-01',calendar='noleap') == 1.0
|
|
730
|
+
assert cftime.date2num(cftime.DatetimeNoLeap(1980, 1, 1, 0, 0, 0, 0, 6, 1),'days since 1970-01-01','noleap') == 3650.0
|
|
728
731
|
# issue #126
|
|
729
732
|
d = cftime.DatetimeProlepticGregorian(1, 1, 1)
|
|
730
|
-
assert
|
|
731
|
-
'proleptic_gregorian') == 0.0
|
|
733
|
+
assert cftime.date2num(d, 'days since 0001-01-01',\
|
|
734
|
+
'proleptic_gregorian') == 0.0
|
|
732
735
|
# issue #140 (fractional seconds in reference date)
|
|
733
736
|
d = datetime.strptime('2018-01-23 09:27:10.950000',"%Y-%m-%d %H:%M:%S.%f")
|
|
734
737
|
units = 'seconds since 2018-01-23 09:31:42.94'
|
|
735
|
-
assert
|
|
738
|
+
assert float(cftime.date2num(d, units)) == -271.99
|
|
736
739
|
# issue 143 - same answer for arrays vs scalars.
|
|
737
740
|
units = 'seconds since 1970-01-01 00:00:00'
|
|
738
741
|
times_in = [1261440000.0, 1261440001.0, 1261440002.0, 1261440003.0,
|
|
@@ -743,34 +746,34 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
743
746
|
times_out2.append(cftime.num2date(time_in, units))
|
|
744
747
|
dates1 = [str(d) for d in times_out1]
|
|
745
748
|
dates2 = [str(d) for d in times_out2]
|
|
746
|
-
assert
|
|
749
|
+
assert dates1 == dates2
|
|
747
750
|
# issue #143 formatting of microseconds
|
|
748
751
|
d = cftime.num2date(1261440000.015625,units)
|
|
749
752
|
# on windows only 100 ms precision
|
|
750
|
-
assert
|
|
753
|
+
assert str(d)[0:24] == '2009-12-22 00:00:00.0156'
|
|
751
754
|
# issue #152 add isoformat()
|
|
752
|
-
assert
|
|
753
|
-
assert
|
|
754
|
-
assert
|
|
755
|
-
assert
|
|
756
|
-
assert
|
|
757
|
-
assert
|
|
755
|
+
assert d.isoformat()[0:24] == '2009-12-22T00:00:00.0156'
|
|
756
|
+
assert d.isoformat(sep=' ')[0:24] == '2009-12-22 00:00:00.0156'
|
|
757
|
+
assert d.isoformat(sep=' ',timespec='milliseconds') == '2009-12-22 00:00:00.016'
|
|
758
|
+
assert d.isoformat(sep=' ',timespec='seconds') == '2009-12-22 00:00:00'
|
|
759
|
+
assert d.isoformat(sep=' ',timespec='minutes') == '2009-12-22 00:00'
|
|
760
|
+
assert d.isoformat(sep=' ',timespec='hours') == '2009-12-22 00'
|
|
758
761
|
# issue #165: make sure python datetime returned
|
|
759
762
|
d=num2date(0,units="seconds since 2000-01-01 00:00:00",only_use_cftime_datetimes=False)
|
|
760
763
|
assert isinstance(d, datetime)
|
|
761
764
|
# issue #169: cftime.datetime has no calendar attribute, causing dayofwk,dayofyr methods
|
|
762
765
|
# to fail.
|
|
763
766
|
c = cftime.datetime(*cftime._parse_date('7480-01-01 00:00:00'),calendar='standard')
|
|
764
|
-
assert
|
|
767
|
+
assert c.strftime() == '7480-01-01 00:00:00'
|
|
765
768
|
# issue #175: masked values not treated properly in num2date
|
|
766
769
|
times = np.ma.masked_array([-3956.7499999995343,-999999999999],mask=[False,True])
|
|
767
770
|
units='days since 1858-11-17 00:00:00'
|
|
768
771
|
dates = num2date(times, units=units, calendar='standard',\
|
|
769
772
|
only_use_cftime_datetimes=False, only_use_python_datetimes=True)
|
|
770
773
|
test = dates == np.ma.masked_array([datetime(1848, 1, 17, 6, 0, 0, 40), None],mask=[0,1])
|
|
771
|
-
assert
|
|
774
|
+
assert test.all()
|
|
772
775
|
dates = num2date(times, units=units, calendar='standard')
|
|
773
|
-
assert
|
|
776
|
+
assert str(dates)=="[cftime.DatetimeGregorian(1848, 1, 17, 6, 0, 0, 40, has_year_zero=False)\n --]"
|
|
774
777
|
# check that time range of 200,000 + years can be represented accurately
|
|
775
778
|
calendar='standard'
|
|
776
779
|
_MAX_INT64 = np.iinfo("int64").max
|
|
@@ -779,13 +782,13 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
779
782
|
units = '%s since 01-01-01' % unit
|
|
780
783
|
time = 292471*365*86400*(1000000//int(UNIT_CONVERSION_FACTORS[unit])) + 1000000//int(UNIT_CONVERSION_FACTORS[unit])
|
|
781
784
|
date = num2date(time,units,calendar=calendar)
|
|
782
|
-
assert
|
|
785
|
+
assert date == refdate
|
|
783
786
|
# check round-trip
|
|
784
787
|
time2 = date2num(date,units,calendar=calendar)
|
|
785
788
|
date2 = num2date(time2,units,calendar=calendar)
|
|
786
789
|
# windows doesn't have a longdouble type (it defaults to float64)
|
|
787
790
|
if np.finfo(np.longdouble).precision == 18:
|
|
788
|
-
assert
|
|
791
|
+
assert date2 == refdate
|
|
789
792
|
# microsecond roundtrip accuracy preserved over time ranges of 286 years
|
|
790
793
|
# (float64 can only represent integers exactly up to 2**53-1)
|
|
791
794
|
refdate=DatetimeGregorian(286,6,3,23,47,34,740992)
|
|
@@ -793,11 +796,11 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
793
796
|
units = '%s since 01-01-01' % unit
|
|
794
797
|
time = (2**53 - 1)*(1/UNIT_CONVERSION_FACTORS[unit]) + 1/UNIT_CONVERSION_FACTORS[unit]
|
|
795
798
|
date = num2date(time,units,calendar=calendar)
|
|
796
|
-
assert
|
|
799
|
+
assert date == refdate
|
|
797
800
|
# check round-trip
|
|
798
801
|
time2 = date2num(date,units,calendar=calendar)
|
|
799
802
|
date2 = num2date(time2,units,calendar=calendar)
|
|
800
|
-
assert
|
|
803
|
+
assert date2 == refdate
|
|
801
804
|
# issue #185: date2num should work the numpy scalar array of dates (1.2.0 regression)
|
|
802
805
|
dates = np.array(datetime(2010, 2, 2, 0, 0))
|
|
803
806
|
assert (date2num(dates, units="hours since 2010-02-01 00:00:00") == 24.)
|
|
@@ -808,7 +811,7 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
808
811
|
units = 'days since -4713-01-01 12:00'
|
|
809
812
|
dt2 = num2date(date2num(dt1, units), units, calendar='proleptic_gregorian')
|
|
810
813
|
dt2 = num2date(date2num(dt1, units, calendar='standard'), units)
|
|
811
|
-
assert
|
|
814
|
+
assert dt1 == dt2
|
|
812
815
|
# issue #189 - leap years calculated incorrectly for negative years in proleptic_gregorian calendar
|
|
813
816
|
dt1 = datetime(2020, 4, 24, 16, 15, 10) # python datetime
|
|
814
817
|
units = 'days since -4713-01-01 12:00'
|
|
@@ -817,32 +820,32 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
817
820
|
warnings.simplefilter("ignore",category=cftime.CFWarning)
|
|
818
821
|
dt2 = num2date(date2num(dt1, units, cal, has_year_zero=False), units,
|
|
819
822
|
cal, has_year_zero=False)
|
|
820
|
-
assert
|
|
823
|
+
assert dt1 == dt2
|
|
821
824
|
# issue #198 - cftime.datetime creates calendar specific datetimes that
|
|
822
825
|
# support addition/subtraction of timedeltas.
|
|
823
826
|
for cal in calendars:
|
|
824
827
|
dt = cftime.datetime(2020, 1, 1, calendar=cal)
|
|
825
828
|
dt += timedelta(hours=1)
|
|
826
|
-
assert
|
|
829
|
+
assert str(dt) == '2020-01-01 01:00:00'
|
|
827
830
|
# issue #193 - years with more than four digits in reference date
|
|
828
|
-
assert
|
|
831
|
+
assert cftime.date2num(cftime.datetime(18000, 12, 1, 0, 0), 'days since 18000-1-1', '360_day') == 330.0
|
|
829
832
|
# julian day not including year zero
|
|
830
833
|
d = cftime.datetime(2020, 12, 1, 12, calendar='julian')
|
|
831
834
|
with warnings.catch_warnings():
|
|
832
835
|
warnings.simplefilter("ignore",category=cftime.CFWarning)
|
|
833
836
|
units = 'days since -4713-1-1 12:00'
|
|
834
837
|
jd = cftime.date2num(d,units,calendar='julian')
|
|
835
|
-
assert
|
|
838
|
+
assert jd == 2459198.0
|
|
836
839
|
# if calendar=None, use input date to determine calendar
|
|
837
840
|
jd = cftime.date2num(d,units,calendar=None)
|
|
838
|
-
assert
|
|
841
|
+
assert jd == 2459198.0
|
|
839
842
|
# if no calendar specified, use calendar associated with datetime
|
|
840
843
|
# instance.
|
|
841
844
|
jd = cftime.date2num(d,units)
|
|
842
|
-
assert
|
|
845
|
+
assert jd == 2459198.0
|
|
843
846
|
# use 'standard' calendar
|
|
844
847
|
jd = cftime.date2num(d,units,calendar='standard')
|
|
845
|
-
assert
|
|
848
|
+
assert jd == 2459185.0
|
|
846
849
|
|
|
847
850
|
# issue #211
|
|
848
851
|
# (masked array handling in date2num - AttributeError:
|
|
@@ -850,7 +853,7 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
850
853
|
m = np.ma.asarray(
|
|
851
854
|
[cftime.DatetimeGregorian(2014, 8, 1, 12, 0, 0, 0)]
|
|
852
855
|
)
|
|
853
|
-
assert(
|
|
856
|
+
assert (
|
|
854
857
|
cftime.date2num(m, units="seconds since 2000-1-1")==[4.602096e+08]
|
|
855
858
|
)
|
|
856
859
|
|
|
@@ -869,11 +872,11 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
869
872
|
else:
|
|
870
873
|
raise AssertionError # fail if ValueError not raised
|
|
871
874
|
d2 = cftime.datetime(1,1,1,0,has_year_zero=has_year_zero,calendar=calendar)
|
|
872
|
-
assert(
|
|
875
|
+
assert (d2-d).days==366 # 1-1-1 is 366 days after -1-1-1 if no year zero.
|
|
873
876
|
has_year_zero=True
|
|
874
877
|
d = cftime.datetime(0,1,1,0,has_year_zero=has_year_zero,calendar=calendar)
|
|
875
878
|
d2 = cftime.datetime(1,1,1,0,has_year_zero=has_year_zero,calendar=calendar)
|
|
876
|
-
assert(
|
|
879
|
+
assert (d2-d).days==366 # 1-1-1 is 366 days after 0-1-1 if year zero allowed.
|
|
877
880
|
for has_year_zero in [True,False]:
|
|
878
881
|
if calendar == 'julian':
|
|
879
882
|
d = cftime.datetime(1858,11, 4,12,has_year_zero=has_year_zero,calendar=calendar)
|
|
@@ -890,40 +893,56 @@ class cftimeTestCase(unittest.TestCase):
|
|
|
890
893
|
else:
|
|
891
894
|
d0 = cftime.datetime(-4713, 1, 1,12,has_year_zero=has_year_zero,calendar=calendar)
|
|
892
895
|
jd = d.toordinal()
|
|
893
|
-
assert(
|
|
894
|
-
assert
|
|
895
|
-
assert
|
|
896
|
+
assert (d-d0).days == jdref
|
|
897
|
+
assert jd == jdref
|
|
898
|
+
assert d.toordinal() == jdref
|
|
896
899
|
d2 = cftime.datetime.fromordinal(jd,calendar=calendar,has_year_zero=has_year_zero)
|
|
897
|
-
assert
|
|
900
|
+
assert d2 == d
|
|
898
901
|
# issue #248. Set has_year_zero=True if year zero requested
|
|
899
902
|
# on instance creation, or by using replace method.
|
|
900
903
|
d=cftime.datetime(0, 0, 0, calendar=None)
|
|
901
|
-
assert
|
|
904
|
+
assert d.has_year_zero is True
|
|
902
905
|
d=cftime.datetime(1, 0, 0, calendar=None)
|
|
903
|
-
assert
|
|
906
|
+
assert d.has_year_zero is False
|
|
904
907
|
d = d.replace(year=0)
|
|
905
|
-
assert
|
|
908
|
+
assert d.has_year_zero is True
|
|
906
909
|
# this should raise a warning, since the default has_year_zero
|
|
907
910
|
# is changed if year specified as zero. (issue #248, PR #249)
|
|
908
911
|
self.assertWarns(UserWarning, cftime.datetime, 0, 1, 1,\
|
|
909
912
|
calendar='standard')
|
|
910
913
|
# check that for idealized calendars has_year_zero is always True
|
|
911
914
|
d=cftime.datetime(0, 1, 1, calendar='360_day')
|
|
912
|
-
assert
|
|
915
|
+
assert d.has_year_zero is True
|
|
913
916
|
d=cftime.datetime(1, 1, 1, calendar='360_day')
|
|
914
|
-
assert
|
|
917
|
+
assert d.has_year_zero is True
|
|
915
918
|
d = d.replace(year=0)
|
|
916
|
-
assert
|
|
919
|
+
assert d.has_year_zero is True
|
|
917
920
|
# test leap year function
|
|
918
|
-
assert
|
|
919
|
-
assert
|
|
920
|
-
assert
|
|
921
|
-
assert
|
|
922
|
-
assert
|
|
923
|
-
assert
|
|
921
|
+
assert cftime.is_leap_year(2000,calendar='standard')
|
|
922
|
+
assert cftime.is_leap_year(-1,calendar='standard')
|
|
923
|
+
assert cftime.is_leap_year(0,calendar='standard',has_year_zero=True)
|
|
924
|
+
assert not cftime.is_leap_year(1,calendar='standard',has_year_zero=True)
|
|
925
|
+
assert not cftime.is_leap_year(1,calendar='365_day')
|
|
926
|
+
assert cftime.is_leap_year(1,calendar='366_day')
|
|
924
927
|
# num2date should not fail on an empty int array (issue #287)
|
|
925
928
|
d = cftime.num2date(np.array([], dtype="int64"), "days since 1970-01-01",\
|
|
926
929
|
calendar="proleptic_gregorian", only_use_cftime_datetimes=True)
|
|
930
|
+
# date2num should return an empty array if given one (issue #315)
|
|
931
|
+
d = cftime.date2num([], 'seconds since 2000-01-01 12:00:00')
|
|
932
|
+
assert d.size==0
|
|
933
|
+
# issue #328: handle nan/inf in num2date.
|
|
934
|
+
times = np.array([1,2,3,np.nan],dtype=np.float64)
|
|
935
|
+
expected = np.array([DatetimeGregorian(2000, 1, 2, 0, 0, 0, 0),
|
|
936
|
+
DatetimeGregorian(2000, 1, 3, 0, 0, 0, 0),
|
|
937
|
+
DatetimeGregorian(2000, 1, 4, 0, 0, 0, 0),
|
|
938
|
+
DatetimeGregorian(2000, 1, 5, 0, 0, 0, 0)])
|
|
939
|
+
mask = [False, False, False, True]
|
|
940
|
+
expected = np.ma.masked_array(expected, mask=mask)
|
|
941
|
+
result = cftime.num2date(times, 'days since 2000-01-01', 'standard')
|
|
942
|
+
np.testing.assert_equal(result, expected)
|
|
943
|
+
times = np.array([1,2,3,np.inf],dtype=np.float64)
|
|
944
|
+
result = cftime.num2date(times, 'days since 2000-01-01', 'standard')
|
|
945
|
+
np.testing.assert_equal(result, expected)
|
|
927
946
|
|
|
928
947
|
|
|
929
948
|
class TestDate2index(unittest.TestCase):
|
|
@@ -1034,7 +1053,7 @@ class TestDate2index(unittest.TestCase):
|
|
|
1034
1053
|
nutime = self.TestTime(datetime(1950, 1, 1), 366, 24,
|
|
1035
1054
|
'hours since 1900-01-01', 'standard')
|
|
1036
1055
|
try:
|
|
1037
|
-
|
|
1056
|
+
_t = date2index(datetime(1949, 2, 1), nutime)
|
|
1038
1057
|
except ValueError:
|
|
1039
1058
|
pass
|
|
1040
1059
|
else:
|
|
@@ -1108,12 +1127,12 @@ class TestDate2index(unittest.TestCase):
|
|
|
1108
1127
|
units = 'microseconds since 1776-07-04 00:00:00-12:00'
|
|
1109
1128
|
dates = [datetime(1962, 10, 27, 6, 1, 30, 9001),
|
|
1110
1129
|
datetime(1993, 11, 21, 12, 5, 25, 999),
|
|
1111
|
-
datetime(1995, 11, 25, 18, 7, 59,
|
|
1130
|
+
datetime(1995, 11, 25, 18, 7, 59, 9999)]
|
|
1112
1131
|
times2 = date2num(dates, units)
|
|
1113
1132
|
dates2 = num2date(times2, units)
|
|
1114
1133
|
datediff = abs(dates-dates2)
|
|
1115
1134
|
for diff in datediff:
|
|
1116
|
-
assert
|
|
1135
|
+
assert diff.microseconds < 100 # tolerance of 100 ms
|
|
1117
1136
|
|
|
1118
1137
|
def test_issue444(self):
|
|
1119
1138
|
# make sure integer overflow not causing error in
|
|
@@ -1122,19 +1141,19 @@ class TestDate2index(unittest.TestCase):
|
|
|
1122
1141
|
query_time = datetime(2037, 1, 3, 21, 12)
|
|
1123
1142
|
index = date2index(query_time, self.time_vars['time3'],
|
|
1124
1143
|
select='nearest')
|
|
1125
|
-
assert
|
|
1144
|
+
assert index == 11
|
|
1126
1145
|
|
|
1127
1146
|
def test_issue272(self):
|
|
1128
1147
|
timeArray = self.issue272time
|
|
1129
1148
|
date = datetime(2020, 2, 22, 13)
|
|
1130
|
-
assert
|
|
1131
|
-
select="exact")==3
|
|
1132
|
-
assert
|
|
1133
|
-
select="before")==2
|
|
1134
|
-
assert
|
|
1135
|
-
select="after")==4
|
|
1136
|
-
assert
|
|
1137
|
-
select="nearest")==3
|
|
1149
|
+
assert date2index(date, timeArray, calendar="gregorian",
|
|
1150
|
+
select="exact")==3
|
|
1151
|
+
assert date2index(date, timeArray, calendar="gregorian",
|
|
1152
|
+
select="before")==2
|
|
1153
|
+
assert date2index(date, timeArray, calendar="gregorian",
|
|
1154
|
+
select="after")==4
|
|
1155
|
+
assert date2index(date, timeArray, calendar="gregorian",
|
|
1156
|
+
select="nearest")==3
|
|
1138
1157
|
|
|
1139
1158
|
|
|
1140
1159
|
class issue584TestCase(unittest.TestCase):
|
|
@@ -1353,7 +1372,7 @@ class DateTime(unittest.TestCase):
|
|
|
1353
1372
|
deserialized = pickle.loads(pickle.dumps(date))
|
|
1354
1373
|
self.assertEqual(date, deserialized)
|
|
1355
1374
|
self.assertEqual(type(date), type(deserialized))
|
|
1356
|
-
|
|
1375
|
+
|
|
1357
1376
|
def test_misc(self):
|
|
1358
1377
|
"Miscellaneous tests."
|
|
1359
1378
|
# make sure repr succeeds
|
|
@@ -1511,7 +1530,7 @@ def days_per_month_leap_year(date_type, month):
|
|
|
1511
1530
|
|
|
1512
1531
|
|
|
1513
1532
|
def test_zero_year(date_type):
|
|
1514
|
-
# Year 0 is valid in the 360,365 and 366 day and
|
|
1533
|
+
# Year 0 is valid in the 360,365 and 366 day and
|
|
1515
1534
|
# Proleptic Gregorian calendars by default.
|
|
1516
1535
|
with warnings.catch_warnings():
|
|
1517
1536
|
warnings.simplefilter("ignore",category=cftime.CFWarning)
|
|
@@ -1520,7 +1539,7 @@ def test_zero_year(date_type):
|
|
|
1520
1539
|
date_type(0, 1, 1)
|
|
1521
1540
|
else:
|
|
1522
1541
|
d=date_type(0,1,1) # has_year_zero=True set if year 0 specified
|
|
1523
|
-
assert
|
|
1542
|
+
assert d.has_year_zero # (issue #248)
|
|
1524
1543
|
with pytest.raises(ValueError):
|
|
1525
1544
|
date_type(0, 1, 1, has_year_zero=False)
|
|
1526
1545
|
|
|
@@ -1707,19 +1726,21 @@ def test_string_format2():
|
|
|
1707
1726
|
|
|
1708
1727
|
def test_strptime():
|
|
1709
1728
|
d = cftime.datetime.strptime('24/Aug/2004:17:57:26 +0200', '%d/%b/%Y:%H:%M:%S %z',calendar='julian',has_year_zero=True)
|
|
1710
|
-
assert
|
|
1729
|
+
assert repr(d) == "cftime.datetime(2004, 8, 24, 15, 57, 26, 0, calendar='julian', has_year_zero=True)"
|
|
1711
1730
|
d = cftime.datetime.strptime("0000-02-30",\
|
|
1712
1731
|
"%Y-%m-%d",calendar='360_day',has_year_zero=True)
|
|
1713
|
-
assert
|
|
1714
|
-
d = cftime.datetime.strptime('-
|
|
1732
|
+
assert repr(d) == "cftime.datetime(0, 2, 30, 0, 0, 0, 0, calendar='360_day', has_year_zero=True)"
|
|
1733
|
+
d = cftime.datetime.strptime('-9999-02-29 10:18:32.926',\
|
|
1715
1734
|
'%Y-%m-%d %H:%M:%S.%f',calendar='366_day')
|
|
1716
|
-
assert
|
|
1735
|
+
assert repr(d) == "cftime.datetime(-9999, 2, 29, 10, 18, 32, 926000, calendar='all_leap', has_year_zero=True)"
|
|
1736
|
+
d = cftime.datetime.strptime("20200230", "%Y%m%d", "360_day") # no separator, issue #301
|
|
1737
|
+
assert repr(d) == "cftime.datetime(2020, 2, 30, 0, 0, 0, 0, calendar='360_day', has_year_zero=True)"
|
|
1717
1738
|
d = cftime.datetime.strptime('24/Aug/-4712:17:57:26', '%d/%b/%Y:%H:%M:%S',calendar='julian')
|
|
1718
|
-
assert
|
|
1739
|
+
assert repr(d) == "cftime.datetime(-4712, 8, 24, 17, 57, 26, 0, calendar='julian', has_year_zero=False)"
|
|
1719
1740
|
d = cftime.datetime.strptime('24/August/-4712:17:57:26', '%d/%B/%Y:%H:%M:%S',calendar='julian')
|
|
1720
|
-
assert
|
|
1741
|
+
assert repr(d) == "cftime.datetime(-4712, 8, 24, 17, 57, 26, 0, calendar='julian', has_year_zero=False)"
|
|
1721
1742
|
d = cftime.datetime.strptime("-4712", "%Y", calendar="julian")
|
|
1722
|
-
assert
|
|
1743
|
+
assert repr(d) == "cftime.datetime(-4712, 1, 1, 0, 0, 0, 0, calendar='julian', has_year_zero=False)"
|
|
1723
1744
|
# should fail with KeyError
|
|
1724
1745
|
try:
|
|
1725
1746
|
d=cftime.datetime.strptime("2000-45-3", "%G-%V-%u", calendar="noleap")
|
|
@@ -2070,19 +2091,19 @@ def test_num2date_integer_upcast_required():
|
|
|
2070
2091
|
|
|
2071
2092
|
|
|
2072
2093
|
@pytest.mark.parametrize(
|
|
2073
|
-
"encoding_units",
|
|
2094
|
+
"encoding_units",
|
|
2074
2095
|
["microseconds", "milliseconds", "seconds", "minutes", "hours", "days"]
|
|
2075
2096
|
)
|
|
2076
2097
|
@pytest.mark.parametrize(
|
|
2077
2098
|
"freq",
|
|
2078
2099
|
[
|
|
2079
2100
|
timedelta(microseconds=1),
|
|
2080
|
-
timedelta(microseconds=1000),
|
|
2081
|
-
timedelta(seconds=1),
|
|
2082
|
-
timedelta(minutes=1),
|
|
2083
|
-
timedelta(hours=1),
|
|
2101
|
+
timedelta(microseconds=1000),
|
|
2102
|
+
timedelta(seconds=1),
|
|
2103
|
+
timedelta(minutes=1),
|
|
2104
|
+
timedelta(hours=1),
|
|
2084
2105
|
timedelta(days=1)
|
|
2085
|
-
],
|
|
2106
|
+
],
|
|
2086
2107
|
ids=lambda x: f"{x!r}"
|
|
2087
2108
|
)
|
|
2088
2109
|
def test_date2num_num2date_roundtrip(encoding_units, freq, calendar):
|
|
@@ -2090,8 +2111,8 @@ def test_date2num_num2date_roundtrip(encoding_units, freq, calendar):
|
|
|
2090
2111
|
lengthy_timedelta = timedelta(days=291000 * 360)
|
|
2091
2112
|
times = np.array(
|
|
2092
2113
|
[
|
|
2093
|
-
date_type(1, 1, 1),
|
|
2094
|
-
date_type(1, 1, 1) + lengthy_timedelta,
|
|
2114
|
+
date_type(1, 1, 1),
|
|
2115
|
+
date_type(1, 1, 1) + lengthy_timedelta,
|
|
2095
2116
|
date_type(1, 1, 1) + lengthy_timedelta + freq
|
|
2096
2117
|
]
|
|
2097
2118
|
)
|
|
@@ -2138,7 +2159,7 @@ def test_date2num_missing_data():
|
|
|
2138
2159
|
|
|
2139
2160
|
def test_num2date_preserves_shape():
|
|
2140
2161
|
# The optimized num2date algorithm operates on a flattened array. This
|
|
2141
|
-
# check ensures that the original shape of the times is restored in the
|
|
2162
|
+
# check ensures that the original shape of the times is restored in the
|
|
2142
2163
|
# result.
|
|
2143
2164
|
a = np.array([[0, 1, 2], [3, 4, 5]])
|
|
2144
2165
|
result = num2date(a, units="days since 2000-01-01", calendar="standard")
|
|
@@ -2183,8 +2204,8 @@ def test_date2num_unrecognized_units(units, match):
|
|
|
2183
2204
|
|
|
2184
2205
|
|
|
2185
2206
|
def test_num2date_precision():
|
|
2186
|
-
if
|
|
2187
|
-
pytest.skip("skipping tests that require
|
|
2207
|
+
if np.finfo(np.longdouble).precision < 18:
|
|
2208
|
+
pytest.skip("skipping tests that require extended precision longdouble type")
|
|
2188
2209
|
testdates = [(1271, 3, 18, 19, 41, 33),
|
|
2189
2210
|
(1271, 3, 18, 19, 41, 32, 999998)]
|
|
2190
2211
|
unitinc = ['microseconds', 'seconds', 'minutes', 'hours', 'days']
|
cftime-1.6.2/pyproject.toml
DELETED
cftime-1.6.2/requirements.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
numpy>1.13.3
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
numpy>1.13.3
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|