5151)
5252from neo4j .time .arithmetic import (
5353 nano_add ,
54- nano_sub ,
55- nano_mul ,
5654 nano_div ,
57- nano_mod ,
58- nano_divmod ,
5955 symmetric_divmod ,
6056 round_half_to_even ,
6157)
@@ -334,18 +330,16 @@ class Duration(tuple):
334330 max = None
335331
336332 def __new__ (cls , years = 0 , months = 0 , weeks = 0 , days = 0 , hours = 0 , minutes = 0 ,
337- seconds = 0 , milliseconds = 0 , microseconds = 0 , nanoseconds = 0 ,
338- subseconds = 0 ):
333+ seconds = 0 , subseconds = 0 , milliseconds = 0 , microseconds = 0 ,
334+ nanoseconds = 0 ):
339335
340- if subseconds and nanoseconds :
341- raise ValueError ("Specify either subseconds or nanoseconds" )
342336 if subseconds :
343- deprecation_warn ("subseconds will be removed in 5.0."
337+ deprecation_warn ("` subseconds` will be removed in 5.0. "
344338 "Use `nanoseconds` instead." )
345339 with _decimal_context (prec = 9 , rounding = ROUND_HALF_EVEN ):
346340 nanoseconds = int (Decimal (subseconds ) * NANO_SECONDS )
347341
348- mo = round_half_to_even (12 * years + months )
342+ mo = int (12 * years + months )
349343 if mo < MIN_INT64 or mo > MAX_INT64 :
350344 raise ValueError ("Months value out of range" )
351345 d = int (7 * weeks + days )
@@ -360,26 +354,22 @@ def __new__(cls, years=0, months=0, weeks=0, days=0, hours=0, minutes=0,
360354 raise ValueError ("Days value out of range" )
361355 if s < MIN_INT64 or s > MAX_INT64 :
362356 raise ValueError ("Seconds value out of range" )
363- if ns < MIN_INT64 or s > MAX_INT64 :
364- raise ValueError ("Nanoseconds value out of range" )
357+ if s < MIN_INT64 or s > MAX_INT64 :
358+ raise ValueError ("Seconds value out of range" )
365359 return tuple .__new__ (cls , (mo , d , s , ns ))
366360
367361 def __bool__ (self ):
368362 return any (map (bool , self ))
369363
370364 __nonzero__ = __bool__
371365
372- def _check_composite (self ):
373- if sum ((self [0 ], self [1 ], self [2 ] or self [3 ])) > 1 :
374- deprecation_warn (
375- "Dividing composite durations will cause an error in 5.0"
376- )
377-
378366 def __add__ (self , other ):
379367 if isinstance (other , Duration ):
380368 return Duration (
381- months = self [0 ] + other [0 ], days = self [1 ] + other [1 ],
382- seconds = self [2 ] + other [2 ], nanoseconds = self [3 ] + other [3 ]
369+ months = self [0 ] + int (other .months ),
370+ days = self [1 ] + int (other .days ),
371+ seconds = self [2 ] + int (other .seconds ),
372+ nanoseconds = self [3 ] + int (other .nanoseconds )
383373 )
384374 if isinstance (other , timedelta ):
385375 return Duration (
@@ -392,30 +382,35 @@ def __add__(self, other):
392382 def __sub__ (self , other ):
393383 if isinstance (other , Duration ):
394384 return Duration (
395- months = self [0 ] - other [0 ], days = self [1 ] - other [1 ],
396- seconds = self [2 ] - other [2 ],
397- nanoseconds = self [3 ] - other [3 ]
385+ months = self [0 ] - int (other .months ),
386+ days = self [1 ] - int (other .days ),
387+ seconds = self [2 ] - int (other .seconds ),
388+ nanoseconds = self [3 ] - int (other .nanoseconds )
398389 )
399390 if isinstance (other , timedelta ):
400391 return Duration (
401- months = self [0 ], days = self [1 ] - other .days ,
392+ months = self [0 ],
393+ days = self [1 ] - other .days ,
402394 seconds = self [2 ] - other .seconds ,
403395 nanoseconds = self [3 ] - other .microseconds * 1000
404396 )
405397 return NotImplemented
406398
407399 def __mul__ (self , other ):
400+ if isinstance (other , float ):
401+ deprecation_warn ("Multiplication with float will be deprecated in "
402+ "5.0." )
408403 if isinstance (other , (int , float )):
409404 return Duration (
410405 months = self [0 ] * other , days = self [1 ] * other ,
411406 seconds = self [2 ] * other , nanoseconds = self [3 ] * other
412407 )
413408 return NotImplemented
414409
410+ @deprecated ("Will be removed in 5.0." )
415411 def __floordiv__ (self , other ):
416- self ._check_composite ()
417412 if isinstance (other , int ):
418- # TODO 5.0: new method (floor months, days, nanoseconds)
413+ # TODO 5.0: new method (floor months, days, nanoseconds) or remove
419414 # return Duration(
420415 # months=self[0] // other, days=self[1] // other,
421416 # nanoseconds=(self[2] * NANO_SECONDS + self[3]) // other
@@ -426,10 +421,10 @@ def __floordiv__(self, other):
426421 seconds = int (seconds // other ))
427422 return NotImplemented
428423
424+ @deprecated ("Will be removed in 5.0." )
429425 def __mod__ (self , other ):
430- self ._check_composite ()
431426 if isinstance (other , int ):
432- # TODO 5.0: new method (mod months, days, nanoseconds)
427+ # TODO 5.0: new method (mod months, days, nanoseconds) or remove
433428 # return Duration(
434429 # months=self[0] % other, days=self[1] % other,
435430 # nanoseconds=(self[2] * NANO_SECONDS + self[3]) % other
@@ -441,13 +436,14 @@ def __mod__(self, other):
441436 seconds = seconds , subseconds = subseconds )
442437 return NotImplemented
443438
439+ @deprecated ("Will be removed in 5.0." )
444440 def __divmod__ (self , other ):
445441 if isinstance (other , int ):
446442 return self .__floordiv__ (other ), self .__mod__ (other )
447443 return NotImplemented
448444
445+ @deprecated ("Will be removed in 5.0." )
449446 def __truediv__ (self , other ):
450- self ._check_composite ()
451447 if isinstance (other , (int , float )):
452448 return Duration (
453449 months = round_half_to_even (self [0 ] / other ),
@@ -1141,9 +1137,10 @@ def from_iso_format(cls, s):
11411137 @classmethod
11421138 def from_ticks (cls , ticks , tz = None ):
11431139 if 0 <= ticks < 86400 :
1144- minute , second = nano_divmod (ticks , 60 )
1145- hour , minute = divmod (minute , 60 )
1146- return cls .__new (ticks , hour , minute , second , tz )
1140+ ticks = Decimal (ticks ) * NANO_SECONDS
1141+ ticks = int (ticks .quantize (Decimal ("1." ), rounding = ROUND_HALF_EVEN ))
1142+ assert 0 <= ticks < 86400000000000
1143+ return cls .from_ticks_ns (ticks , tz = tz )
11471144 raise ValueError ("Ticks out of range (0..86400)" )
11481145
11491146 @classmethod
@@ -1249,7 +1246,7 @@ def ticks(self):
12491246 def ticks_ns (self ):
12501247 """ Return the total number of seconds since midnight.
12511248 """
1252- # TODO 5.0: this will replace self.__ticks
1249+ # TODO 5.0: this will replace self.ticks
12531250 return self .__ticks
12541251
12551252 @property
@@ -1408,9 +1405,9 @@ def to_native(self):
14081405 """ Convert to a native Python `datetime.time` value.
14091406 """
14101407 h , m , s , ns = self .hour_minute_second_nanoseconds
1411- mic_s = round_half_to_even (ns / 1000 )
1408+ µs = round_half_to_even (ns / 1000 )
14121409 tz = self .tzinfo
1413- return time (h , m , s , mic_s , tz )
1410+ return time (h , m , s , µs , tz )
14141411
14151412 def iso_format (self ):
14161413 s = "%02d:%02d:%02d.%09d" % self .hour_minute_second_nanoseconds
@@ -1568,8 +1565,8 @@ def from_clock_time(cls, clock_time, epoch):
15681565 else :
15691566 ordinal , seconds = divmod (seconds , 86400 )
15701567 ticks = epoch .time ().ticks_ns + seconds * NANO_SECONDS + nanoseconds
1571- ticks_overflow , ticks = divmod (ticks , 86400 * NANO_SECONDS )
1572- ordinal += ticks_overflow
1568+ days , ticks = divmod (ticks , 86400 * NANO_SECONDS )
1569+ ordinal += days
15731570 date_ = Date .from_ordinal (ordinal + epoch .date ().to_ordinal ())
15741571 time_ = Time .from_ticks_ns (ticks )
15751572 return cls .combine (date_ , time_ )
0 commit comments