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%20given%20year.-,Supported%20operations%3A,!%3D.%20The%20latter%20cases%20return%20False%20or%20True%2C%20respectively.,-In%20Boolean%20contexts.... 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
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.
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.
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)
Related
I have a dataframe with timestamp of BirthDate = 2001-10-10 11:01:04.343
How can I get an actual age?
I tried like that:
i.loc[0, "BirthDate"] = pd.to_datetime('today').normalize() - i.loc[0, "BirthDate"].normalize()
output is: 7248 days 00:00:00
but is there any better method which give me just output 19 years?
If i use:
(i.loc[0, "BirthDate"] = pd.to_datetime('today').normalize() - i.loc[0, "BirthDate"].normalize())/365
the output is:
19 days 20:34:50:958904109 and it is type <class 'pandas.timedeltas.Timedelta>
The timedelta result is wrong because you are dividing by 365 where you shouldn't. It actually means 19.86 years.
In some more detail, you are taking a value which is in years, and dividing it with 365; so now you have a result which shows 1/365 of the input duration. The proper way to get the result in years is to divide by another timedelta.
>>> from datetime import timedelta
>>> t = timedelta(days=7248)
>>> 7248/365.0
19.85753424657534
>>> print(t)
7248 days, 0:00:00
>>> t/timedelta(days=365)
19.85753424657534
>>> # years
How exactly to represent a year is not completely well-defined. You could use timedelta(days=365.2425) for the arithmetically correct length of a year, but then of course that produces odd results if you try to convert that back to a resolution where hours and minutes are important.
First, delete the last part of the timestamp and then the following python code can be applied:
from datetime import datetime, date
def calculate_age(born):
born = datetime.strptime(born, "%d/%m/%Y").date()
today = date.today()
return today.year - born.year - ((today.month, today.day) < (born.month, born.day))
df['Age'] = df['Date of birth'].apply(calculate_age)
print(df)
PaymentDate = datetime.now().timetuple().tm_yday + 7
NS_Date_Text = driver.find_element(By.ID, "custrecord_ps_inv_date_val").text
basedate = datetime.strptime(NS_Date_Text, '%m/%d/%Y')
basedate1 = datetime.timetuple(basedate).tm_yday
DaysUntilPayment = PaymentDate - basedate1
This code works so far for the year of 2019. But, I am not sure how to account for 2020 or 2018
So, I am converting the current date to the number of day in the year (January 1 would be 1 and December 31 would be 365/366) then adding 7 to that number. This is the Payment Date.
Then, I am finding a date on the webpage(BaseDate) and converting that number to the day of the year.
Then subtracting those two numbers.
I am not sure how well it's going to work if the current date is: January 10, 2020 (10th day) + 7 = day 17. But the base date is 12/28/2019 (362nd day).
The number I will get would be 345 and that's way too far ahead, while I need the number(DaysUntilPayment) to be 20.
I hope I was able to explain this well. Please lmk if you have any questions!
You are making this way more complicated than it needs to be. Python's datetime.date() objects know how to handle deltas themselves; if you subtract two date() objects you get a timedelta() instance, which has a .days attribute.
Next, you can create your own timedelta() object to add 7 days to 'today':
from datetime import date, timedelta
# 7 days from today
payment_date = date.today() + timedelta(days=7)
# find base date on the webpage
ns_date_text = driver.find_element(By.ID, "custrecord_ps_inv_date_val").text
basedate = datetime.strptime(ns_date_text, '%m/%d/%Y').date()
# calculate the difference in days between these two dates
# date - date = timedelta, so take the .days attribute from that result
days_until_payment = (payment_date - basedate).days
Note that I used only the date component of the datetime.strptime() result. You can do all this with datetime objects too, but then you may have to worry about timezones and such, and it's just easier not to have to do that.
These operations take care of details such as handling years, and more importantly, handling leap years:
>>> from datetime import date, datetime, timedelta
>>> payment_date = date(2020, 2, 22) + timedelta(days=7)
>>> payment_date # this is February 29th, a leap day!
datetime.date(2020, 2, 29)
>>> basedate = datetime.strptime("12/31/2019", '%m/%d/%Y').date # last day of 2019
>>> payment_date - basedate
datetime.timedelta(days=60)
>>> (payment_date - basedate).days # February 29th is 60 days later
60
For further details, see the datetime.date documentation, which has a Supported operations section, with:
date2 = date1 + timedelta
date2 is timedelta.days days removed from date1
timedelta = date1 - date2
This is exact, and cannot overflow. timedelta.seconds and timedelta.microseconds are 0, and date2 + timedelta == date1 after.
I have a dataframe named 'train' with column ID which represents 'date' in a very unusual manner. For e.g. certain entry in ID:
For example, the value of ID 2013043002 represents the date 30/04/2013
02:00:00
First 4 digits represents year, subsequent 2 digits represent month and day respectively. And last two digits represent time.
So I want to convert this into proper date time format to perform time series analysis.
Use to_datetime with parameter format - check http://strftime.org/:
df = pd.DataFrame({'ID':[2013043002,2013043002]})
df['ID'] = pd.to_datetime(df['ID'], format='%Y%m%d%H')
print(df)
ID
0 2013-04-30 02:00:00
1 2013-04-30 02:00:00
print(df['ID'].dtype)
datetime64[ns]
Use datetime for date time manipulations.
datetime.strptime(d,"%Y%m%d%H").strftime("%d/%m/%Y %H:%M:%S")
First, if you are gonna have ALWAYS the same input style in the Id you could play with string or digit formating ...
Id = 2013043002
Year = Id[0:3]
Month = Id[4:5]
Day = Id[6:7]
Time= Id[-2:-1]
DateFormat = "{}-{}-{}".format(Day,Month,Year)
TimeFormar = "%d:00:00"%Time
Print (DateFormat)
Output:
04:30:2013
Then with this you could wrap it into a function and pass every Ids by loops and manage your data.
Of course, if you dont know your previous ID incomming format you should used the other time module options, and manage the string formating to show it in the order you want.
By using the module datetime you can do that easily with the function strptime :
my_date = datetime.datetime.strptime(ID, "%Y%m%d%H")
"%Y%m%d%H"
is the format of your date : %Y is the year, %m is the month(0 padded), %d is the day(0 padded) and %H is the hour(24H, 0 padded). See http://strftime.org/ for more.
I'm working on a simple program to tell an individual how long they have been alive.
I know how to get the current date, and get their birthday. The only problem is I have no way of subtracting the two, I know a way of subtracting two dates, but unfortunately it does not include hours, minutes, or seconds.
I am looking for a method that can subtract two dates and return the difference down to the second, not merely the day.
from datetime import datetime
birthday = datetime(1988, 2, 19, 12, 0, 0)
diff = datetime.now() - birthday
print diff
# 8954 days, 7:03:45.765329
Use UTC time otherwise age in seconds can go backwards during DST transition:
from datetime import datetime
born = datetime(1981, 12, 2) # provide UTC time
age = datetime.utcnow() - born
print(age.total_seconds())
You also can't use local time if your program runs on a computer that is in a different place (timezone) from where a person was born or if the time rules had changed in this place since birthday. It might introduce several hours error.
If you want to take into account leap seconds then the task becomes almost impossible.
When substracting two datetime objects you will get a new datetime.timedelta object.
from datetime import datetime
x = datetime.now()
y = datetime.now()
delta = y - x
It will give you the time difference with resolution to microsencods.
For more information take a look at the official documentation.
Create a datetime.datetime from your date:
datetime.datetime.combine(birthdate, datetime.time())
Now you can subtract it from datetime.datetime.now().
>>> from datetime import date, datetime, time
>>> bday = date(1973, 4, 1)
>>> datetime.now() - datetime.combine(bday, time())
datetime.timedelta(14392, 4021, 789383)
>>> print datetime.now() - datetime.combine(bday, time())
14392 days, 1:08:13.593813
import datetime
born = datetime.date(2002, 10, 31)
today = datetime.date.today()
age = today - born
print(age.total_seconds())
Output: 463363200.0
Since DateTime.DateTime is an immutable type method like these always produce a new object the difference of two DateTime object produces a DateTime.timedelta type:
from datetime import date,datetime,time,timedelta
dt=datetime.now()
print(dt)
dt2=datetime(1997,7,7,22,30)
print(dt2)
delta=dt-dt2
print(delta)
print(int(delta.days)//365)
print(abs(12-(dt2.month-dt.month)))
print(abs(dt.day))
The output timedelta(8747,23:48:42.94) or what ever will be days when u test the code indicates that the time delta encodes an offset of 8747 days and 23hour and 48 minute ...
The Output
2021-06-19 22:27:36.383761
1997-07-07 22:30:00
8747 days, 23:57:36.383761
23 Year
11 Month
19 Day
I have a .txt file data-set like this with the date column of interest:
1181206,3560076,2,01/03/2010,46,45,M,F
2754630,2831844,1,03/03/2010,56,50,M,F
3701022,3536017,1,04/03/2010,40,38,M,F
3786132,3776706,2,22/03/2010,54,48,M,F
1430789,3723506,1,04/05/2010,55,43,F,M
2824581,3091019,2,23/06/2010,59,58,M,F
4797641,4766769,1,04/08/2010,53,49,M,F
I want to work out the number of days between each date and 01/03/2010 and replace the date with the days offset {0, 2, 3, 21...} yielding an output like this:
1181206,3560076,2,0,46,45,M,F
2754630,2831844,1,2,56,50,M,F
3701022,3536017,1,3,40,38,M,F
3786132,3776706,2,21,54,48,M,F
1430789,3723506,1,64,55,43,F,M
2824581,3091019,2,114,59,58,M,F
4797641,4766769,1,156,53,49,M,F
I've been trying for ages and its getting really frustrating. I've tried converting to datetime using the datetime.datetime.strptime( '01/03/2010', "%d/%m/%Y").date() method and then subtracting the two dates but it gives me an output of e.g. '3 days, 0:00:00' but I can't seem to get an output of only the number!
The difference between two dates is a timedelta. Any timedelta instance has days attribute that is an integer value you want.
This is fairly simple. Using the code you gave:
date1 = datetime.datetime.strptime('01/03/2010', '%d/%m/%Y').date()
date2 = datetime.datetime.strptime('04/03/2010', '%d/%m/%Y').date()
You get two datetime objects.
(date2-date1)
will give you the time delta. The mistake you're making is to convert that timedelta to a string. timedelta objects have a days attribute. Therefore, you can get the number of days using it:
(date2-date1).days
This generates the desired output.
Using your input (a bit verbose...)
#!/usr/bin/env python
import datetime
with open('input') as fd:
d_first = datetime.date(2010, 03, 01)
for line in fd:
date=line.split(',')[3]
day, month, year= date.split(r'/')
d = datetime.date(int(year), int(month), int(day))
diff=d - d_first
print diff.days
Gives
0
2
3
21
64
114
156
Have a look at pleac, a lot of date-example there using python.