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.
@@ -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.2
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.7
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.
@@ -0,0 +1,9 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools>=41.2",
4
+ "cython>=0.29.20",
5
+ "wheel",
6
+ "oldest-supported-numpy ; python_version < '3.9'",
7
+ "numpy>=2.0.0rc1,<3 ; python_version >= '3.9'",
8
+ ]
9
+ build-backend = "setuptools.build_meta"
@@ -1,7 +1,7 @@
1
1
  check-manifest
2
2
  coverage
3
3
  coveralls
4
- cython>0.26.1
4
+ cython>=0.29.20
5
5
  pytest
6
6
  pytest-cov
7
7
  sphinx
@@ -0,0 +1,2 @@
1
+ numpy>1.13.3; python_version<'3.12.0.rc1'
2
+ numpy>=1.26.0b1; python_version>='3.12.0.rc1'
@@ -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 = {'linetrace': True,
78
- 'warn.maybe_uninitialized': False,
79
- 'warn.unreachable': False,
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.7",
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.2'
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
- isscalar = True
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 using the same calendar.
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
- # 'Y': r"(?P<Y>\d\d\d\d)",
34
- 'Y': r"(?P<Y>[+-]?[0-9]+)", # handle neg and > 4 digits
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.2
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.7
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.
@@ -0,0 +1,6 @@
1
+
2
+ [:python_version < "3.12.0.rc1"]
3
+ numpy>1.13.3
4
+
5
+ [:python_version >= "3.12.0.rc1"]
6
+ numpy>=1.26.0b1
@@ -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(abs(t2 - t) < 1e-5) # values should be less than second
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(d1 == d2)
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(self.cdftime_mixed_tz.date2num(
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(1.0 == date2num(num2date(1.0, units), units))
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(np.all(err<eps))
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(dates1==dates2)
420
+ assert dates1==dates2
423
421
  return err.max()
424
422
  for calendar in calendars:
425
- eps = 1.; delta = 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; delta = 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; delta = 0.1
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; delta = 0.01
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; delta = 0.001
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; delta = 0.00001
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 (num2date(0, 'hours since 2000-01-01 0') ==
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( dates1.shape == (2,2) )
472
- assert( dates2.shape == (2,2) )
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( num1b.shape == (2,2) )
476
- assert( num2b.shape == (2,2) )
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 (num == -7)
488
- assert (num2date(num, units) == date)
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(np.abs((d-utc_date).total_seconds()) < 1.e-3)
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(d==datetime(1,1,1,0))
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(np.abs((d-utc_date).total_seconds()) < 1.e-3)
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(np.abs((d - \
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(cftime.date2num(cftime.datetime(1, 12, 1, 0, 0, 0, 0, -1, 1), units='days since 01-01-01',calendar='noleap') == 334.0)
726
- 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)
727
- assert(cftime.date2num(cftime.DatetimeNoLeap(1980, 1, 1, 0, 0, 0, 0, 6, 1),'days since 1970-01-01','noleap') == 3650.0)
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(cftime.date2num(d, 'days since 0001-01-01',\
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(float(cftime.date2num(d, units)) == -271.99)
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(dates1 == dates2)
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(str(d)[0:24] == '2009-12-22 00:00:00.0156')
753
+ assert str(d)[0:24] == '2009-12-22 00:00:00.0156'
751
754
  # issue #152 add isoformat()
752
- assert(d.isoformat()[0:24] == '2009-12-22T00:00:00.0156')
753
- assert(d.isoformat(sep=' ')[0:24] == '2009-12-22 00:00:00.0156')
754
- assert(d.isoformat(sep=' ',timespec='milliseconds') == '2009-12-22 00:00:00.016')
755
- assert(d.isoformat(sep=' ',timespec='seconds') == '2009-12-22 00:00:00')
756
- assert(d.isoformat(sep=' ',timespec='minutes') == '2009-12-22 00:00')
757
- assert(d.isoformat(sep=' ',timespec='hours') == '2009-12-22 00')
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(c.strftime() == '7480-01-01 00:00:00')
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(test.all())
774
+ assert test.all()
772
775
  dates = num2date(times, units=units, calendar='standard')
773
- assert(str(dates)=="[cftime.DatetimeGregorian(1848, 1, 17, 6, 0, 0, 40, has_year_zero=False)\n --]")
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(date == refdate)
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(date2 == refdate)
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(date == refdate)
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(date2 == refdate)
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(dt1 == dt2)
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(dt1 == dt2)
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(str(dt) == '2020-01-01 01:00:00')
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(cftime.date2num(cftime.datetime(18000, 12, 1, 0, 0), 'days since 18000-1-1', '360_day') == 330.0)
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(jd == 2459198.0)
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(jd == 2459198.0)
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(jd == 2459198.0)
845
+ assert jd == 2459198.0
843
846
  # use 'standard' calendar
844
847
  jd = cftime.date2num(d,units,calendar='standard')
845
- assert(jd == 2459185.0)
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((d2-d).days==366) # 1-1-1 is 366 days after -1-1-1 if no year zero.
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((d2-d).days==366) # 1-1-1 is 366 days after 0-1-1 if year zero allowed.
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((d-d0).days == jdref)
894
- assert(jd == jdref)
895
- assert(d.toordinal() == jdref)
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(d2 == d)
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(d.has_year_zero==True)
904
+ assert d.has_year_zero is True
902
905
  d=cftime.datetime(1, 0, 0, calendar=None)
903
- assert(d.has_year_zero==False)
906
+ assert d.has_year_zero is False
904
907
  d = d.replace(year=0)
905
- assert(d.has_year_zero==True)
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(d.has_year_zero==True)
915
+ assert d.has_year_zero is True
913
916
  d=cftime.datetime(1, 1, 1, calendar='360_day')
914
- assert(d.has_year_zero==True)
917
+ assert d.has_year_zero is True
915
918
  d = d.replace(year=0)
916
- assert(d.has_year_zero==True)
919
+ assert d.has_year_zero is True
917
920
  # test leap year function
918
- assert(cftime.is_leap_year(2000,calendar='standard'))
919
- assert(cftime.is_leap_year(-1,calendar='standard'))
920
- assert(cftime.is_leap_year(0,calendar='standard',has_year_zero=True))
921
- assert(not cftime.is_leap_year(1,calendar='standard',has_year_zero=True))
922
- assert(not cftime.is_leap_year(1,calendar='365_day'))
923
- assert(cftime.is_leap_year(1,calendar='366_day'))
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
- t = date2index(datetime(1949, 2, 1), nutime)
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, 999999)]
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(diff.microseconds < 100) # tolerance of 100 ms
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(index == 11)
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(date2index(date, timeArray, calendar="gregorian",
1131
- select="exact")==3)
1132
- assert(date2index(date, timeArray, calendar="gregorian",
1133
- select="before")==2)
1134
- assert(date2index(date, timeArray, calendar="gregorian",
1135
- select="after")==4)
1136
- assert(date2index(date, timeArray, calendar="gregorian",
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(d.has_year_zero) # (issue #248)
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(repr(d) == "cftime.datetime(2004, 8, 24, 15, 57, 26, 0, calendar='julian', has_year_zero=True)")
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(repr(d) == "cftime.datetime(0, 2, 30, 0, 0, 0, 0, calendar='360_day', has_year_zero=True)")
1714
- d = cftime.datetime.strptime('-99999-02-29 10:18:32.926',\
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(repr(d) == "cftime.datetime(-99999, 2, 29, 10, 18, 32, 926000, calendar='all_leap', has_year_zero=True)")
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(repr(d) == "cftime.datetime(-4712, 8, 24, 17, 57, 26, 0, calendar='julian', has_year_zero=False)")
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(repr(d) == "cftime.datetime(-4712, 8, 24, 17, 57, 26, 0, calendar='julian', has_year_zero=False)")
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(repr(d) == "cftime.datetime(-4712, 1, 1, 0, 0, 0, 0, calendar='julian', has_year_zero=False)")
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 sys.platform.startswith("win"):
2187
- pytest.skip("skipping tests that require float128 on windows")
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']
@@ -1,3 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools>=41.2", "cython", "wheel", "oldest-supported-numpy"]
3
- build-backend = "setuptools.build_meta"
@@ -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