69

I want to get the seconds that expired since last midnight. What's the most elegant way in Python?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
linqu
  • 11,320
  • 8
  • 55
  • 67
  • 3
    What have you tried to do this? Can you share some code with us? (I'm sure the downvotes are just because of this ...) – Levon Apr 12 '13 at 12:25
  • 5
    Actually I was searching for that question on stackoverflow but could not get an answer. After consulting the python docs I had a solution I liked. To help other people with the same problem I posted my solution as a question & answer. But apparently people don't like that, even though it gets promoted here http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ – linqu Apr 12 '13 at 12:29
  • How about timestamp % 86400? – Nour Wolf Jan 30 '19 at 15:08
  • @NourChawich clever idea, that should also work if your timezone is UTC – linqu Feb 01 '19 at 08:49
  • Why does every answer here require datetime? This is simpler: `t = time.localtime(); since_midnight = t.tm_hour * 3600 + t.tm_min * 60 + t.tm_sec` – SurpriseDog Feb 06 '21 at 03:14

3 Answers3

66

It is better to make a single call to a function that returns the current date/time:

from datetime import datetime

now = datetime.now()
seconds_since_midnight = (now - now.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds()

Or does

datetime.now() - datetime.now()

return zero timedelta for anyone here?

eumiro
  • 207,213
  • 34
  • 299
  • 261
  • why is it better to use a single call? – Dirk Apr 12 '13 at 12:40
  • 4
    Otherwise you get two concepts of what "now" is. – Lennart Regebro Apr 12 '13 at 12:41
  • 3
    @Dirk - because the instant my `now` is created is the instant I want to calculate the number of seconds for. If you take `now` in one line and then the `midnight` in a second line (executed nano/micro/seconds later), your calculations may go wrong. Imagine the midnight occurs in that time. – eumiro Apr 12 '13 at 12:42
  • Using just "import datetime" avoids masking other datetime methods that might be needed elsewhere in the code. Sure, you have to use datetime.datetime.now(), but at least it's unambiguous. – Alex North-Keys Apr 24 '17 at 15:26
  • 1
    @Dirk - now()-now() is a discrepancy of 17 microseconds (on my laptop), but datetime.now().minute+datetime.now().second/60 - apparently a pretty reasonable calculation - will be off by 59 seconds, about once in 3.5 million attempts. – AMADANON Inc. Aug 14 '18 at 23:33
  • `(now - now.normalize()).total_seconds()` maybe this function is recent, not sure, but I find it a bit more compact :) – Arthur Araújo Jul 15 '20 at 12:11
26
import datetime
now = datetime.datetime.now()
midnight = now.replace(hour=0, minute=0, second=0, microsecond=0)
seconds = (now - midnight).seconds

or

import datetime
now = datetime.datetime.now()
midnight = datetime.datetime.combine(now.date(), datetime.time())
seconds = (now - midnight).seconds

Which to choose is a matter of taste.

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
  • Here. :-) We added it pretty much at the same time, it seems. Although when testing it it turned out I had misspelled things. – Lennart Regebro Apr 12 '13 at 12:39
  • 1
    another way to get midnight: [`midnight = datetime(d.year, d.month, d.day)`](http://stackoverflow.com/a/33276464/4279). btw, any answer that does not use `mktime()` or equiv. fails if there was a DST transition today. – jfs Nov 18 '15 at 10:57
  • You can use a correct timezone implementation as well. – Lennart Regebro Nov 20 '15 at 12:45
  • You should use timedelta.total_seconds() instead of .seconds. If there is a nonzero 'days' component, .seconds will not include that, at least as of Python 3.8 – The AI Architect Jan 11 '21 at 02:17
4

I would do it this way:

import datetime
import time

today = datetime.date.today()
seconds_since_midnight = time.time() - time.mktime(today.timetuple())
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
linqu
  • 11,320
  • 8
  • 55
  • 67
  • If this is part of your question, it's better to edit your question and add this to your original post as your attempt. – Levon Apr 12 '13 at 12:28
  • 1
    your answer is the only one that takes the local timezone into account (other answers may produces easily an hour error due to DST transitions). `mktime()` may also fail, see [Find if 24 hrs have passed between datetimes - Python](http://stackoverflow.com/a/26313848/4279) – jfs Nov 18 '15 at 10:58