I asked a similar question earlier and got some great feedback. I combined several answers to arrive at a solution, but it seems highly inefficient. I'm looking for a better way to get the total number of days between a variable (ts) and today in the form of an integer.
My Code:
import datetime
ts = '2015-03-01T17:09:00.000+0000'
ts = ts[:10]
f = '%Y-%m-%d'
date_from_sql = datetime.datetime.strptime(ts, f)
now = datetime.datetime.now()
now = str(now)
now = now[:10]
now = datetime.datetime.strptime(str(now), f)
delta = date_from_sql - now
print delta.total_seconds()/(3600*24)
Output:
67.0
delta.total_seconds()/(3600*24) is not needed, just get use .days
from datetime import datetime
now = datetime.now()
ts = '2015-03-01T17:09:00.000+0000'
ts = ts[:10]
f = '%Y-%m-%d'
date_from_sql = datetime.strptime(ts, f)
print(date_from_sql - now).days
If you dont want to take the time into account just use dates:
now = datetime.now().date()
ts = '2015-03-01T17:09:00.000+0000'
ts = ts[:10]
f = '%Y-%m-%d'
date_from_sql = datetime.strptime(ts, f).date()
print(date_from_sql - now).days
If there is a chance the date string may be in different formats you might want dateutil:
from dateutil import parser
now = datetime.now().date()
ts = '2015-03-01T17:09:00.000+0000'
ts = parser.parse(ts).date()
print(ts - now).days
#Padraic, yes agree, My solution also same,
from datetime import datetime
ts = '2015-03-01T17:09:00.000+0000'
print "days:-", (datetime.strptime(ts[:10], '%Y-%m-%d').date() - datetime.now().date()).days
If you don't care about the time of the day (and timezones) i.e., the result has a day resolution; you could use datetime.date class and .toordinal() method to get the number of days:
from datetime import date
ts = '2015-03-01T17:09:00.000+0000'
date_from_sql = date(*map(int, ts[:10].split('-')))
print(date_from_sql.toordinal() - date.today().toordinal())
# -> 66
Related
I'm stuck trying to figure out what is wrong with my for loop. Why is this appending the same UNIX timestamp in all of the UNIX dates variable?
now = datetime.datetime.today()
dates = []
for x in range(7):
d = now - timedelta(days=x)
dates.append(d.strftime("%Y/%m/%d"))
print(dates)
unixdates = []
for date in dates:
e = time.mktime(datetime.datetime.strptime(datetime.date.today().strftime("%m/%d/%Y"), '%m/%d/%Y').timetuple())
unixdates.append(e)
print(unixdates)
Here is the output:
['2021/11/03', '2021/11/02', '2021/11/01', '2021/10/31', '2021/10/30', '2021/10/29', '2021/10/28']
[1635912000.0, 1635912000.0, 1635912000.0, 1635912000.0, 1635912000.0, 1635912000.0, 1635912000.0]
because you use the same date over and over again which will always give the same UNIX time (datetime.date.today(), with datetime being the datetime module here).
simplify your code by using the datetime.timestamp method to get UNIX time:
from datetime import datetime, timedelta
today = datetime.now().date()
dates, unixdates = [], []
for x in range(7):
d = today - timedelta(days=x)
dates.append(d.strftime("%Y/%m/%d"))
unixdates.append(datetime.combine(d, datetime.min.time()).timestamp())
print(dates)
print(unixdates) # my machine is on UTC+1
# ['2021/11/03', '2021/11/02', '2021/11/01', '2021/10/31', '2021/10/30', '2021/10/29', '2021/10/28']
# [1635894000.0, 1635807600.0, 1635721200.0, 1635631200.0, 1635544800.0, 1635458400.0, 1635372000.0]
Also notice that you use naive datetime here, which will assume local time if you don't set the tz argument, e.g.
today = datetime.now(timezone.utc)
to get UTC.
From what I've seen this should be working even if it's not the prettiest. I've tried plenty of things but doesn't seem to work with anything and best I've been able to do is change the error message lol.
try:
date = dt.datetime.now()
d1 = date - timedelta(days=1)
d1.strftime('%Y%m%d')
url = 'http://regsho.finra.org/FNQCshvol' + d1 + '.txt'
Try the following:
from datetime import timedelta
import datetime as dt
date = dt.datetime.now()
d1 = date - timedelta(days=1)
d1 = d1.strftime('%Y%m%d') # I changed this line
url = 'http://regsho.finra.org/FNQCshvol' + d1 + '.txt'
strftime() returns the string, it does not convert the date itself to a string.
I modified your code a little. There were a couple of mistake in it and it wasn't running.
The main problem you were running into is you were trying to concatenate a string with a datetime object. You applied the strftime correctly but you didn't save the string. That string you can concatenate with another string.
import datetime as dt
date = dt.datetime.now()
d1 = date - dt.timedelta(days=1)
d1_string = d1.strftime('%Y%m%d')
url = 'http://regsho.finra.org/FNQCshvol{timestamp}.txt'.format(timestamp=d1_string)
In your code you don't assign result of datetime.strftime() to a variable. Solution is simple:
from datetime import datetime, timedelta
current_date = datetime.now() # store current date and time
required_date = current_date - timedelta(days=1) # substitute 1 day
str_date = required_date.strftime('%Y%m%d') # apply formatting
url = f'http://regsho.finra.org/FNQCshvol{str_date}.txt'
You can also do it in one line (which makes code much less readable):
url = f"http://regsho.finra.org/FNQCshvol{(datetime.now() - timedelta(days=1)).strftime('%Y%m%d')}.txt"
I'm looking to compare a list of dates with todays date and would like to return the closest one. Ive had various ideas on it but they are seem very convoluted and involve scoring based on how many days diff and taking the smallest diff. But I have no clue how to do this simply any pointers would be appreciated.
import datetime
import re
date_list = ['2019-02-10', '2018-01-13', '2019-02-8',]
now = datetime.date.today()
for date_ in date_list:
match = re.match('.*(\d{4})-(\d{2})-(\d{2}).*', date_)
if match:
year = match.group(1)
month = match.group(2)
day = match.group(3)
delta = now - datetime.date(int(year), int(month), int(day))
print(delta)
As I was Waiting EDIT
So I solved this using the below
import datetime
import re
date_list = ['2019-02-10', '2018-01-13', '2019-02-8',]
now = datetime.date.today()
for date_ in date_list:
match = re.match('.*(\d{4})-(\d{2})-(\d{2}).*', date_)
if match:
year = match.group(1)
month = match.group(2)
day = match.group(3)
delta = now - datetime.date(int(year), int(month), int(day))
dates_range.append(int(delta.days))
days = min(s for s in dates_range)
convert each string into a datetime.date object, then just subtract and get the smallest difference
import datetime
import re
date_list = ['2019-02-10', '2018-01-13', '2019-02-8',]
now = datetime.date.today()
date_list_converted = [datetime.datetime.strptime(each_date, "%Y-%m-%d").date() for each_date in date_list]
differences = [abs(now - each_date) for each_date in date_list_converted]
minimum = min(differences)
closest_date = date_list[differences.index(minimum)]
This converts the strings to a datetime object, then subracts the current date from that and returns the date with the corresponding lowest absolute difference:
import datetime
import re
date_list = ['2019-02-10', '2018-01-13', '2019-02-8',]
numPattern = re.compile("[0-9]+")
def getclosest(dates):
global numPattern
now = datetime.date.today()
diffs = []
for day in date_list:
year, month, day = [int(i) for i in re.findall(numPattern, day)]
currcheck = datetime.date(year, month, day)
diffs.append(abs(now - currcheck))
return dates[diffs.index(min(diffs))]
It's by no means the most efficient, but it's semi-elegant and works.
Using inbuilts
Python's inbuilt datetime module has the functionality to do what you desire.
Let's first take your list of dates and convert it into a list of datetime objects:
from datetime import datetime
date_list = ['2019-02-10', '2018-01-13', '2019-02-8']
datetime_list = [datetime.strptime(date, "%Y-%m-%d") for date in date_list]
Once we have this we can find the difference between those dates and today's date.
today = datetime.today()
date_diffs = [abs(date - today) for date in datetime_list]
Excellent, date_diffs is now a list of datetime.timedelta objects. All that is left is to find the minimum and find which date this represents.
To find the minimum difference it is simple enough to use min(date_diffs), however, we then want to use this minimum to extract the corresponding closest date. This can be achieved as:
closest_date = date_list[date_diffs.index(min(date_diffs))]
With pandas
If performance is an issue, it may be worth investigating a pandas implementation. Using pandas we can convert your dates to a pandas dataframe:
from datetime import datetime
import pandas as pd
date_list = ['2019-02-10', '2018-01-13', '2019-02-8']
date_df = pd.to_datetime(date_list)
Finally, as in the method using inbuilts we find the differences in the dates and use it to extract the closest date to today.
today = datetime.today()
date_diffs = abs(today - date_df)
closest_date = date_list[date_diffs.argmin()]
The advantage of this method is that we've removed the for loops and so I'd expect this method to be more efficient for large numbers of dates
one fast and simple way will be to use bisect algorithm, especially if your date_list is significantly big :
import datetime
from bisect import bisect_left
FMT = '%Y-%m-%d'
date_list = ['2019-02-10', '2018-01-13', '2019-02-8', '2019-02-12']
date_list.sort()
def closest_day_to_now(days):
"""
Return the closest day form an ordered list of days
"""
now = datetime.datetime.now()
left_closest_day_index = bisect_left(days, now.strftime(FMT))
# check if there is one greater value
if len(days) - 1 > left_closest_day_index:
right_closest_day_index = left_closest_day_index + 1
right_day = datetime.datetime.strptime(days[right_closest_day_index], FMT)
left_day = datetime.datetime.strptime(days[left_closest_day_index], FMT)
closest_day_index = right_closest_day_index if abs(right_day - now) < abs(left_day - now) \
else left_closest_day_index
else:
closest_day_index = left_closest_day_index
return days[closest_day_index]
print(closest_day_to_now(date_list))
I need to calculate difference between time (and if it exceed 24 hours then days)
Like:
from datetime import datetime
from time import strftime
s1 = '24:11:2014:14:28:42'
s2 = datetime.now().strftime("%d:%m:%Y:%H:%M:%S")
FMT = '%d:%m:%Y:%H:%M:%S'
timedelta = datetime.now.strftime(s2,FMT) - datetime.now.strftime(s1,FMT)
print (timedelta)
But this is not detecting more than 24 hours, If found this code which can detect the days:
from datetime import datetime
date_format = "%d/%m/%Y %H%M%S"
a = datetime.strptime('22/10/2014 090000', date_format)
b = datetime.strptime('25/11/2014 100000', date_format)
delta = b - a
print (delta.days)
What I want is something like this in return: "2 days 03:35:00 HH:MM:SS" in return"
The timedelta you are getting from b - a already has all the information you need, have a look at https://docs.python.org/2/library/datetime.html#datetime.timedelta.
I have an input that is given in %I:%M%p (ex. "6:02PM").
I'm trying to input into this code to find the difference between now and then:
import datetime
now = datetime.now()
then = "6:02PM"
tdelta = now - then
import datetime as dt
now = dt.datetime.now()
then = dt.datetime.combine(now, dt.datetime.strptime("6:02PM", "%I:%M%p").time())
print(then)
# 2012-08-26 18:02:00
tdelta = now - then
print(tdelta)
# -1 day, 20:53:25.190721