[Tutor] time comparison question

Anna Ravenscroft revanna at mn.rr.com
Fri Nov 26 14:19:54 CET 2004


Brian van den Broek wrote:
> Hi all,
> 
> I'm trying to build some Python 2.3.4 code which will determine if the 
> actual time when it is run is after the date and time specified in some 
> data. I want my data to be able to specify the target date/time in a 
> various levels of detail. I.e., I want 2004-11-28 13:25, 2004-11-28, 
> 11-28, 11-28 13:25 to all be accepted.
> 
> My first thought was to get the current time via time.time() and then 
> parse my target date into a struct_time tuple to pass to time.mktime(), 
> run a comparison and be done. However, a struct_time tuple has data that 
> I won't know, given one of my target dates. I can make sensible dummies 
> for seconds (as well as year, hours and minutes when my target does not 
> specify them), and I know that the time module will try to make a 
> reasonable guess if given -1 for the DST element. But for 
> a_struct_time_tuple[-3:-1], I'd just be guessing at the weekday and day 
> of year. This leads to two questions:
> 
> 1) As I write, time.asctime() gives 'Fri Nov 26 04:32:18 2004' for a 
> time.localtime() of (2004, 11, 26, 4, 32, 18, 4, 331, 0). If I were 
> filling out a target date of 2004-11-26 04:32, I might well end up 
> passing something like (2004, 11, 26, 4, 32, 18, 6, 328, 0) to 
> time.mktime() for the result 'Sun Nov 26 04:32:18 2004'. If I am not 
> actually using the weekday information, I suspect that I can just ignore 
> the incorrect 'Sun'. But I feel better checking -- is anything going to 
> break by giving struct_time elements that don't make sense (provided of 
> course I am not myself explicitly drawing upon them)?
> 
> 2) Naturally, these worries lead me to think that there must be a better 
> way. I took a brief look at the datetime module, thinking it was a 
> natural place to find such tools. But it is all in terms of classes. 
> Sadly, I am still not too comfortable with doing things via OOP, so I'd 
> prefer a procedural (if that's the right term for a program with 
> functions but no classes) way. Is there a cleaner, non-class employing, 
> way of meeting my goal of finding out if a date of the form YYYY-MM-DD 
> is in the future, present, or past? (If it matters, I am on Windows.)

Actually, datetime is just about as painless OOP as you can get... It's 
no different from making a string, or an integer, and less complicated 
than time.mktime and its ilk.

Let's try doing your task with it and see what you think:

import datetime

def comparedates(date1, date2):			#define function
         try: date1 = date1.date()		# coerce to date*
         except AttributeError: date1		# don't need to coerce
         try: date2= date2.date()		
         except AttributeError: date2
         print sorted([date1, date2])		# built-in list sort

today = datetime.datetime.today() 		# right now
comparedate1 = datetime.date(2004, 12, 25)	# a date to compare
comparedate2 = datetime.datetime(2004, 9, 1)	# another date
lcomp = [comparedate1, comparedate2]		# a list of date
	
for d in lcomp:					# for each date in list
     comparedates(today,d)			# compare with today  						
If you prefer to just use less than or greater than, you can - you just 
have to remember to coerce any datetime objects to date objects. This 
isn't as complicated as it might sound. It's just like you use coercion 
between strings and integers and floats when you want to compare them. 
If you have list l = ['3', 2.4, 5] you would have to coerce the string 
to an integer or float in order to compare it with the other values in 
the list. Same here - you want to compare like with like, and it's 
pretty easy to coerce a datetime object into a date object.

Don't think of it as doing OOP. Just think of it as using a nifty new 
Type that Python gives you - just as nifty as strings and integers are.

Once you have two date objects, you can use < = > comparisons with them:

 >>> date1 = datetime.date(2004, 11, 25)
 >>> date2 = datetime.date(2004, 6, 25)
 >>> date1 < date2
False
 >>> date1 > date2
True
 >>>

Note that, if you need to worry about the *TIME* it was run, not *JUST* 
the date, you'll need to the opposite coercion - I would coerce 
everything (datetimes and dates) into a timetuple using the datetime method:
 >>> date1
datetime.date(2004, 11, 25)
 >>> date1.timetuple()
(2004, 11, 25, 0, 0, 0, 3, 330, -1)
 >>> time1 = date1.timetuple()
 >>> date3 = datetime.datetime.today()
 >>> date3
datetime.datetime(2004, 11, 26, 14, 8, 13, 252000)
 >>> time3=date3.timetuple()

That way you've got all timetuples to compare. And again, you can 
compare those just fine.

 >>> time1 > time3
False
 >>> time1 < time3
True
 >>>

Hope this helps.
Anna


More information about the Tutor mailing list