This question is related to the datetime module of Python - python

I wrote a Python function that prints the number of days remaining in birthday of a user - the value of which is entered by the user. The code is as follows:
"""
Created on Thu Feb 20 16:01:33 2020
#author: hussain.ali
"""
import datetime as dt
import pytz
def days_to_birthday():
a = (input('Enter your birthday in YYYY, MM, DD format with the year being the current year:'))
td = dt.datetime.today()
#td2= td.replace(hour=0, minute =0, second =0, microsecond =0)
birthday = dt.datetime.strptime(a, '%Y,%m,%d')
days_to_birthday = birthday - td
print("There are", days_to_birthday, ' remaining until your next birthday!')
days_to_birthday()
This script or code works well except that it gives the number of days plus hours as well as minutes, seconds and even microseconds remaining until the next birthday.
The output seems like:
Enter your birthday in YYYY, MM, DD format with the year being the current year:2020,3,7
There are 15 days, 6:11:07.020133 remaining until your next birthday!
I want either only the days remaining to be displayed in the output
OR the output as:
There are 15 days, 6 hours, 11minutes, 07seconds, and 020133 microseconds remaining until your next birthday!
What one needs to do to attain the desired output? Please advise.

change your print statement to this code below.
print("There are", days_to_birthday.days, 'days remaining until your next birthday!')

timedelta doesn't have strftime() to format it so you can do one of two things:
get total_seconds() and calculate all values using divmod() or using // and %
total = days_to_birthday.seconds
rest, seconds = divmod(total, 60)
hours, minutes = divmod(rest, 60)
days = days_to_birthday.days
microseconds = days_to_birthday.microseconds
print('{} days {:02} hrs {:02} mins {:02} secs {:06} microseconds'.format(days, hours, minutes, seconds, microseconds))
get string 15 days, 6:11:07.020133, split it and use parts to create new string
days = days_to_birthday.days
parts = str(days_to_birthday).split(', ')[1].replace('.', ':').split(':')
print('{} days {} hrs {} mins {} secs {} microseconds'.format(days, *parts))
import datetime as dt
import pytz
#a = input('Enter your birthday in YYYY,MM,DD format with the year being the current year:')
a = '2020,06,01'
print('date:', a)
td = dt.datetime.today()
birthday = dt.datetime.strptime(a, '%Y,%m,%d')
days_to_birthday = birthday - td
print(days_to_birthday)
total = days_to_birthday.seconds
rest, seconds = divmod(total, 60)
hours, minutes = divmod(rest, 60)
days = days_to_birthday.days
microseconds = days_to_birthday.microseconds
print('{} days {:02} hrs {:02} mins {:02} secs {:06} microseconds'.format(days, hours, minutes, seconds, microseconds))
days = days_to_birthday.days
parts = str(days_to_birthday).split(', ')[1].replace('.', ':').split(':')
print('{} days {} hrs {} mins {} secs {} microseconds'.format(days, *parts))
Result
date: 2020,06,01
93 days, 21:35:15.056351
93 days 21 hrs 35 mins 15 secs 056351 microseconds
93 days 21 hrs 35 mins 15 secs 056351 microseconds

Related

How to calculate time difference in python?

Example:
9:43 - 17:27 - how many hours and minutes elapsed between those times ?
Here is one approach to get the number of total minutes:
from datetime import datetime
s = '9:30 - 14:00 ; 14:30 - 16:30'
sum(((b-a).total_seconds()/60 for x in s.split(' ; ')
for a,b in [list(map(lambda t: datetime.strptime(t, '%H:%M'), x.split(' - ')))]))
Output: 390.0
If you know that the time periods will never span midnight, then you could simply split the time strings with time.split(":") and do the math yourself with the hours and minutes.
However, the correct solution would be to import the datetime module and calculate the timedelta.
This example could be condensed. I intentionally made it verbose without knowing exactly how you're getting your inputs:
from datetime import datetime
times = [
"9:30",
"14:00",
"14:30",
"16:30"
]
#Just using today's date to fill in the values with assumption all times are on the same day.
year = 2022
month = 6
day = 9
date_times = []
for time in times:
split_time = time.split(":")
hour = split_time[0]
minutes = split_time[1]
timestamp = datetime.datetime.today(year=year, month=month, day=day, hour=hour, min=minutes)
date_times.append(timestamp)
total_seconds = 0
for i in range(1, len(date_times), 2):
delta = date_times[i] - date_times[i-1] # The timedelta object returned will have days, seconds, milliseconds
total_seconds += delta.days * 86400 + delta.seconds
hours = total_seconds // 3600 # Integer division
minutes = round((total_seconds % 3600) / 60) # Change depending on if you want to round to nearest, or always up or down.

Adding a user specified date to existing code

I'm a but stuck with being able to add a user defined date to this Days to Go code. Works well with a set date embedded. But can't get this to work with the input lines.
from datetime import datetime, time
b = input
event = (input('What is the name of your event?')) # input the name of the event
year = int(input('Enter a year')) # input the requires year
month = int(input('Enter a month')) # input the required month
day = int(input('Enter a day')) # input the required day
def date_diff_in_seconds(dt2, dt1):
timedelta = dt2 - dt1
return timedelta.days * 24 * 3600 + timedelta.seconds
def dhms_from_seconds(seconds):
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
return (days, hours, minutes, seconds)
# Specified date
date1 = datetime.date(b[1], b[2], b[3])
# Current date
date2 = datetime.now()
print("\n%d days, %d hours, %d minutes, %d seconds" %
dhms_from_seconds(date_diff_in_seconds(date2, date1)))
print()
First, you wrongly used b=input. It means you want to use input function with function name b, such as event = b('what is the name of your event?').
Instead, you can assign values to b like b = (event, year, month, day) after getting information using input().
And you imported datetime module by from datetime import datetime you don't need to explitly say datetime.date, just date. However, you can use datetime rather than date here, as follows:
from datetime import datetime, time
#b = input -> wrong usage
event = (input('What is the name of your event? ')) # input the name of the event
year = int(input('Enter a year ')) # input the requires year
month = int(input('Enter a month ')) # input the required month
day = int(input('Enter a day ')) # input the required day
b = (event, year, month, day) # you can assign date values to b
def date_diff_in_seconds(dt2, dt1):
timedelta = dt2 - dt1
return timedelta.days * 24 * 3600 + timedelta.seconds
def dhms_from_seconds(seconds):
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
return (days, hours, minutes, seconds)
# Specified date
date1 = datetime(b[1], b[2], b[3]) # not datetime.date()
# Current date
date2 = datetime.now()
print("\n%d days, %d hours, %d minutes, %d seconds" %
dhms_from_seconds(date_diff_in_seconds(date2, date1)))
print()
# if you want to print the event together:
print("\n%d days, %d hours, %d minutes, %d seconds left for %s" % (
dhms_from_seconds(date_diff_in_seconds(date2, date1)) + (event,)))
The result is like:
What is the name of your event? birthday
Enter a year 2022
Enter a month 03
Enter a day 19
0 days, 14 hours, 40 minutes, 2 seconds
0 days, 14 hours, 40 minutes, 2 seconds left for Sunday # in case that you print the event together
I think your problem is likely this line:
date1 = datetime.date(b[1],b[2],b[3])
Try changing it to this:
date1 = datetime.date(year, month, day, 0, 0, 0)

From string to datetime, looking at the current (local) time

Is there any function, in python, that extracts time information from a string to get the time from the current local one?
For example:
I have a column with time information in the past compared to the current time (let's say UK time, approximately 20:00)
Time
10 hours # ago
6 hours # ago
12 hours # ago
2 days # ago
1 day # ago
I would like to have, looking at the current UK time, (i.e., approximately 20:00):
New_Time
10:00
14:00
8:00
48:00
24:00
The column above comes from the current local time minus the number of hours (from string to numerical) in Time column.
Is it something that I might do with a function? The New_Time is the output that I will need.
In case there might not be a function in python, my approach would be:
use something to detect the current time (to save it in a variable)
consider hours as 60 min and 1 day as 24 hours ... in order to run some mathematical operations, once transformed strings into numerical
subtract from the current time the amount of minutes/hours to go back in time
You can make use of the dateparser package (some explanation in comments):
import datetime
import dateparser # pip install dateparser
# a function to format timedelta to string needed below,
# see https://stackoverflow.com/q/538666/10197418
def timedelta2str(sec):
hours, remainder = divmod(sec, 3600)
return f'{int(hours):02}:{int(remainder//60):02}'
def formatTimeAgo(string, reftime):
# try to parser... if successful, you get a datetime object
dtobj = dateparser.parse(string, settings={'RELATIVE_BASE': reftime})
if isinstance(dtobj, datetime.datetime):
# calculate a timedelta object against reference time
td = reftime - dtobj
# now format output based on input (days or hours..)
if td >= datetime.timedelta(1):
return timedelta2str(td.total_seconds())
else:
return (reftime-td).strftime('%H:%M')
else:
return "N/A"
# exemplary input
t = ("10 hours", "6 hours", "2 days", "1 day")
# a reference time
reftime = datetime.datetime(2021,4,10,20)
for elem in t:
print(elem, '->', formatTimeAgo(elem, reftime))
# giving you
>>> 10 hours -> 10:00
>>> 6 hours -> 14:00
>>> 2 days -> 48:00
>>> 1 day -> 24:00
Now you can adjust that to be used on pandas.Series:
import pandas as pd
df = pd.DataFrame({'Time': ["10 hours", "6 hours", "12 hours", "2 days", "1 day"]})
df['New_Time'] = df['Time'].apply(formatTimeAgo, args=(reftime,))
df['New_Time']
0 10:00
1 14:00
2 08:00
3 48:00
4 24:00
Name: New_Time, dtype: object
You can create a method that would return the time that it was a few hours/days/... ago. For example, two methods that will respectively return what day it was x days ago and what hour it was x hours ago :
def getTimeDaysAgo(x):
today = datetime.datetime.now()
value = today.day - x
previousMonth = today.month - 1
previousMonthDuration = 30
if previousMonth == 2:
if today.year % 4 == 0:
previousMonthDuration = 29
else:
previousMonthDuration = 28
if previousMonth % 2 == 1:
previousMonthDuration = 31
return value if value >= 0 else value + previousMonthDuration
def getTimeHoursAgo(x):
value = datetime.datetime.now().hour - x
return value if value >= 0 else value + 24
I'm not sure why you want to get "48:00" as a result of 2 days ago and "10:00" as a result of 10 hours ago at the same time. Feel free to ask for more infos, I'd be glad to help you out.

Weekly Countdown Timer in Python

I am trying to write a script that runs continuously in the background to countdown to a repeated weekly event. For example, it should tell me how many days, hours, and minutes it will take to reach the specified time.
I know how to do it if I had a specific date and time.
import datetime
delta = datetime.datetime(2018, 5, 5, 8) - datetime.datetime.now()
But what if I don't have a specific date and time? Can datetime let me choose the day of the week?
EDIT:
i.e. Some pseudocode like this is what I need.
delta = datetime(Thursday 8 PM) - datetime.datetime.now()
#returns datetime or timedelta in days, hours, minutes
EDIT:
Thanks Ethan, i appreciate your constructive advice.
I wrote a small script which should do what you want:
import datetime
import time
wanted_day = 'thursday'
wanted_time = 8
list = [['monday', 0],['tuesday', 1],['wednesday', 2],['thursday', 3],['friday', 4],['saturday', 5],['sunday', 6]]
for i in list:
if wanted_day == i[0]:
number_wanted_day = i[1]
# today delivers the actual day
today = datetime.datetime.today().weekday()
# delta_days describes how many days are left until the wanted day
delta_days = number_wanted_day - today
# time delivers the actual time
time = time.localtime(time.time())
if wanted_time > time[3]:
delta_hours = wanted_time - time[3]
delta_mins = 59 - time[4]
delta_secs = 59 - time[5]
else:
delta_days = delta_days - 1
delta_hours = 23 - time[3] + wanted_time
delta_mins = 59 - time[4]
delta_secs = 59 - time[5]
print [delta_days, delta_hours, delta_mins, delta_secs]
The output looks like this then:
[2, 21, 3, 49]
2 is the number of days, 21 the number of hours, 3 the number of mins and 49 the number of secs (I used thursday 8 am as wanted time).
You just need to input the time in the format 0-23, with am and pm you would need to adapt it a bit

Express time in hours units to verbose time

I need express my time in Hours and minutes. This is what I have:
0.0425 hours
~153 seconds, How can I show this as 0 Hours 2 minutos 33 seconds?
Here is one way.
time = '0.0425 hours'
# Extract time from string
time = time.split()[0]
# Convert time to a number of hours, then a number of seconds
time = float(time)
time = int(time * 3600)
# Compute the constituent elements of the time
hours = time // 3600
minutes = (time // 60) % 60
seconds = time % 60
# Print the result
print '{hours} Hours {minutes} minutos {seconds} seconds'.format(
hours=hours, minutes=minutes, seconds=seconds)
import time
import re
secs = int(re.sub('\D', '','~153'))
print '%d hours %d minutos %s seconds'%(time.gmtime(secs)[3:6])

Categories