508

How would I compare two dates to see which is later, using Python?

For example, I want to check if the current date is past the last date in this list I am creating, of holiday dates, so that it will send an email automatically, telling the admin to update the holiday.txt file.

codeforester
  • 39,467
  • 16
  • 112
  • 140
Steven Matthews
  • 9,705
  • 45
  • 126
  • 232
  • 28
    Er, you use the `<` and `>` operators, just like with any other comparison. – Daniel Roseman Nov 15 '11 at 20:00
  • 12
    @JohnMachin: you write a function with prototype `int compare_dates(void const *, void const*)`, cast both arguments to `struct Date *` and implement the comparison logic. It may not be that obvious to a Python newcomer. – Fred Foo Nov 15 '11 at 20:42
  • 1
    @larsmans: Sorry .... s/any_language/any_reasonable_language/ and anyone used to an unreasonable language should spend a few minutes perusing the docs and trying out date1 < date2 – John Machin Nov 15 '11 at 20:51
  • 2
    http://docs.python.org/library/datetime.html#datetime-objects Ctrl-F search for "Supported operations" – John Machin Nov 15 '11 at 20:56
  • @FredFoo This question is about Python, not C. – Galaxy May 07 '19 at 03:30
  • 1
    @Galaxy - he’s using an analogy, to show that what should be simple to a seasoned person might not be simple to a total beginner and he’s using C to illustrate this. He doesn’t think the question is about C. And he was right, I was a total beginner at the time I asked this question almost 8 years ago, and had no clue how any of it worked. – Steven Matthews May 07 '19 at 03:34
  • Yes, I agree that Fred's comment is helpful as an analogy. I am good at C but in Python, I'm in the same stage you were at 8 years ago. :) – Galaxy May 07 '19 at 03:42

7 Answers7

641

Use the datetime method and the operator < and its kin.

>>> from datetime import datetime, timedelta
>>> past = datetime.now() - timedelta(days=1)
>>> present = datetime.now()
>>> past < present
True
>>> datetime(3000, 1, 1) < present
False
>>> present - datetime(2000, 4, 4)
datetime.timedelta(4242, 75703, 762105)
Thomas Decaux
  • 21,738
  • 2
  • 113
  • 124
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 25
    This works for timezone-aware values as well, if anyone was wondering. – Mat Gessel Mar 08 '16 at 01:52
  • 2
    What's different between `past` and `present`? I can't understand your example and its result doesn't make sense. – Emadpres Mar 13 '17 at 08:42
  • 20
    @Emadpres: imagine this was typed manually. The past line was typed first, while the present line was typed second... so the past line was entered first, so past < present is True. – ramcdougal Mar 20 '17 at 15:50
  • @MatGessel does that mean that if the two dates are from different timezones, it will understand that and convert them to any one common timezone before comparing the values? If yes, that's really cool. – Vikas Prasad Jul 25 '18 at 12:52
  • ok, a quick [doc search](https://docs.python.org/3.4/library/datetime.html#datetime.datetime.tzinfo) gave me the answer. It actually adjusts different timezones before comparing. – Vikas Prasad Jul 25 '18 at 12:59
  • 2
    Quoting from the doc: "If one comparand is naive and the other is aware, TypeError is raised if an order comparison is attempted. For equality comparisons, naive instances are never equal to aware instances. If both comparands are aware, and have the same tzinfo attribute, the common tzinfo attribute is ignored and the base datetimes are compared. If both comparands are aware and have different tzinfo attributes, the comparands are first adjusted by subtracting their UTC offsets (obtained from self.utcoffset())." – Vikas Prasad Jul 25 '18 at 13:00
  • 4
    The variable names should be `past` and `past_but_a_little_after`. Technically, `present` is also in the past when the comparison `past < present` is made. – william_grisaitis Aug 07 '18 at 18:57
  • `TypeError: can't compare offset-naive and offset-aware datetimes` – evandrix Jun 19 '19 at 19:03
  • 1
    @grisaitis Technically, any "present" time is in the past between getting it and operating on it :p On the order of nanoseconds at minimum – wjandrea Dec 23 '21 at 18:56
109

Use time

Let's say you have the initial dates as strings like these:

date1 = "31/12/2015"
date2 = "01/01/2016"

You can do the following:

newdate1 = time.strptime(date1, "%d/%m/%Y")
newdate2 = time.strptime(date2, "%d/%m/%Y")

to convert them to python's date format. Then, the comparison is obvious:

  • newdate1 > newdate2 will return False
  • newdate1 < newdate2 will return True
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Guillermo Pereira
  • 1,899
  • 1
  • 12
  • 7
49

datetime.date(2011, 1, 1) < datetime.date(2011, 1, 2) will return True.

datetime.date(2011, 1, 1) - datetime.date(2011, 1, 2) will return datetime.timedelta(-1).

datetime.date(2011, 1, 1) - datetime.date(2011, 1, 2) will return datetime.timedelta(1).

see the docs.

Daniel Nill
  • 5,539
  • 10
  • 45
  • 63
  • 2
    The last example doesn't work. Adding up two dates doesn't make sense anyways. – Joooeey May 30 '22 at 20:04
  • @Joooeey too many pending edits so I can't fix it, but he means `-`, not `+`. – Lorraine Jul 20 '23 at 11:16
  • Now that there's a `-` instead of a `+`, the expression is the same as the second expression. So the result would be the same too. Daniel Nill, can you please edit? – Joooeey Jul 22 '23 at 08:45
5

Other answers using datetime and comparisons also work for time only, without a date.

For example, to check if right now it is more or less than 8:00 a.m., we can use:

import datetime

eight_am = datetime.time( 8,0,0 ) # Time, without a date

And later compare with:

datetime.datetime.now().time() > eight_am  

which will return True

Luis
  • 3,327
  • 6
  • 35
  • 62
2

With python as the easiest language available it is pretty easy to compare dates in python the python operators <, > and == fit wonderfully with datetime objects. each of them has their own meaning in python:

  • < means the date is earlier than the first
  • > means the date comes later
  • == means the date is same as the first So, for your case:
import datetime

date = datetime.datetime(2000, 1, 1) # Replace with whatever you want
now = datetime.datetime.now() # You can even find the current date and time using this expression

if date < now:
    print('past')
elif date > now:
    print('future')
else:
    print('present')
# This would print "past"

rurban
  • 4,025
  • 24
  • 27
  • 3
    Other answers posted already cover the case. Better to look for new questions to contribute to the site. – Ank May 22 '21 at 11:27
0
import datetime
from dateutil.parser import parse

# Read in the list of holiday dates as a generator expression
with open('holiday.txt') as f:
    holiday_dates = (parse(line.strip()) for line in f)

# Get the current date
today = datetime.datetime.now().date()

# Check if the current date is past the last holiday date
if today > max(holiday_dates).date():
    # Send email to admin
    print("Please update the holiday.txt file")

We use a generator expression to read in the holiday dates, which returns a generator object that yields the parsed dates one at a time. We then use the max() function to find and compare the latest holiday date with the current date. We also use the date() method to convert the datetime objects to date objects, which allows us to compare them directly with the today variable.

Note that the dateutil.parser.parse() method can handle a wider variety of date formats than datetime.datetime.strptime(), so you may not need to specify a format string for the dates in your file. However, if you know the exact format of the dates in your file, you can still use strptime() to parse them if you prefer.

SyntaxNavigator
  • 312
  • 3
  • 10
-2

For calculating days in two dates difference, can be done like below:

import datetime
import math

issuedate = datetime(2019,5,9)   #calculate the issue datetime
current_date = datetime.datetime.now() #calculate the current datetime
diff_date = current_date - issuedate #//calculate the date difference with time also
amount = fine  #you want change

if diff_date.total_seconds() > 0.0:   #its matching your condition
    days = math.ceil(diff_date.total_seconds()/86400)  #calculate days (in 
    one day 86400 seconds)
    deductable_amount = round(amount,2)*days #calclulated fine for all days

Becuase if one second is more with the due date then we have to charge