Using the time functions - python

I have a small question. I have an array that saves dates in the following format.
'01/02/20|07/02/20'
It is saved as a string, which uses the start date on the left side of the "|" and end date on the other side.
It is only the end date that matters here, but is there a function or algorithm I can use to automatically calculate the difference in days and months between now.datetime and the end date (right-hand side of "|")?
Thanks, everyone

datetime.strptime is the main routine for parsing strings into datetimes. It can handle all sorts of formats, with the format determined by a format string you give it:
In [34]: from datetime import datetime
In [35]: end_date = datetime.strptime(s.split('|')[1], '%d/%m/%y')
In [36]: diff = datetime.now() - end_date
In [37]: diff
Out[37]: datetime.timedelta(days=81, seconds=81712, microseconds=14069)
In [38]: diff.days
Out[38]: 81

You might be looking for something like this.
Python datetime module is the way to go for a problem like this
import datetime
dates = '01/02/20|07/02/20'
enddate = dates.split('|')[-1]
# Use %y for 2 digits year else %Y for 4 digit year
enddate = datetime.datetime.strptime(enddate, "%d/%m/%y")
today = datetime.date.today()
print(abs(enddate.date() - today).days)
Output:
81

Related

The right way to parse date

Exist an easier way to do this kind of parse date?
I'm trying to make a filter in pandas to localize dates 3 months ago and loc the entire month too.
The code works, but I'm searching for the best way.
final_date = pd.to_datetime(f'{(datetime.today() - timedelta(days=90)).year}-{(datetime.today() - timedelta(days=90)).month}-01', dayfirst=True)
My Suggestion
This version of the code is more concise and easier to read.
It avoids using multiple calls to datetime.today() and string formatting.
import pandas as pd
from datetime import date, timedelta
# Calculate the date 90 days ago
d = date.today() - timedelta(days=90)
# Format the date as a string in the '%Y-%m-01' format
date_str = d.strftime('%Y-%m-01')
# Parse the string as a datetime object
final_date = pd.to_datetime(date_str, dayfirst=True)

Comparison between datetime and datetime64[ns] in pandas

I'm writing a program that checks an excel file and if today's date is in the excel file's date column, I parse it
I'm using:
cur_date = datetime.today()
for today's date. I'm checking if today is in the column with:
bool_val = cur_date in df['date'] #evaluates to false
I do know for a fact that today's date is in the file in question. The dtype of the series is datetime64[ns]
Also, I am only checking the date itself and not the timestamp afterwards, if that matters. I'm doing this to make the timestamp 00:00:00:
cur_date = datetime.strptime(cur_date.strftime('%Y_%m_%d'), '%Y_%m_%d')
And the type of that object after printing is datetime as well
For anyone who also stumbled across this when comparing a dataframe date to a variable date, and this did not exactly answer your question; you can use the code below.
Instead of:
self.df["date"] = pd.to_datetime(self.df["date"])
You can import datetime and then add .dt.date to the end like:
self.df["date"] = pd.to_datetime(self.df["date"]).dt.date
You can use
pd.Timestamp('today')
or
pd.to_datetime('today')
But both of those give the date and time for 'now'.
Try this instead:
pd.Timestamp('today').floor('D')
or
pd.to_datetime('today').floor('D')
You could have also passed the datetime object to pandas.to_datetime but I like the other option mroe.
pd.to_datetime(datetime.datetime.today()).floor('D')
Pandas also has a Timedelta object
pd.Timestamp('now').floor('D') + pd.Timedelta(-3, unit='D')
Or you can use the offsets module
pd.Timestamp('now').floor('D') + pd.offsets.Day(-3)
To check for membership, try one of these
cur_date in df['date'].tolist()
Or
df['date'].eq(cur_date).any()
When converting datetime64 type using pd.Timestamp() it is important to note that you should compare it to another timestamp type. (not a datetime.date type)
Convert a date to numpy.datetime64
date = '2022-11-20 00:00:00'
date64 = np.datetime64(date)
Seven days ago - timestamp type
sevenDaysAgoTs = (pd.to_datetime('today')-timedelta(days=7))
convert date64 to Timestamp and see if it was in the last 7 days
print(pd.Timestamp(pd.to_datetime(date64)) >= sevenDaysAgoTs)

String to date formatting

I have a string of the following format:
x = '2018-02-15-11'
I need to convert this to a date format. I have tried:
from datetime import date
from datetime import time
from datetime import datetime
dhs = '2018-02-15-11'
x = datetime.strptime(dhs, '%Y-%M-%d-%H')
print x
However, the output is
2018-01-15 11:02:00
I need the output in the format (as date object):
2018-01-15-11
Am I missing something here?
I think there could be a mistake on your part, you have used %Y-%M-%d-%H where %M indicates minutes, not month. But according to the look, it should be %m i.e. month.
Answering your original question, the format specifiers for strftime (datetime to string) and strptime (string to datetime) are the same. So you can use datetime.datetime.strftime('%Y-%m-%d-%H') like:
In [47]: dhs = '2018-02-15-11'
...: x = datetime.datetime.strptime(dhs, '%Y-%m-%d-%H')
...: print(x.strftime('%Y-%m-%d-%H'))
...:
2018-02-15-11
I've used %m instead of %M here. If you are really sure about this, use %M if you want.
N.B: You are getting same string you've started with.

Time difference with different time formats in Python3

Hi I have two times in slightly different formats and I need to work out the difference. The first was parsed from a ISO 8601 date using dateutil.parser
I'm not sure what I need to do to parse them into the same format, but my two dates are:
2017-05-24 15:40:00+00:00
2017-05-24 14:23:44.995015
If they were both in datetime format I could just subtract one from the other, so I need to chop the milliseconds off both (coz that's not relevant to me), and tell python the new strings are both datetimes?
Since you're already using dateutil, what's wrong with just removing the timezone (or adding it to the other) and subtracting them?
import dateutil.parser
date1 = dateutil.parser.parse("2017-05-24 15:40:00+00:00").replace(tzinfo=None)
date2 = dateutil.parser.parse("2017-05-24 14:23:44.995015")
date_delta = date1 - date2 # 1:16:15.004985
You can call replace(microsecond=0) on your dates to remove the microseconds.
You could transform the second datetime (that is a timestamp) into the first one with this code:
def convert_to_timestamp(string_date):
the_datetime = datetime.strptime(string_date.decode("utf-8"), "%Y%m%d.%H%M%S.%f")
return time.mktime(the_datetime.timetuple()) * 1e6 + the_datetime.microsecond
or:
def transformTimestamps(timestamp_):
year = timestamp_[:4]
month = timestamp_[4:6]
day = timestamp_[6:8]
hour = timestamp_[9:11]
minute = timestamp_[11:13]
second = timestamp_[13:15]
microsecond = timestamp_[16:22]
myformat = year+"-"+month+"-"+day+" +hour+":"+minute+":"+second+":"+microsecond
return datetime.strptime(myformat, '%Y-%m-%d %H:%M:%S:%f')
Then, you can calculate the difference between them.
I hope this help. Greetings!
Probably you want to use this method
datetime.strptime(date_string, format)
Also remember you can get rid of elements you do not want in your date (Like milliseconds) when you declare the specified date, as in
class datetime.datetime(year, month, day, hour=0, minute=0, second=0,
microsecond=0, tzinfo=None, *, fold=0)
For more on this topic you can always read the python docs, you can find the same information I just gave you and more here:
https://docs.python.org/3/library/datetime.html
Hope it helped.

Format Pandas datetime column as year-week [duplicate]

Please what's wrong with my code:
import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d, "%Y-W%W")
print(r)
Display "2013-01-01 00:00:00", Thanks.
A week number is not enough to generate a date; you need a day of the week as well. Add a default:
import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d + '-1', "%Y-W%W-%w")
print(r)
The -1 and -%w pattern tells the parser to pick the Monday in that week. This outputs:
2013-07-01 00:00:00
%W uses Monday as the first day of the week. While you can pick your own weekday, you may get unexpected results if you deviate from that.
See the strftime() and strptime() behaviour section in the documentation, footnote 4:
When used with the strptime() method, %U and %W are only used in calculations when the day of the week and the year are specified.
Note, if your week number is a ISO week date, you'll want to use %G-W%V-%u instead! Those directives require Python 3.6 or newer.
In Python 3.8 there is the handy datetime.date.fromisocalendar:
>>> from datetime import date
>>> date.fromisocalendar(2020, 1, 1) # (year, week, day of week)
datetime.date(2019, 12, 30, 0, 0)
In older Python versions (3.7-) the calculation can use the information from datetime.date.isocalendar to figure out the week ISO8601 compliant weeks:
from datetime import date, timedelta
def monday_of_calenderweek(year, week):
first = date(year, 1, 1)
base = 1 if first.isocalendar()[1] == 1 else 8
return first + timedelta(days=base - first.isocalendar()[2] + 7 * (week - 1))
Both works also with datetime.datetime.
To complete the other answers - if you are using ISO week numbers, this string is appropriate (to get the Monday of a given ISO week number):
import datetime
d = '2013-W26'
r = datetime.datetime.strptime(d + '-1', '%G-W%V-%u')
print(r)
%G, %V, %u are ISO equivalents of %Y, %W, %w, so this outputs:
2013-06-24 00:00:00
Availabe in Python 3.6+; from docs.
import datetime
res = datetime.datetime.strptime("2018 W30 w1", "%Y %W w%w")
print res
Adding of 1 as week day will yield exact current week start. Adding of timedelta(days=6) will gives you the week end.
datetime.datetime(2018, 7, 23)
If anyone is looking for a simple function that returns all working days (Mo-Fr) dates from a week number consider this (based on accepted answer)
import datetime
def weeknum_to_dates(weeknum):
return [datetime.datetime.strptime("2021-W"+ str(weeknum) + str(x), "%Y-W%W-%w").strftime('%d.%m.%Y') for x in range(-5,0)]
weeknum_to_dates(37)
Output:
['17.09.2021', '16.09.2021', '15.09.2021', '14.09.2021', '13.09.2021']
In case you have the yearly number of week, just add the number of weeks to the first day of the year.
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> week = 40
>>> year = 2019
>>> date = datetime.date(year,1,1)+relativedelta(weeks=+week)
>>> date
datetime.date(2019, 10, 8)
Another solution which worked for me that accepts series data as opposed to strptime only accepting single string values:
#fw_to_date
import datetime
import pandas as pd
# fw is input in format 'YYYY-WW'
# Add weekday number to string 1 = Monday
fw = fw + '-1'
# dt is output column
# Use %G-%V-%w if input is in ISO format
dt = pd.to_datetime(fw, format='%Y-%W-%w', errors='coerce')
Here's a handy function including the issue with zero-week.

Categories