58

I've read a few posts about this and thought I had some code that worked. If the difference between the 2 values is less than a 1sec then the millisecs displayed is correct.

If the difference is more than a sec, its still only showing me the difference of the millisecs.

As below.

Correct:

 now_wind 2013-08-25 08:43:04.776209 
 first_time_wind 2013-08-25 08:43:04.506301
 time_diff 0:00:00.269908
 diff 269

Wrong - this should be 2000 + 76?:

 now_wind 2013-08-25 08:43:25.660427
 first_time_wind 2013-08-25 08:43:23.583902
 time_diff 0:00:02.076525
 diff 76


 #!/usr/bin/env python
 import datetime
 import time
 from time import sleep
 first_time_wind = datetime.datetime.now()
 sleep (2)
 now_wind = datetime.datetime.now()
 print "now_wind", now_wind
 print "first_time_wind", first_time_wind
 time_diff_wind = (now_wind - first_time_wind)
 print "time_diff", time_diff_wind
 print "diff", time_diff_wind.microseconds / 1000
Greg
  • 1,715
  • 5
  • 27
  • 36

5 Answers5

84

Try using total_seconds method:

print time_diff_wind.total_seconds() * 1000

That method is equivalent to: (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6

Note: It's available since version 2.7

Caumons
  • 9,341
  • 14
  • 68
  • 82
moliware
  • 10,160
  • 3
  • 37
  • 47
  • 8
    add `int(time_diff_wind.total_seconds() * 1000)` to get just the milliseconds, otherwise you will still have some decimal precision like `17215.996` – ebob Jun 08 '17 at 14:35
49
>>> a = datetime.datetime.now()
>>> b = datetime.datetime.now()
>>> a
datetime.datetime(2013, 8, 25, 2, 5, 1, 879000)
>>> b
datetime.datetime(2013, 8, 25, 2, 5, 8, 984000)
>>> a - b
datetime.timedelta(-1, 86392, 895000)
>>> b - a
datetime.timedelta(0, 7, 105000)
>>> (b - a).microseconds
105000
>>> (b - a).seconds
7
>>> (b - a).microseconds / 1000
105

your microseconds don't include the seconds that have passed

blakev
  • 4,154
  • 2
  • 32
  • 52
25

The correct answer (in 2020) is:

>>> from datetime import timedelta
>>> timedelta(days=1, milliseconds=50) / timedelta(milliseconds=1)
86400050.0

The other answers lose precision and/or are more verbose.

shadow-light
  • 447
  • 5
  • 7
18

I faced this issue as well, but in my case I need real milliseconds precision, so using total_seconds() * 1000 isn't an option for me, so what I did is:

def millis_interval(start, end):
    """start and end are datetime instances"""
    diff = end - start
    millis = diff.days * 24 * 60 * 60 * 1000
    millis += diff.seconds * 1000
    millis += diff.microseconds / 1000
    return millis

I hope this helps someone else! :)

Caumons
  • 9,341
  • 14
  • 68
  • 82
  • 10
    I think total_seconds() returns a floating point number and includes the microseconds, so it does retain millisecond accuracy, correct me if I'm wrong. – Samuel Mar 30 '16 at 17:12
  • 2
    @Samuel This is true since Python version 2.7. See: https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds – Caumons Sep 30 '16 at 06:24
  • 1
    @Samuel As long as the number of total seconds was not so large that the floating point lost precision the `total_seconds()` approach should be preferred. Large is explained in [this discussion](https://stackoverflow.com/a/13543600/6741942) and well exceeds a human lifetime so I couldn't think of many applications needing decimal precision. – strongbutgood Aug 01 '19 at 05:01
  • @Samuel, but it does not keep track of longer time spans, like minutes, hours etc, so get wrong results whenever these reset to zero. – alancalvitti Dec 04 '19 at 20:41
8

From the documentation:

Instance attributes (read-only):

Attribute Value

days Between -999999999 and 999999999 inclusive

seconds Between 0 and 86399 inclusive

microseconds Between 0 and 999999 inclusive

Microseconds never exceed 999,999. Hence your milliseconds never exceed 999.

Hyperboreus
  • 31,997
  • 9
  • 47
  • 87