183

What is the cleanest and most Pythonic way to get tomorrow's date? There must be a better way than to add one to the day, handle days at the end of the month, etc.

linkmaster03
  • 4,038
  • 6
  • 25
  • 22

7 Answers7

343

datetime.date.today() + datetime.timedelta(days=1) should do the trick

Esteban Küber
  • 36,388
  • 15
  • 79
  • 97
Kamil Szot
  • 17,436
  • 6
  • 62
  • 65
59

timedelta can handle adding days, seconds, microseconds, milliseconds, minutes, hours, or weeks.

>>> import datetime
>>> today = datetime.date.today()
>>> today
datetime.date(2009, 10, 1)
>>> today + datetime.timedelta(days=1)
datetime.date(2009, 10, 2)
>>> datetime.date(2009,10,31) + datetime.timedelta(hours=24)
datetime.date(2009, 11, 1)

As asked in a comment, leap days pose no problem:

>>> datetime.date(2004, 2, 28) + datetime.timedelta(days=1)
datetime.date(2004, 2, 29)
>>> datetime.date(2004, 2, 28) + datetime.timedelta(days=2)
datetime.date(2004, 3, 1)
>>> datetime.date(2005, 2, 28) + datetime.timedelta(days=1)
datetime.date(2005, 3, 1)
Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
9

No handling of leap seconds tho:

>>> from datetime import datetime, timedelta
>>> dt = datetime(2008,12,31,23,59,59)
>>> str(dt)
'2008-12-31 23:59:59'
>>> # leap second was added at the end of 2008, 
>>> # adding one second should create a datetime
>>> # of '2008-12-31 23:59:60'
>>> str(dt+timedelta(0,1))
'2009-01-01 00:00:00'
>>> str(dt+timedelta(0,2))
'2009-01-01 00:00:01'

darn.

EDIT - @Mark: The docs say "yes", but the code says "not so much":

>>> time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S")
(2008, 12, 31, 23, 59, 60, 2, 366, -1)
>>> time.mktime(time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S"))
1230789600.0
>>> time.gmtime(time.mktime(time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S")))
(2009, 1, 1, 6, 0, 0, 3, 1, 0)
>>> time.localtime(time.mktime(time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S")))
(2009, 1, 1, 0, 0, 0, 3, 1, 0)

I would think that gmtime or localtime would take the value returned by mktime and given me back the original tuple, with 60 as the number of seconds. And this test shows that these leap seconds can just fade away...

>>> a = time.mktime(time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S"))
>>> b = time.mktime(time.strptime("2009-01-01 00:00:00","%Y-%m-%d %H:%M:%S"))
>>> a,b
(1230789600.0, 1230789600.0)
>>> b-a
0.0
PaulMcG
  • 62,419
  • 16
  • 94
  • 130
  • 1
    `time.strftime` handles leap seconds: see Note 2: http://docs.python.org/library/time.html#time.strftime and Note 3: http://docs.python.org/library/datetime.html#strftime-behavior – Mark Rushakoff Oct 02 '09 at 00:18
  • This is because Unix time doesn't handle leap seconds. See http://en.wikipedia.org/wiki/Unix_time#History, http://www.mail-archive.com/leapsecs@rom.usno.navy.mil/msg00094.html, and POSIX itself. –  Nov 29 '09 at 23:37
  • "each and every day shall be accounted for by exactly 86400 seconds" http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15 –  Nov 29 '09 at 23:42
  • Leap years account for the difference between the solar year and an even 365 days, while leap seconds are inherently different and account for differences caused by external factors like earthquakes. This makes them irregular and can't be determined in the same way as, e.g. determining the day of the week that March 3rd, 2055 will land on. – David Woods Mar 04 '13 at 14:04
  • 1
    @DavidWoods: leap seconds are to keep UTC within +/- 0.9 seconds from UT1 (Earth rotation). There are 25 leap seconds accumulated from 1972 to 2012. Earthquakes are too weak to cause it ([a single earthquake may introduce microsecond changes -- thousand times less than a typical millisecond difference in the duration of the day from 86400 SI seconds](http://en.wikipedia.org/wiki/Earth's_rotation)). – jfs Sep 04 '14 at 21:56
8

Even the basic time module can handle this:

import time
time.localtime(time.time() + 24*3600)
u0b34a0f6ae
  • 48,117
  • 14
  • 92
  • 101
  • 2
    This fails on the boundaries of Daylight Savings Time in the united states, because at those boundaries one day will have 23 hours and one day will have 25 hours. This also does not take leap seconds into account. – Charles Wood Aug 14 '14 at 23:12
  • 1
    @CharlesWood: this answer may return a different hour that (in some timezones) means it may return a **different date** (not tomorrow) but it always returns the time that is exactly 24 hours ahead (the accepted answer returns midnight (unknown hours from now)). I don't see how leap seconds can change the result here unless called during a leap second on systems where 23:59:60 and 00:00:00 have the same timestamp. – jfs Sep 04 '14 at 21:46
  • True, it will always be 24 hours from now, but that wasn't the question. OP wanted to know how to get __tomorrow's date__. The leap seconds thing was just nitpicking ;) – Charles Wood Sep 04 '14 at 22:01
  • @CharlesWood: yes. I've just clarified that it doesn't return 23, 25 hours. And yes, it may return **wrong date** (not tomorrow e.g., for "2014-10-18 23:00:00" in "Brazil/East" timezone). Related: [Given the current time in UTC, how do you determine the start and end time of the day in a particular timezone?](http://stackoverflow.com/a/25605133/4279). – jfs Sep 04 '14 at 22:21
  • @J.F.Sebastian Right, I was just trying to point out that __days aren't always 24 hours long__. No wonder working with dates is so difficult; it's hard to even communicate about them :/ – Charles Wood Sep 05 '14 at 17:00
  • @Greg, disregarding the daylight savings issues, I don't feel it's elegant to have to add `24*3600` seconds - I just want to add a day, and I shouldn't really even need to know how many hours/minutes/seconds there are in a day (although it might make everyday life a bit difficult)! – Simon MᶜKenzie May 15 '15 at 04:48
3

For people who are dealing with servers Time Stamp

To get yesterday Time Stamp:

yesterdaytimestamp = datetime.datetime.today() + datetime.timedelta(days=-1)

To get Today Time Stamp:

currenttimestamp = datetime.datetime.now().timestamp()

To get Tomorrow Time Stamp:

tomorrowtimestamp = datetime.datetime.today() + datetime.timedelta(days=1)

To print:

print('\n Yesterday TimeStamp is : ', yesterdaytimestamp.timestamp(), 
    '\n Today TimeStamp is :', currenttimestamp, 
    '\n Tomorrow TimeStamp is: ', tomorrowtimestamp.timestamp())

The output:

Yesterday TimeStamp is :  1632842904.110993 
Today TimeStamp is       :  1632929304.111022 
Tomorrow TimeStamp is    :  1633015704.11103
Davo
  • 526
  • 3
  • 19
Mr Dream
  • 134
  • 1
  • 10
3

There's nothing at all wrong with using today() as shown in the selected answer if that is the extent of your needs.

datetime.date.today() + datetime.timedelta(days=1)

Alternatively, if you or someone else working with your code might need more precision in handling tomorrow's date, consider using datetime.now() instead of today(). This will certainly allow for simpler, more readable code:

datetime.datetime.now() + datetime.timedelta(days=1)

This returns something like:

datetime.datetime(2022, 2, 17, 19, 50, 19, 984925)

The advantage is that you can now work with datetime attributes in a concise, human readable way:

class datetime.datetime

A combination of a date and a time. Attributes: year, month, day, hour, minute, second, microsecond, and tzinfo.

Examples

You can easily convert this to a date object withdate():

import datetime
tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
print(f"Tomorrow's date is {tomorrow.date()}")

tomorrow.date() is easy to use and it is very clear to anyone reading your code that it is returning the date for tomorrow. The output for the above looks like so:
Tomorrow's date is 2022-02-17

If later in your code you only need the date number for the day, you can now use tomorrow.day:

print(f"Tomorrow is the {tomorrow.day}rd")

Which will return something like:
Tomorrow is the 17rd

That's a silly example, but you can see how having access to these attributes can be useful and keep your code readable as well. It can be easily understood that tomorrow.day returns the day number.

Need to work with the exact time tomorrow's date begins? You can now replace the hours, minutes, seconds, and microseconds:

# Replace all attributes except day with 0.
midnight = tomorrow.replace(
    hour=0,
    minute=0,
    second=0,
    microsecond=0)
# Print midnight as the beginning of tomorrow's date.
print(f"{midnight}")

Reading the above code, it should be apparent which attributes of tomorrow are being replaced. When midnight is printed, it will output:
2022-02-17 00:00:00

Need to know the time left until tomorrow's date? Now something like that is possible, simple, and readable:

print(f"{midnight - datetime.datetime.now()}")

The output is the time to the microsecond that tomorrow's date begins: 3:14:28.158331

There are many ways people might wish to handle tomorrow's date. By ensuring these attributes are available from the beginning, you can write more readable code and avoid unnecessary work later.

iyrin
  • 612
  • 5
  • 14
0

For the case you only want to calculate the timestamp

import time
tomorrow = (int(time.time() / 86400) + 1) * 86400
MattPatrik
  • 26
  • 1
  • 4