I have the following time string
12:45pm - 01:00pm Today, September 7
and I want to convert this string into UTC datetime in the following format
2016-09-07T22:45:00Z
How can I achieve this in python?
developed the script to achieve it.
def appointment_time_string(time_str):
import datetime
a = time_str.split()[0]
in_time = datetime.datetime.strptime(a,'%I:%M%p')
start_time = str(datetime.datetime.strftime(in_time, "%H:%M:%S")) + "Z"
if time_str.split()[3] == 'Today,':
start_date = datetime.datetime.utcnow().strftime("%Y-%m-%dT")
elif time_str.split()[3] == 'Tomorrow,':
today = datetime.date.today( )
start_date = (today + datetime.timedelta(days=1)).strftime("%Y-%m-%dT")
appointment_time = str(start_date) + str(start_time)
return appointment_time
Related
I tried to develop a Python function that determines the difference between two datetime objects. I need an algorithm that calculates the number of hours per day. Is there a built-in function for this?
from datetime import datetime, timedelta, date
def getHoursByDay(dateA, dateB):
...
dateA = datetime.strptime('2018-09-01 09:00:00', '%Y-%m-%d %H:%M:%S')
dateB = datetime.strptime('2018-09-03 11:30:00', '%Y-%m-%d %H:%M:%S')
hours = getHoursByDay(dateA, dateB)
print hours
# {
# '2018-09-01': 15,
# '2018-09-02': 24,
# '2018-09-03': 11.5,
# }
There is no built-in function, though it is very simple to build one.
from datetime import datetime, timedelta, time
def deltaByDay(dateA, dateB):
dateAstart = datetime.combine(dateA, time())
dateBstart = datetime.combine(dateB, time())
result = {}
oneday = timedelta(1)
if dateAstart == dateBstart:
result[dateA.date()] = dateB - dateA
else:
nextDate = dateAstart + oneday
result[dateA.date()] = nextDate - dateA
while nextDate < dateBstart:
result[nextDate.date()] = oneday
nextDate += oneday
result[dateB.date()] = dateB - dateBstart
return result
def deltaToHours(delta, ndigits=None):
return delta.days * 24 + round(delta.seconds / 3600.0, ndigits)
dateA = datetime.strptime('2018-09-01 09:00:00', '%Y-%m-%d %H:%M:%S')
dateB = datetime.strptime('2018-09-03 11:30:00', '%Y-%m-%d %H:%M:%S')
deltas = deltaByDay(dateA, dateB);
output = {k.strftime('%Y-%m-%d'): deltaToHours(v, 1) for k, v in deltas.items()}
print(output)
# => {'2018-09-01': 15.0, '2018-09-02': 24.0, '2018-09-03': 11.5}
The built in timedelta functions would be able to get you the total days, and the remaining hours difference. If you want the output specifically in that dictionary format posted you would have to create it manually like this:
from datetime import datetime, time, timedelta
def getHoursByDay(dateA, dateB):
if dateA.strftime("%Y-%m-%d") == dateB.strftime("%Y-%m-%d"):
return {dateA.strftime("%Y-%m-%d"): abs(b-a).seconds / 3600}
result = {}
delta = dateB - dateA
tomorrow = dateA + timedelta(days=1)
day1 = datetime.combine(tomorrow, time.min) - dateA
result[dateA.strftime("%Y-%m-%d")] = day1.seconds / 3600
for day in range(1, delta.days):
result[(dateA + timedelta(days=day)).strftime("%Y-%m-%d")] = 24
priorday = dateB - timedelta(days1)
lastday = dateB - datetime.combine(priorday, time.min)
result[dateB.strftime("%Y-%m-%d")] = lastday.seconds / 3600
return result
Essentially this function calculates the first day and the last day values, then populates all the days in between with 24.
There is a kind of simple way to do this.
hours = (dateA - dateB).hours
I've used this to caclulate a difference in days.
https://docs.python.org/2/library/datetime.html#datetime.timedelta
What I am trying to do is see if date is in 1 week from currdate
from datetime import datetime, timedelta
import yagmail
year = datetime.now().year
month = datetime.now().month
day = datetime.now().day
currdate = '{}-{}-{}'.format(year, month, day)
currdate = datetime.strptime(currdate, '%Y-%m-%d')
date = '2018-04-01'
days = currdate - timedelta(int(date[-2:]))
days = str(days)
print(days)
if days[8:11] == '07':
yag = yagmail.SMTP("##########gmail.com", "######")
content = ['One Of Your Homework\'s Is Due In 1 Week!']
yag.send('###########gmail.com', 'Homework Due Soon!', content)
else:
print('It Isn\'t')
But it prints:
2018-04-07 00:00:00
It Isnt't
And I'm not sure why. Because days[8:11] is 07.
It is not 07. It's 07 (note the trailing space).
The following change will work:
if int(days[8:11]) == 7:
I'd create a function that you pass the date as a string. Something like this:
import datetime
def check_if_less_than_seven_days(x):
d = datetime.datetime.strptime(x, "%Y-%m-%d") # Add .date() if hour doesn't matter
now = datetime.datetime.now() # Add .date() if hour doesn't matter
return (d - now).days < 7
if check_if_less_than_seven_days("2018-04-18"):
print('Do something') # This will not print
if check_if_less_than_seven_days("2018-04-14"):
print('Do something') # This will print
Will print:
'Do something'
I suppose your first line when you initiate datetime.now() three times is just for testing purposes but dont do this as it could end up over different days (if you run this exactly at the milliseconds around midnight..) this will work better in that regard.
now = datetime.datetime.now()
year = now.year
month = now.month
day = now.day
Anyway, read up on datetime timedelta. Just make you logic around that.
https://docs.python.org/3/library/datetime.html#timedelta-objects
import datetime
test_date_string = "2018-04-10"
d = datetime.datetime.strptime(test_date_string, "%Y-%m-%d")
now = datetime.datetime.now()
delta = d - now
elif delta.days < 7:
print("You have less then 7 days to go")
For days[8:11] you get the following output
>>> days[8:11]
'08 '
So you should use days[8:10]=='07' in case you want to use the same method,as it wont have extra space at the end.
>>> days[8:10]
'08'
so you should use
if days[8:10] == '07':
I'm working on my python script to get the strings from the button objects so I can use it to set the date formats with the time that I got from the strings to store it in the lists. When I get the strings from the button objects, I want to set the date for each string, example: 29/08/2017 11:30PM, 30/08/2017 12:00AM, 30/08/2017 12:30AM.
When I try this:
if day_date >= 0 and day_date <= 6:
if epg_time3 == '12:00AM':
if day_date > 0:
currentday = datetime.datetime.now() + datetime.timedelta(days = 0)
nextday = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
if currentday != nextday:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
elif currentday == nextday:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day - 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day - 1)
It will show the output:
self.epg_time_1
['29/08/2017 11:00PM']
self.epg_time_2
['29/08/2017 11:30PM']
self.epg_time_3
['29/08/2017 12:00AM']
When I'm calling the EPG_Times function again, it will show the output like this:
self.epg_time_1
['30/08/2017 11:00PM']
self.epg_time_2
['30/08/2017 11:30PM']
self.epg_time_3
['30/08/2017 12:00AM']
It should be:
self.epg_time_1
['30/08/2017 11:00PM']
self.epg_time_2
['30/08/2017 11:30PM']
self.epg_time_3
['31/08/2017 12:00AM']
As you can see the time 12:00AM is the next day so I want to set it to 31 not 30. I have changed from days = self.program_day + 1 to days = self.program_day - 1, but when the strings show 11:00PM, 11:30PM and 12:00AM from the variables epg_time_1, epg_time_2 and epg_time_3, it will show the output like this:
self.epg_time_1
['30/08/2017 11:00PM']
self.epg_time_2
['30/08/2017 11:30PM']
self.epg_time_3
['30/08/2017 12:00AM']
Here is the full code:
self.program_day = list()
def EPG_Times(self):
self.epg_time_1 = list()
self.epg_time_2 = list()
self.epg_time_3 = list()
epg_time1 = str(self.getControl(344).getLabel())
epg_time2 = str(self.getControl(345).getLabel())
epg_time3 = str(self.getControl(346).getLabel())
day_date = self.program_day
day = ''
month = ''
year = ''
if day_date >= 0 and day_date <= 6:
if epg_time3 == '12:00AM':
if day_date == 0:
if epg_time1 == '12:00AM':
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
else:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
else:
currentday = datetime.datetime.now() + datetime.timedelta(days = 0)
nextday = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
if currentday != nextday:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
elif currentday == nextday:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day - 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day - 1)
epg1_day = epg_time_1.strftime("%d")
epg1_month = epg_time_1.strftime("%m")
epg1_year = epg_time_1.strftime("%Y")
epg2_day = epg_time_2.strftime("%d")
epg2_month = epg_time_2.strftime("%m")
epg2_year = epg_time_2.strftime("%Y")
epg3_day = epg_time_2.strftime("%d")
epg3_month = epg_time_2.strftime("%m")
epg3_year = epg_time_2.strftime("%Y")
half_hour = str(epg1_day + "/" + epg1_month + "/" + epg1_year + " " + epg_time1)
one_hour = str(epg2_day + "/" + epg2_month + "/" + epg2_year + " " + epg_time2)
one_hour_half = str(epg3_day + "/" + epg3_month + "/" + epg3_year + " " + epg_time3)
#Store the times and date in the list....
self.epg_time_1.append(half_hour)
self.epg_time_2.append(one_hour)
self.epg_time_3.append(one_hour_half)
What I'm expected the code to do is to change to the previous day date for each string that I get from the button objects when I call the EPG_time(self) function. If the epg_time_1 and epg_time_2 show the strings 11:00PM and 11:30PM, I want to set the time and date to 29/08/2017 11:00PM for epg_time_1 and 29/08/2017 11:30PM for the epg_time_2. If the epg_time_3 show the string 12:00AM then I want to add it to the next day date with the time 30/08/2017 12:00AM.
In the next 24 hours if the epg_time_1 and epg_time_2 show the strings 11:00PM and 11:30PM, I want to set the time and date to 30/08/2017 11:00PM for epg_time_1 and 30/08/2017 11:30PM for the epg_time_2. If the epg_time_3 show the string 12:00AM then I want to set to the next day date with the time 1/09/2017 12:00AM
If the epg_time_1 and epg_time_2 show the strings 11:30PM and 12:00AM, I want to change to the previous date for epg_time_1 which it is 29/08/2017 11:30PM and 30/08/2017 12:00AM. It will be depends on the time and date when I have stored the strings in the list.
Can you please tell me an example how I could use to change the date to the previous date and add to the next day date using in python?
There's a lot of text in your question that makes it hard to pinpoint the issue exactly. However, it appears to boil down to adding a variable number of days to a particular date and ensuring that the month is also updated (if necessary).
You should use the datetime.datetime.strptime() method to convert your dates to datetimes, which makes it trivial to add timedelta (you use both timedelta and strftime but miss this crucial method) and then just convert back to a string.
import datetime as dt
def add_days(datelist, days_to_add):
# Convert the strings to datetime objects
datelist = [dt.datetime.strptime(item, '%d/%m/%Y %I:%M%p')
for item in datelist]
# Add a variable number of days (can be negative) to the datetimes
mod_dates = [item + dt.timedelta(days=days_to_add) for item in datelist]
# Convert back to strings
str_dates = [dt.datetime.strftime(item, '%d/%m/%Y %I:%M%p')
for item in mod_dates]
return str_dates
# This is the list right at the top of your question
a = ['29/08/2017 11:30PM', '30/08/2017 12:00AM', '30/08/2017 12:30AM']
print("Start:")
print(a)
b = add_days(a, 1)
print("After 1 call:")
print(b)
c = add_days(b, 1)
print("After 2 calls:")
print(c)
I have time string 11:15am or 11:15pm.
I am trying to convert this string into UTC timezone with 24 hour format.
FROM EST to UTC
For example: When I pass 11:15am It should convert into 15:15 and when I pass 11:15pm then it should convert to 3:15.
I have this code which I am trying:
def appointment_time_string(time_str):
import datetime
a = time_str.split()[0]
# b = re.findall(r"[^\W\d_]+|\d+",a)
# c = str(int(b[0]) + 4) + ":" + b[1]
# print("c", c)
in_time = datetime.datetime.strptime(a,'%I:%M%p')
print("In Time", in_time)
start_time = str(datetime.datetime.strftime(in_time, "%H:%M:%S"))
print("Start TIme", start_time)
if time_str.split()[3] == 'Today,':
start_date = datetime.datetime.utcnow().strftime("%Y-%m-%dT")
elif time_str.split()[3] == 'Tomorrow,':
today = datetime.date.today( )
start_date = (today + datetime.timedelta(days=1)).strftime("%Y-%m-%dT")
appointment_time = str(start_date) + str(start_time)
return appointment_time
x = appointment_time_string(time_str)
print("x", x)
But this is just converting to 24 hour not to UTC.
To convert the time from 12 hours to 24 hours format, you may use below code:
from datetime import datetime
new_time = datetime.strptime('11:15pm', '%I:%M%p').strftime("%H:%M")
# new_time: '23:15'
In order to convert time from EST to UTC, the most reliable way is to use third party library pytz. Refer How to convert EST/EDT to GMT? for more details
Developed the following script using provided options/solutions to satisfy my requirement.
def appointment_time_string(time_str):
import datetime
import pytz
a = time_str.split()[0]
in_time = datetime.datetime.strptime(a,'%I:%M%p')
start_time = str(datetime.datetime.strftime(in_time, "%H:%M:%S"))
if time_str.split()[3] == 'Today,':
start_date = datetime.datetime.utcnow().strftime("%Y-%m-%d")
elif time_str.split()[3] == 'Tomorrow,':
today = datetime.date.today( )
start_date = (today + datetime.timedelta(days=1)).strftime("%Y-%m-%d")
appointment_time = str(start_date) + " " + str(start_time)
# print("Provided Time", appointment_time)
utc=pytz.utc
eastern=pytz.timezone('US/Eastern')
fmt='%Y-%m-%dT%H:%M:%SZ'
# testeddate = '2016-09-14 22:30:00'
test_date = appointment_time
dt_obj = datetime.datetime.strptime(test_date,'%Y-%m-%d %H:%M:%S')
dt_str = datetime.datetime.strftime(dt_obj, '%m/%d/%Y %H:%M:%S')
date=datetime.datetime.strptime(dt_str,"%m/%d/%Y %H:%M:%S")
date_eastern=eastern.localize(date,is_dst=None)
date_utc=date_eastern.astimezone(utc)
# print("Required Time", date_utc.strftime(fmt))
return date_utc.strftime(fmt)
Following this answer I tried to get the date for last Thursday of the current month. But my code doesn't get out of loop.
from datetime import datetime
from dateutil.relativedelta import relativedelta, TH
todayte = datetime.today()
cmon = todayte.month
nthu = todayte
while nthu.month == cmon:
nthu += relativedelta(weekday=TH(1))
#print nthu.strftime('%d%b%Y').upper()
Looking at the documentation of relativedelta
Notice that if the calculated date is already Monday, for example, using (0, 1) or (0, -1) won’t change the day.
If nthu is already Thursday then adding TH(1) or TH(-1) won't have any effect but result in the same date and that's why your loop is running infinitely.
I will assume maximum 5 weeks in a month and do it like following:
todayte = datetime.today()
cmon = todayte.month
for i in range(1, 6):
t = todayte + relativedelta(weekday=TH(i))
if t.month != cmon:
# since t is exceeded we need last one which we can get by subtracting -2 since it is already a Thursday.
t = t + relativedelta(weekday=TH(-2))
break
Based on Adam Smith's answer on How can I get the 3rd Friday of a month in Python?, you can get the date of the last Thursday of the current month as follows:
import calendar
import datetime
def get_thursday(cal,year,month,thursday_number):
'''
For example, get_thursday(cal, 2017,8,0) returns (2017,8,3)
because the first thursday of August 2017 is 2017-08-03
'''
monthcal = cal.monthdatescalendar(year, month)
selected_thursday = [day for week in monthcal for day in week if \
day.weekday() == calendar.THURSDAY and \
day.month == month][thursday_number]
return selected_thursday
def main():
'''
Show the use of get_thursday()
'''
cal = calendar.Calendar(firstweekday=calendar.MONDAY)
today = datetime.datetime.today()
year = today.year
month = today.month
date = get_thursday(cal,year,month,-1) # -1 because we want the last Thursday
print('date: {0}'.format(date)) # date: 2017-08-31
if __name__ == "__main__":
main()
You should pass 2 to TH instead of 1, as 1 doesn't change anything. Modify your code to:
while (nthu + relativedelta(weekday=TH(2))).month == cmon:
nthu += relativedelta(weekday=TH(2))
print nthu.strftime('%d-%b-%Y').upper()
# prints 26-MAY-2016
Note that I modified the loop's condition in order to break in the last occurrence of the day on the month, otherwise it'll break in the next month (in this case, June).
from datetime import datetime , timedelta
todayte = datetime.today()
cmon = todayte.month
nthu = todayte
while todayte.month == cmon:
todayte += timedelta(days=1)
if todayte.weekday()==3: #this is Thursday
nthu = todayte
print nthu
You can also use calendar package.
Access the calendar in the form of monthcalendar. and notice that, the Friday is the last day of a week.
import calendar
import datetime
now = datetime.datetime.now()
last_sunday = max(week[-1] for week in calendar.monthcalendar(now.year,
now.month))
print('{}-{}-{:2}'.format(now.year, calendar.month_abbr[now.month],
last_sunday))
I think this will be fastest perhaps:
end_of_month = datetime.datetime.today() + relativedelta(day=31)
last_thursday = end_of_month + relativedelta(weekday=TH(-1))
This code can be used in python 3.x for finding last Thursday of current month.
import datetime
dt = datetime.datetime.today()
def lastThurs(dt):
currDate, currMth, currYr = dt, dt.month, dt.year
for i in range(31):
if currDate.month == currMth and currDate.year == currYr and currDate.weekday() == 3:
#print('dt:'+ str(currDate))
lastThuDate = currDate
currDate += datetime.timedelta(1)
return lastThuDate
You can do something like this:
import pandas as pd
from dateutil.relativedelta import relativedelta, TH
expiry_type = 0
today = pd.datetime.today()
expiry_dates = []
if expiry_type == 0:
# Weekly expiry
for i in range(1,13):
expiry_dates.append((today + relativedelta(weekday=TH(i))).date())
else:
# Monthly expiry
for i in range(1,13):
x = (today + relativedelta(weekday=TH(i))).date()
y = (today + relativedelta(weekday=TH(i+1))).date()
if x.month != y.month :
if x.day > y.day :
expiry_dates.append(x)
print(expiry_dates)
import datetime
def get_thursday(_month,_year):
for _i in range(1,32):
if _i > 9:
_dateStr = str(_i)
else:
_dateStr = '0' + str(_i)
_date = str(_year) + '-' + str(_month) + '-' + _dateStr
try:
a = datetime.datetime.strptime(_date, "%Y-%m-%d").strftime('%a')
except:
continue
if a == 'Thu':
_lastThurs = _date
return _lastThurs
x = get_thursday('05','2017')
print(x)
It is straightforward fast and easy to understand, we take the first of every month and then subtract it by 3 coz 3 is Thursday weekday number and then multiply it by either 4 and check if it is in the same month if it is then that is last Thursday otherwise we multiply it with 3 and we get our last Thursday
import datetime as dt
from datetime import timedelta
#start is the first of every month
start = dt.datetime.fromisoformat('2022-08-01')
if start.month == (start + timedelta((3 - start.weekday()) + 4*7)).month:
exp = start + timedelta((3 - start.weekday()) + 4*7)
else:
exp = start + timedelta((3 - start.weekday()) + 3*7)
You can use Calendar to achieve your result. I find it simple.
import calendar
import datetime
testdate= datetime.datetime.now()
weekly_thursday=[]
for week in calendar.monthcalendar(testdate.year,testdate.month):
if week[3] != 0:
weekly_thursday.append(week[3])
weekly_thursday
The list weekly_thursday will have all the Thursdays from the month.
weekly_thursday[-1] will give you the last Thursday of the month.
testdate : datetime.datetime(2022, 9, 9, 6, 35, 16, 752465)
weekly_thursday : [1, 8, 15, 22, 29]
weekly_thursday [-1]:29