I am wanting to take user input of date1 and date2 and calculate the difference to determine how many weeks are in between. My entire program is below. The example dates I'm using are:
date1 = 2023-03-15
date2 = 2022-11-09
Output is Number of weeks: 18
-- which is correct.
My 1st question that I need help in clarifying is why do I need the .days
after the days = abs(date2-date1).days
? I have searched for many hours via Google, stackoverflow, Youtube and Python docs https://docs.python.org/3.9/library/datetime.html?highlight=datetime#module-datetime. I'm pretty new to Python and reading the docs sometimes trips me up, so please forgive if it's in there -- I've struggled reading through some of it. Why is the .days
needed? I know that if I remove .days
, the output is: Number of weeks: 18 days, 0:00:00
. Where is the documentation on needing the .days
listed in the datetime module docs??? Can someone help me understand this please?
My 2nd question is why do I get Number of weeks: 0
when I change .days
to .seconds
? (this is when I was testing things and comment out the weeks = days//7
and print out days
) The one part in the docs that I think addresses this the following: https://docs.python.org/3.9/library/datetime.html?highlight=datetime#module-datetime:~:text=the given year.-,Supported operations:,!=. The latter cases return False or True, respectively.,-In Boolean contexts.... and if this is correct, am I reading it correctly that if the difference in dates are to be determined, only "days" are returned, and thus no seconds or microseconds?
Thank you for your help! Code below:
#Find the number of weeks between two given dates
from datetime import datetime
#User input for 1st date in YYYY-MM-DD format
date1 = input("Enter 1st date in YYYY-MM-DD format: ")
date1 = datetime.strptime(date1, "%Y-%m-%d")
#User input for 2nd date in YYYY-MM-DD format
date2 = input("Enter 2nd date in YYYY-MM-DD format: ")
date2 = datetime.strptime(date2, "%Y-%m-%d")
#Calculate the weeks between the 2 given dates
days = abs(date2-date1).days
weeks = days//7
print("Number of weeks: ", weeks)
Output-correct answer with .days
included:
Enter 1st date in YYYY-MM-DD format: 2023-03-15
Enter 2nd date in YYYY-MM-DD format: 2022-11-09
Number of weeks: 18
Output-with no .days
added:
Enter 1st date in YYYY-MM-DD format: 2023-03-15
Enter 2nd date in YYYY-MM-DD format: 2022-11-09
Number of weeks: 18 days, 0:00:00
Output-(regarding 2nd question with the .seconds
put in place of .days
:
Enter 1st date in YYYY-MM-DD format: 2023-03-15
Enter 2nd date in YYYY-MM-DD format: 2022-11-09
Number of weeks: 0
CodePudding user response:
Subtracting two datetime.datetime
objects returns a datetime.timedelta
object:
>>> date1 = datetime.strptime('2023-03-15', "%Y-%m-%d")
>>> date2 = datetime.strptime('2022-11-09', "%Y-%m-%d")
>>> date2-date1
datetime.timedelta(days=-126)
>>>
From the docs:
Only days, seconds and microseconds are stored internally. Arguments are converted to those units:
A millisecond is converted to 1000 microseconds.
A minute is converted to 60 seconds.
An hour is converted to 3600 seconds.
A week is converted to 7 days.
Here is some example usage of datetime.timedelta
objects. So for your second question, I believe that you're right; for the difference between two days, there are no .seconds
, as it is strictly a difference of days. For .seconds
to be nonzero, you'd have to have some component of the difference that is larger than a 1,000,000 microseconds but smaller than 86,400 seconds, I suppose.
CodePudding user response:
TL;DR: The answer to both of your questions is "because that is a property of the datetime.timedelta
class."
More fully, the date1 and date2 objects you create in your code are both instances of the datetime.datetime
class. The -
operation between them makes a timedelta object.
- Why is the
.days
needed to avoid printing ", 0:00:00"?
By default all the date information in the timedelta object you created with the operation abs(date2-date1)
is printed (including seconds and microseconds, even after modifying it with the //7
operation). When you use the .
operator, you access the days
attribute of the timedelta object, and only that attribute's value is used.
- Why do I get "Number of weeks: 0" when I change
.days
to.seconds
?
The value of the seconds
attribute of the timedelta object you created with the operation abs(date2-date1)
is integer 0
.
See below:
>>> from datetime import datetime
>>> date1 = "2023-03-15"
>>> date1, type(date1)
('2023-03-15', <class 'str'>)
>>> date1 = datetime.strptime(date1, "%Y-%m-%d")
>>> date1, type(date1)
(datetime.datetime(2023, 3, 15, 0, 0), <class 'datetime.datetime'>)
>>> date2 = "2022-11-09"
>>> date2, type(date2)
('2022-11-09', <class 'str'>)
>>> date2 = datetime.strptime(date2, "%Y-%m-%d")
>>> date2, type(date2)
(datetime.datetime(2022, 11, 9, 0, 0), <class 'datetime.datetime'>)
>>> abs(date2-date1), type(abs(date2-date1))
(datetime.timedelta(days=126), <class 'datetime.timedelta'>)
>>> abs(date2-date1).days, type(abs(date2-date1).days)
(126, <class 'int'>)
>>> abs(date2-date1).seconds, type(abs(date2-date1).seconds)
(0, <class 'int'>)
See also: this discussion.
CodePudding user response:
To be precise you calculate difference in 7 days intervals, but the week is actualy a time period which starts on Monday (or Sunday) and ends on Sunday (or Monday). So the difference between 2022-10-01 (Sat) and 2022-10-04 (Tue) in weeks of year is 1, but in days is 3 (0 7days intervals in your case).
So if you need to find the distance between two dates in weeks of year you have to take account of the weekdays:
from datetime import date
d1 = date(2022,10,18)
d2 = date(2022,10,5)
w1 = d1.weekday()
w2 = d2.weekday()
# dfference in weeks of year = 2
((d1-d2).days - (w1-w2))/7 # 2.0
# difference in days = 13
d1-d2 # datetime.timedelta(days=13)