Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python difference in datetime now against datetime now

I have got into an issue or might quite possibly feature in turn! Not sure, wondering!! In python's datetime library, to get difference in time, as in below snippet.

>>> import datetime
>>> datetime.datetime.now() - datetime.datetime.now()
datetime.timedelta(-1, 86399, 999958)
>>> tnow = datetime.datetime.now()
>>> datetime.datetime.now() - tnow
datetime.timedelta(0, 4, 327859)

I would like to understand why datetime.datetime.now() - datetime.datetime.now() is producing output as -1 days, 86399 seconds whereas assigning current time to some variable and computing difference gives desired output 0 days, 4 seconds.

The results seems to be bit confusing, it would be helpful if someone could decode whats going behind

Note: I'm using Python 2.7

like image 933
Vivek Harikrishnan Avatar asked Feb 20 '18 10:02

Vivek Harikrishnan


People also ask

What is the difference between now and today in Python?

datetime. now(tz=None) Return the current local date and time. datetime. today() Return the current local datetime, with tzinfo None.

How do you find the difference between two timestamps in Python?

To get the difference between two-time, subtract time1 from time2. A result is a timedelta object. The timedelta represents a duration which is the difference between two-time to the microsecond resolution. To get a time difference in seconds, use the timedelta.

What is datetime datetime now () in Python?

datetime. now() method contains the year, month, day, hour, minute, second, and microsecond (expressed as YYYY-MM-DD hh:mm:ss. ffffff ). It also accepts an optional time_zone parameter, which is set to None by default.

How do I compare two datetime values in Python?

You can use equal to comparison operator = to check if one datetime object is has same value as other.


2 Answers

As per the documentation of timedelta object

If the normalized value of days lies outside the indicated range, OverflowError is raised.

Note that normalization of negative values may be surprising at first. For example:

>>> from datetime import timedelta
>>> d = timedelta(microseconds=-1)
>>> (d.days, d.seconds, d.microseconds)
(-1, 86399, 999999)

This is valid for python 2.7 and 3 both.

Why this is happening is simple:

a , b = datetime.datetime.now(), datetime.datetime.now()
# here datetime.now() in a will be <= b.
# That is because they will be executed separately at different CPU clock cycle.

a - b
# datetime.timedelta(-1, 86399, 999973)

b - a
# datetime.timedelta(0, 0, 27)

To get the proper time difference:

(tnow - datetime.datetime.now()).total_seconds()
# output: -1.751166

This Answer gives more information on how to use time delta safely (handle negative values) Link

like image 136
Vikash Singh Avatar answered Nov 14 '22 20:11

Vikash Singh


You are encountering a "corner case" situation.

  • Every datetime.datetime.now() produces a datetime.datetime object ([Python]: https://docs.python.org/3/library/datetime.html#datetime-objects), which is the current date & time at the moment the call was made
  • You have 2 such calls (even if they are on the same line). Since the CPU speeds are very high nowadays, every such call takes a very small amount of time (much less than microseconds, I presume)
  • But, when the 1st call is at the very end of a (microsecond?) period, and the 2nd one is at the beginning of the next one, you'd get this behavior:
>>> import datetime

>>> now0 = datetime.datetime.now()
>>> now0
datetime.datetime(2018, 2, 20, 12, 23, 23, 1000)
>>> delta = datetime.timedelta(microseconds=1)
>>> now1 = now0 + delta
>>> now0 - now1
datetime.timedelta(-1, 86399, 999999)

Explanation:

  • Let now0 to be the result of the 1st call made to datetime.datetime.now()
  • Let's say that the 2nddatetime.datetime.now() call happens one microsecond later (I am reproducing the behavior using the delta object, as the times involved here are waaay too small for me to be able to to run the line at the exact time when this behavior is encountered). That is placed into now1
  • When subtracting them you get the negative value (in my case is -delta), since now0 happened earlier than now1 (check [Python]: timedelta Objects for more details)
like image 42
CristiFati Avatar answered Nov 14 '22 22:11

CristiFati