0

I'm looking to understand why module and class "datetime" can't work together. In the code below i have 3 choices :

  1. Else date.today doesn't work
  2. Else strptime doesn't work
  3. Else they can't work together :"TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'datetime.date'
import datetime

film_name = input("What is the movie name ?")

Date = input("When it's up ?")
date_format = "%d/%m/%y"

d1 = datetime.datetime.strptime(Date, date_format)
d0 = datetime.date.today()
print(d0,d1)

delta = d1 - d0

print("Il reste {} dodos avant la sortie de {}".format(delta, film_name))

I tried a lot of things like creating some function, then a class and nothing work. If someone can explain to me why or give me another method to do it ?

Thanks for your help and sorry for my english, not my native language. If you have any question i'm here

#Edit : as suggested below, i tried : ''' import "from datetime import date" d0 = datetime.combine(date.today(), datetime.min.time()) '''

The answer is : AttributeError: module 'datetime' has no attribute 'combine'

#Edit_2 : If i use : ''' d0 = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time()) ''' It almost works, i got :

Il reste 304 days, 0:00:00 dodos avant la sortie de Avatar

But i still see the time ?

#Edit3

If you need advice about it, please check the comments. Then the right answer is :


import datetime

film_name = input("What is the movie name ?")

Date = input("When it's up ?")
date_format = "%d/%m/%y"

d1 = datetime.datetime.strptime(Date, date_format)
d0 = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time())

d2 = (d1 - d0).days

print("Il reste {} dodos avant la sortie de {}".format(d2, film_name))
SRP
  • 209
  • 6
  • 15
  • You're right that's a mistake. But if i do datetime.datetime.today(), i got another error, with the seconds : raise ValueError("unconverted data remains: %s" % I used date instead of datetime to take only the "date" and not the hours, minutes, secondes – SRP Jul 05 '21 at 18:11

2 Answers2

2

datetime.date is a date - eg as I'm writing this it's July 5, 2021. datetime.datetime is a specific time on a date - eg 14:04 on July 5, 2021.

You can't subtract a date from a datetime, they're not comparable that way. You can convert between them, eg with datetime.combine() to create a datetime from a date and a time or with the date() instance method to truncate from a datetime to just a date. The latter is probably the simplest option if you want to keep using strptime to parse your input rather than switching to fromisoformat() or using a third party library like dateutil.

Your edited attempt using combine() is working as expected. You've modified the input date into a datetime instance, so when you subtract you get a timedelta. timedeltas include finer precision than just days - whether you create a datetime.date() instance from input or use combine() to turn the current date into a datetime() you'll see something similar. You can use the days field to get the number of days in the timedelta, discarding hours/minutes.

Peter DeGlopper
  • 36,326
  • 7
  • 90
  • 83
  • The combine way doesn't work because when i add "from datetime import date", the d1 with strptime doesn't work anymore. For the second way i don't really know how to do. Do i have to change the type to str, truncate and change the type to datetime again ? – SRP Jul 05 '21 at 19:01
  • 1
    You don't actually need to `from datetime import date` - and it wouldn't change `strptime` behavior anyway as long as you're still a) importing the full `datetime` module and then b) naming the method as `datetime.datetime.strptime(...)`. To combine, from your example code you'd just do something like `delta = d1 - datetime.datetime.combine(d0, datetime.time.min)`. Or give the results of `combine` a name before subtracting, that's fine too. For the second way, `delta = d1.date() - d0`. Or `d1 = datetime.datetime.strptime(...).date()`. – Peter DeGlopper Jul 05 '21 at 20:10
  • And note my closing paragraph regarding formatting `timedelta` output. Overall I'd prefer turning the input into a `date` object over using `combine()` but either way you'll need to take just the days field to get the output I think you want. – Peter DeGlopper Jul 05 '21 at 22:24
  • Actually it works but i still see the time in the answer (i imported it in the datetime.datetime.min.time, combined) – SRP Jul 05 '21 at 22:32
  • 1
    Right, see the last paragraph for that - that's how `timedelta` appears when you stringify it, but you can access the `days` field to get an integer count of whole days difference. – Peter DeGlopper Jul 05 '21 at 23:16
  • I won !! I understood what you said and got the right result, after hours of trying everything, thanks a lot – SRP Jul 06 '21 at 00:10
0

You can import classes from the datetime module like so

from datetime import date, datetime

# ...

d1 = datetime.strptime(Date, date_format)
d0 = datetime.combine(date.today(), datetime.min.time())

Or use the module itself

import datetime

# ...

d1 = datetime.datetime.strptime(Date, date_format)
d0 = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time())

Please refer to answer here: https://stackoverflow.com/a/1937636/9190640

jorf.brunning
  • 452
  • 4
  • 9
  • If i add "from datetime import date", the d1 with strptime doesn't work anymore – SRP Jul 05 '21 at 18:59
  • I see no reason why that would be. If you replace all `datetime.datetime` with `datetime` and all `datetime.date` with `date` after doing the imports as I have suggested, there will be no errors with the classes in the datetime module working together. – jorf.brunning Jul 05 '21 at 19:40
  • 1
    I have edited my answer to illustrate the usage of the classes with the suggested imports. If this results in errors, please put them in a code block in your question. – jorf.brunning Jul 05 '21 at 19:43
  • Do you mean edit my first post and add one code block and the new problem ? – SRP Jul 05 '21 at 20:06
  • 1
    Yes that's right. Keep adding additional info if the things the answers suggest continue to not work. It's much easier to format additional info in your question than to type stuff in comments. – jorf.brunning Jul 05 '21 at 20:15
  • 1
    I have edited my answer to illustrate that both importing the classes from the datetime module OR using the datetime module itself both work. They are equivalent. – jorf.brunning Jul 05 '21 at 20:16
  • I wil check your edit, thanks. But did you receive a notification if i edit my first post ? – SRP Jul 05 '21 at 20:50
  • Yes, if I look at the "activity" tab on my profile, I can see that there are new actions on your question, including the edits you have made :) – jorf.brunning Jul 05 '21 at 22:53
  • Thx, i'm new on this site, i did not know i have to edit my first post ! – SRP Jul 05 '21 at 23:09