[Git][debian-gis-team/cftime][master] 5 commits: New upstream version 1.2.1+ds
Bas Couwenberg
gitlab at salsa.debian.org
Mon Jul 20 05:08:18 BST 2020
Bas Couwenberg pushed to branch master at Debian GIS Project / cftime
Commits:
e4ec2aaa by Bas Couwenberg at 2020-07-20T05:44:30+02:00
New upstream version 1.2.1+ds
- - - - -
eb85d398 by Bas Couwenberg at 2020-07-20T05:44:31+02:00
Update upstream source from tag 'upstream/1.2.1+ds'
Update to upstream version '1.2.1+ds'
with Debian dir 2e7e8df4c77ca66dec77a2afadf6089ccb07377a
- - - - -
8d15f065 by Bas Couwenberg at 2020-07-20T05:44:58+02:00
New upstream release.
- - - - -
acbce2ed by Bas Couwenberg at 2020-07-20T05:57:48+02:00
Add lintian override for file-references-package-build-path.
- - - - -
12142da3 by Bas Couwenberg at 2020-07-20T05:57:48+02:00
Set distribution to unstable.
- - - - -
6 changed files:
- Changelog
- README.md
- cftime/_cftime.pyx
- debian/changelog
- + debian/lintian-overrides
- test/test_cftime.py
Changes:
=====================================
Changelog
=====================================
@@ -1,3 +1,13 @@
+version 1.2.1 (not yet released)
+=================================
+ * num2date uses 'proleptic_gregorian' scheme when basedate is post-Gregorian but date is pre-Gregorian
+ (issue #182).
+ * fix 1.2.0 regression (date2num no longer works with numpy scalar array inputs, issue #185).
+ * Fix for issue #187 (have date2num round to the nearest second when within 1
+ microsecond).
+ * Fix for issue #189 (leap years calculated incorrectly for negative years in
+ proleptic_gregorian calendar).
+
version 1.2.0 (release tag v1.2.0rel)
=====================================
* Return the default values of dayofwk and dayofyr when calendar
@@ -24,7 +34,7 @@ version 1.1.2 (release tag v1.1.2rel)
=====================================
* change dayofwk and dayofyr attributes into properties (issue #158)
* fix for issue #165 (python datetime should be returned when
- only_use_cftime_datimes=False).
+ only_use_cftime_datetimes=False).
version 1.1.1.2 (release tag v1.1.1.2rel)
=========================================
=====================================
README.md
=====================================
@@ -12,12 +12,14 @@ Time-handling functionality from netcdf4-python
## News
For details on the latest updates, see the [Changelog](https://github.com/Unidata/cftime/blob/master/Changelog).
-7/06/2020: version 1.2.0 released. New microsecond accurate algorithm for date2num/num2date contributed by @spencerkclark. Bugs fixed in masked array handling.
+07/20/2020: Version 1.2.1 released. Fixes a couple of regressions introduced in 1.2.0. See Changelog for details.
+
+7/06/2020: version 1.2.0 released. New microsecond accurate algorithm for date2num/num2date contributed by [spencerkclark](https://github.com/spencerkclark). Bugs fixed in masked array handling.
5/12/2020: version 1.1.3 released. Add isoformat method for compatibility with python datetime (issue #152).
Make 'standard' default calendar for cftime.datetime so that dayofwk,dayofyr methods don't fail (issue #169).
-4/20/2020: version 1.1.2 released. Code optimization, fix logic so `only_use_cftime_datimes=False` works as
+4/20/2020: version 1.1.2 released. Code optimization, fix logic so `only_use_cftime_datetimes=False` works as
expected (issues [#158](https://github.com/Unidata/cftime/issues/158) and [#165](https://github.com/Unidata/cftime/issues/165)).
3/16/2020: version 1.1.1 released. Fix bug in microsecond formatting, ensure identical num2date results if input is an array of times, or a single scalar ([issue #143](https://github.com/Unidata/cftime/issues/143)).
=====================================
cftime/_cftime.pyx
=====================================
@@ -53,7 +53,7 @@ cdef int32_t* days_per_month_array = [
_rop_lookup = {Py_LT: '__gt__', Py_LE: '__ge__', Py_EQ: '__eq__',
Py_GT: '__lt__', Py_GE: '__le__', Py_NE: '__ne__'}
-__version__ = '1.2.0'
+__version__ = '1.2.1'
# Adapted from http://delete.me.uk/2005/03/iso8601.html
# 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.
@@ -166,7 +166,7 @@ def _dateparse(timestr,calendar):
def _can_use_python_datetime(date,calendar):
return ((calendar == 'proleptic_gregorian' and date.year >= MINYEAR and date.year <= MAXYEAR) or \
- (calendar in ['gregorian','standard'] and date > gregorian))
+ (calendar in ['gregorian','standard'] and date > gregorian and date.year <= MAXYEAR))
@cython.embedsignature(True)
def date2num(dates,units,calendar='standard'):
@@ -209,7 +209,7 @@ def date2num(dates,units,calendar='standard'):
if unit in ["months", "month"] and calendar != "360_day":
raise ValueError("Units of months only valid for 360_day calendar.")
factor = UNIT_CONVERSION_FACTORS[unit]
- use_python_datetime = _can_use_python_datetime(basedate,calendar)
+ can_use_python_basedatetime = _can_use_python_datetime(basedate,calendar)
isscalar = False
try:
@@ -220,28 +220,33 @@ def date2num(dates,units,calendar='standard'):
if np.ma.isMA(dates) and np.ma.is_masked(dates):
mask = dates.mask
ismasked = True
- if isscalar:
- dates = np.array([dates])
+ dates = np.asanyarray(dates)
+ shape = dates.shape
+ # are all dates python datetime instances?
+ all_python_datetimes = True
+ for date in dates.flat:
+ if not isinstance(date,datetime_python):
+ all_python_datetimes = False
+ break
+ if can_use_python_basedatetime and all_python_datetimes:
+ use_python_datetime = True
+ if not isinstance(basedate, datetime_python):
+ basedate = real_datetime(basedate.year, basedate.month, basedate.day,
+ basedate.hour, basedate.minute, basedate.second,
+ basedate.microsecond)
else:
- dates = np.array(dates)
- shape = dates.shape
+ use_python_datetime = False
+ # convert basedate to specified calendar
+ if not isinstance(basedate, DATE_TYPES[calendar]):
+ basedate = to_calendar_specific_datetime(basedate, calendar, False)
times = []; n = 0
for date in dates.flat:
# use python datetime if possible.
- if use_python_datetime and date.year >= MINYEAR and date.year <= MAXYEAR:
- if not isinstance(basedate, datetime_python):
- basedate = real_datetime(basedate.year, basedate.month, basedate.day,
- basedate.hour, basedate.minute, basedate.second,
- basedate.microsecond)
- if not isinstance(date, datetime_python):
- date = real_datetime(date.year, date.month, date.day, date.hour,
- date.minute, date.second, date.microsecond)
- # adjust for time zone offset
+ if use_python_datetime:
+ # remove time zone offset
if getattr(date, 'tzinfo',None) is not None:
date = date.replace(tzinfo=None) - date.utcoffset()
- else: # convert basedate and date to same calendar specific cftime.datetime instance
- if not isinstance(basedate, DATE_TYPES[calendar]):
- basedate = to_calendar_specific_datetime(basedate, calendar, False)
+ else: # convert date to same calendar specific cftime.datetime instance
if not isinstance(date, DATE_TYPES[calendar]):
date = to_calendar_specific_datetime(date, calendar, False)
if ismasked and mask.flat[n]:
@@ -348,7 +353,7 @@ _MAX_INT64 = np.iinfo("int64").max
_MIN_INT64 = np.iinfo("int64").min
-def cast_to_int(num):
+def cast_to_int(num, units=None):
if num.dtype.kind in "iu":
return num
else:
@@ -356,8 +361,20 @@ def cast_to_int(num):
raise OverflowError('time values outside range of 64 bit signed integers')
if isinstance(num, np.ma.core.MaskedArray):
int_num = np.ma.masked_array(np.rint(num), dtype=np.int64)
+ # use ceil instead of rint if 1 microsec less than a second
+ # or floor if 1 microsec greater than a second (issue #187)
+ if units not in microsec_units and units not in millisec_units:
+ int_num = np.ma.where(int_num%1000000 == 1, \
+ np.ma.masked_array(np.floor(num),dtype=np.int64), int_num)
+ int_num = np.ma.where(int_num%1000000 == 999999, \
+ np.ma.masked_array(np.ceil(num),dtype=np.int64), int_num)
else:
int_num = np.array(np.rint(num), dtype=np.int64)
+ if units not in microsec_units and units not in millisec_units:
+ int_num = np.where(int_num%1000000 == 1, \
+ np.array(np.floor(num),dtype=np.int64), int_num)
+ int_num = np.where(int_num%1000000 == 999999, \
+ np.array(np.ceil(num),dtype=np.int64), int_num)
return int_num
@@ -478,7 +495,7 @@ def num2date(
times = np.asanyarray(times) # Allow list as input
times = upcast_times(times)
scaled_times = scale_times(times, factor)
- scaled_times = cast_to_int(scaled_times)
+ scaled_times = cast_to_int(scaled_times,units=unit)
# Through np.timedelta64, convert integers scaled to have units of
# microseconds to datetime.timedelta objects, the timedelta type compatible
@@ -1489,9 +1506,9 @@ cdef _is_leap(int year, calendar):
if calendar == 'proleptic_gregorian' or (calendar == 'standard' and year > 1581):
if tyear % 4: # not divisible by 4
leap = False
- elif year % 100: # not divisible by 100
+ elif tyear % 100: # not divisible by 100
leap = True
- elif year % 400: # not divisible by 400
+ elif tyear % 400: # not divisible by 400
leap = False
else:
leap = True
=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+cftime (1.2.1+ds-1) unstable; urgency=medium
+
+ * New upstream release.
+ * Add lintian override for file-references-package-build-path.
+
+ -- Bas Couwenberg <sebastic at debian.org> Mon, 20 Jul 2020 05:45:21 +0200
+
cftime (1.2.0+ds-1) unstable; urgency=medium
* New upstream release.
=====================================
debian/lintian-overrides
=====================================
@@ -0,0 +1,3 @@
+# Cannot easily be fixed
+file-references-package-build-path *
+
=====================================
test/test_cftime.py
=====================================
@@ -805,6 +805,21 @@ class cftimeTestCase(unittest.TestCase):
time2 = date2num(date,units,calendar=calendar)
date2 = num2date(time2,units,calendar=calendar)
assert(date2 == refdate)
+# issue #185: date2num should work the numpy scalar array of dates (1.2.0 regression)
+ dates = np.array(datetime(2010, 2, 2, 0, 0))
+ assert (date2num(dates, units="hours since 2010-02-01 00:00:00") == 24.)
+# issue #187 - roundtrip near second boundary
+ dt1 = datetime(1810, 4, 24, 16, 15, 10)
+ units = 'days since -4713-01-01 12:00'
+ dt2 = num2date(date2num(dt1, units), units)
+ assert(dt1 == dt2)
+# issue #189 - leap years calculated incorrectly for negative years in proleptic_gregorian calendar
+ dt1 = datetime(2020, 4, 24, 16, 15, 10)
+ units = 'days since -4713-01-01 12:00'
+ cal = 'proleptic_gregorian'
+ dt2 = num2date(date2num(dt1, units, cal), units, cal)
+ assert(dt1 == dt2)
+
class TestDate2index(unittest.TestCase):
View it on GitLab: https://salsa.debian.org/debian-gis-team/cftime/-/compare/af94d147a341e9903b3ecad005458f030088ceb9...12142da34ffac2051a0428af26c75fed9062d9d8
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/cftime/-/compare/af94d147a341e9903b3ecad005458f030088ceb9...12142da34ffac2051a0428af26c75fed9062d9d8
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20200720/ca91c57a/attachment-0001.html>
More information about the Pkg-grass-devel
mailing list