By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,645 Members | 1,048 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,645 IT Pros & Developers. It's quick & easy.

comparing datetime with date

P: n/a
I was very surprised to discover that
import datetime
x = datetime.date(2004, 9, 14)
y = datetime.datetime(2004, 9, 14, 6, 43, 15)
print x == y

True

How can these two objects be considered equal? Is there a *general* way
to test for date != datetime as well as 4.5 != 4.6?

Donnal Walter
Arkansas Children's Hospital
Jul 18 '05 #1
Share this Question
Share on Google+
16 Replies


P: n/a
Donnal Walter wrote:
I was very surprised to discover that
>>> import datetime
>>> x = datetime.date(2004, 9, 14)
>>> y = datetime.datetime(2004, 9, 14, 6, 43, 15)
>>> print x == y
True

How can these two objects be considered equal?


Guessing:

In http://docs.python.org/lib/datetime-datetime.html
it says this """Note: In order to stop comparison from falling back to
the default scheme of comparing object addresses, datetime comparison
normally raises TypeError if the other comparand isn't also a datetime
object. However, NotImplemented is returned instead if the other
comparand has a timetuple attribute. This hook gives other kinds of date
objects a chance at implementing mixed-type comparison. """
(the docs for the date class say the same).

I suspect this means simply that datetime.date *does* use this
behaviour to provide a mixed-type comparison that makes sense,
to _it_.
Is there a *general* way
to test for date != datetime as well as 4.5 != 4.6?


Couldn't say, sorry.

-Peter
Jul 18 '05 #2

P: n/a
Donnal Walter wrote:
I was very surprised to discover that
>>> import datetime
>>> x = datetime.date(2004, 9, 14)
>>> y = datetime.datetime(2004, 9, 14, 6, 43, 15)
>>> print x == y
True


I think thats perfectly legal - a date object should care only about if the
object it is compared to contains some sort of valid date information, and
restrict its comparision to that.

The matter is that you try to compare two different things here - so its up
to the implementation if how it deals with this, as there is no canonical
way to compare two things that aren't even structural equivalent.

The current implementation chose one way to do it - and thats as good as any
other one could think of, and certainly has some convenience advantage on
its side.
How can these two objects be considered equal? Is there a *general* way
to test for date != datetime as well as 4.5 != 4.6?


Try making a datetime-object from your date, with zeros for the time part -
then you'll get what you want.

--
Regards,

Diez B. Roggisch
Jul 18 '05 #3

P: n/a
Diez B. Roggisch wrote:
Donnal Walter wrote:
How can these two objects be considered equal? Is there a *general* way
to test for date != datetime as well as 4.5 != 4.6?


Try making a datetime-object from your date, with zeros for the time part -
then you'll get what you want.


While trying to provide my first answer, I thought of suggesting
this, but there doesn't appear to be a simple way of doing it.
It looked like the following was the best I could do (where 'x'
is a datetime.date object):

z = datetime.datetime(x.year, x.month, x.day)

I just found timetuple(), which means this could be written
in the awful form:

z = datetime.datetime(*x.timetuple()[:3])

but that's hardly better, and definitely more inscrutable.

To answer Donnal's question above, however, it appears this
might be a reasonable approach:
x.timetuple() == y.timetuple()

False

Not sure there's a better approach readily available.

-Peter
Jul 18 '05 #4

P: n/a
[Diez B. Roggisch]
Try making a datetime-object from your date, with zeros for the time part -
then you'll get what you want.
[Peter Hansen]
While trying to provide my first answer, I thought of suggesting
this, but there doesn't appear to be a simple way of doing it.


datetime.datetime has a class constructor for building a datetime out
of a date and a time, so this can be done via a simple one-liner:
import datetime
t = datetime.date.today()
t datetime.date(2004, 9, 14) datetime.datetime.combine(t, datetime.time()) datetime.datetime(2004, 9, 14, 0, 0)

Jul 18 '05 #5

P: n/a
Peter Hansen wrote:
Diez B. Roggisch wrote:
Donnal Walter wrote:
How can these two objects be considered equal? Is there a *general* way
to test for date != datetime as well as 4.5 != 4.6?

Try making a datetime-object from your date, with zeros for the time
part -
then you'll get what you want.

While trying to provide my first answer, I thought of suggesting
this, but there doesn't appear to be a simple way of doing it.
It looked like the following was the best I could do (where 'x'
is a datetime.date object):

z = datetime.datetime(x.year, x.month, x.day)

I just found timetuple(), which means this could be written
in the awful form:

z = datetime.datetime(*x.timetuple()[:3])

but that's hardly better, and definitely more inscrutable.

To answer Donnal's question above, however, it appears this
might be a reasonable approach:
>>> x.timetuple() == y.timetuple()

False

Not sure there's a better approach readily available.

-Peter


Thanks for the suggestions. I have decided *not* to store date/datetime
objects, but rather store the corresponding time tuples: 3-tuple for
date only, and 5- or 6-tuple for date and time, depending on whether or
not seconds are given). Then the following method notifies observers if
a simple date is changed to the date with time (just like number changes
and string changes).

def set(self, value):
if value != self._state: # now this works!
self._state = value
self.notify_observers(self)

This means, of course, that if an observer wants to calculate a
TimeDelta, the corresponding datetimes have to be constructed, but I
don't think this is too inefficient.

time1 = datetime.datetime(*time1.get()) # 3-, 5-, or 6-tuple
time2 = datetime.datetime(*time2.get())
tdelta = time2 - time1

The observer object (and user) would need to understand the loss of
precision when times are not actually given, but at least the relevant
methods work regardless.

Thanks again,

Donnal Walter
Arkansas Children's Hospital
Jul 18 '05 #6

P: n/a
This is very interesting because if you continue further and coerce both to
strings you get:
print str(y) == str(y) True str(y) '2004-09-14 06:43:15' str(x) '2004-09-14'
Even though there string values are different they still match?

If we perform a CRC (Cyclic Redundancy Check) i.e compute a one way hash:

import binascii crc_x = binascii.crc32(str(x))
crc_y = binascii.crc32(str(y))
print crc_x == crc_y
False

So this confirms that there values do differ yet a comparision using ==
returns True?

All i can assume is that when a Date / DateTime comparision is made the
'lowest denominator' i.e Date is used but I may be very wrong

Will watch this thread closely

"Donnal Walter" <do****@donnal.net> wrote in message
news:ma**************************************@pyth on.org...
I was very surprised to discover that
import datetime
x = datetime.date(2004, 9, 14)
y = datetime.datetime(2004, 9, 14, 6, 43, 15)
print x == y

True

How can these two objects be considered equal? Is there a *general* way to
test for date != datetime as well as 4.5 != 4.6?

Donnal Walter
Arkansas Children's Hospital

Jul 18 '05 #7

P: n/a
On Wed, 15 Sep 2004 09:24:03 +1000,
Graeme Matthew <gr************@contrado.com.au> wrote:
This is very interesting because if you continue further and coerce both to
strings you get:
print str(y) == str(y) True


Of course if you actually do:
print str(x) == str(y) False


str(y) '2004-09-14 06:43:15' str(x) '2004-09-14'


Even though there string values are different they still match?


No, they only matched becuase you compared y with y :)
--
Sam Holden
Jul 18 '05 #8

P: n/a
On Wed, 15 Sep 2004 09:24:03 +1000 Graeme wrote:
This is very interesting because if you continue further and coerce both
to strings you get:
print str(y) == str(y) of course: ^ ^ :^)
True Even though there string values are different they still match? today = datetime.date(2004,9,14)
yesterday = datetime.date(2004,9,13)
now = datetime.datetime(2004,9,14,20,0)
now == today True now == yesterday False
Looks like date and datetime have 3 arguments and minimum 3 args
respectively, so the comparison appears to simply use the minimum data
available... when given more data to compare, we get:
minute_ago = datetime.datetime(2004,9,14,19,59)
minute_ago == now

False

All i can assume is that when a Date / DateTime comparision is made the
'lowest denominator' i.e Date is used but I may be very wrong
I agree...
Will watch this thread closely

Jul 18 '05 #9

P: n/a
yes it was late, apologies therefore a simple way to solve this problem
would be:

str(x) == str(y)

:=-)

"Sam Holden" <sh*****@flexal.cs.usyd.edu.au> wrote in message
news:slrnckf3e5.ptn.sh*****@flexal.cs.usyd.edu.au. ..
On Wed, 15 Sep 2004 09:24:03 +1000,
Graeme Matthew <gr************@contrado.com.au> wrote:
This is very interesting because if you continue further and coerce both
to
strings you get:
> print str(y) == str(y)

True


Of course if you actually do:
> print str(x) == str(y)

False


> str(y)

'2004-09-14 06:43:15'
> str(x)

'2004-09-14'
>


Even though there string values are different they still match?


No, they only matched becuase you compared y with y :)
--
Sam Holden

Jul 18 '05 #10

P: n/a
Graeme Matthew wrote:
str(y) '2004-09-14 06:43:15'str(x) '2004-09-14' Even though there string values are different they still match?

If we perform a CRC (Cyclic Redundancy Check) i.e compute a one way hash:

import binascii
crc_x = binascii.crc32(str(x))
crc_y = binascii.crc32(str(y))
print crc_x == crc_y


False

So this confirms that there values do differ yet a comparision using ==
returns True?


I'm unclear why you think this binascii.crc32 stuff has anything
to do with anything. The strings are different, as you showed.

Ignoring collisions (which would be rare) two different strings
are going to have different CRC32 values. Did you confuse yourself
somewhere along the way?

(Now if the CRC values for those two strings were the same, *that*
would indeed be interesting.)

-Peter
Jul 18 '05 #11

P: n/a
On Tue, 14 Sep 2004 20:37:29 -0400 Pierre wrote:
All i can assume is that when a Date / DateTime comparision is made
the'lowest denominator' i.e Date is used but I may be very wrong


I agree...


Oops... LOL ...with the first part.
Jul 18 '05 #12

P: n/a
Diez B. Roggisch schrieb:
The matter is that you try to compare two different things here - so its up
to the implementation if how it deals with this, as there is no canonical
way to compare two things that aren't even structural equivalent.


datetime and date are different by implementation, not by meaning. Both
are time intervals.

--
-------------------------------------------------------------------
Peter Maas, M+R Infosysteme, D-52070 Aachen, Tel +49-241-93878-0
E-mail 'cGV0ZXIubWFhc0BtcGx1c3IuZGU=\n'.decode('base64')
-------------------------------------------------------------------
Jul 18 '05 #13

P: n/a
Peter Maas wrote:
Diez B. Roggisch schrieb:
The matter is that you try to compare two different things here - so
its up
to the implementation if how it deals with this, as there is no canonical
way to compare two things that aren't even structural equivalent.

datetime and date are different by implementation, not by meaning. Both
are time intervals.


Actually both are time *points* (as opposed to time intervals) with
differing degress of precision. My problem is somewhat akin to comparing
4.0 with 4.00001. For some purposes it might be appropriate to consider
these two values to be the same, but I need for them to be different.

Donnal Walter
Arkansas Children's Hospital

Jul 18 '05 #14

P: n/a
>> The matter is that you try to compare two different things here - so its
up to the implementation if how it deals with this, as there is no
canonical way to compare two things that aren't even structural
equivalent.


datetime and date are different by implementation, not by meaning. Both
are time intervals.


Neither of them is - they are discrete points in time, with different
resolution.

There is a difference in saying "vacation starts at 9/9/2004" or "lets meet
at 9/9/2004, 12:00" - even to non-programmers.

--
Regards,

Diez B. Roggisch
Jul 18 '05 #15

P: n/a
Diez B. Roggisch schrieb:
datetime and date are different by implementation, not by meaning. Both
are time intervals.

Neither of them is - they are discrete points in time, with different
resolution.

There is a difference in saying "vacation starts at 9/9/2004" or "lets meet
at 9/9/2004, 12:00" - even to non-programmers.


There are several meanings. A date is valid for 24 hours. If you think
of a date as point in time there is usually a time part of 0:00 silently
added. No matter which meaning you prefer: Evaluating 2004-09-16 ==
2004-09-16T3:14 as true is very surprising.

You could as well say that int(3) == 3.14 is true (disregarding the
fractional part of the second operand).

--
-------------------------------------------------------------------
Peter Maas, M+R Infosysteme, D-52070 Aachen, Tel +49-241-93878-0
E-mail 'cGV0ZXIubWFhc0BtcGx1c3IuZGU=\n'.decode('base64')
-------------------------------------------------------------------
Jul 18 '05 #16

P: n/a
> There are several meanings. A date is valid for 24 hours. If you think
of a date as point in time there is usually a time part of 0:00 silently
added. No matter which meaning you prefer: Evaluating 2004-09-16 ==
2004-09-16T3:14 as true is very surprising.


Its a matter of taste - I've seen plenty of worarounds in my life -
especially in database-related code - that exactly tries to create that
behaviour of forced equality. The reason beeing that there are not two
distinct types date and datetime, but only the latter.

A date is all the times from 0:00 to 23:59 only if you you view it with the
greater resolution of datetime - if you restrict yourself to dates, its one
point.

I don't say that your POV isn't correct - but neither is the one currently
implemented: If you compare apples to oranges, it depends on what you focus
on: If you're strict, you'd say they're different. If you focus on them
beeing fruits, you might say they are equal.

We deal here with ternary logic - True, False and Bottom/Failure. One can
very well argue, that your example

int(3) == 3.14

shouldn't work at all, but produce an exception, forcing the programmer to
think about explicit conversion. Then you are in ADA-World :)

But as python tries to be a convenient language, they silently are coerced
to maching types and compared then. The same happened here - with a for
some people surprising outcome, for others it makes life much easier.
--
Regards,

Diez B. Roggisch
Jul 18 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.