How to format datetime output in Python? - python

Have a program to get a date count down. I don't want to print the milliseconds, please help here is my program in python:
import time
import datetime
while (datetime.datetime.now() != datetime.datetime (2018,5,5,19,30)):
print (datetime.datetime (2018,5,5,19,30) - datetime.datetime.now())
time.sleep(1.0)
This is my current output: 54 days, 3:54:53.603289
Would like: 54 days, 3:54:53, but don't know how to do it.

You are looking for datetime.replace(microsecond=0), which will:
Return a datetime with the same attributes, except for those
attributes given new values by whichever keyword arguments are
specified.
import time
import datetime
while (datetime.datetime.now() != datetime.datetime (2018,5,5,19,30)):
print (datetime.datetime (2018,5,5,19,30) - datetime.datetime.now().replace(microsecond=0))
time.sleep(1.0)
Output:
54 days, 3:49:31
54 days, 3:49:30
54 days, 3:49:29
54 days, 3:49:28
54 days, 3:49:27
54 days, 3:49:26
54 days, 3:49:25
54 days, 3:49:24
54 days, 3:49:23

As you have found, there are no good formatting options for a timedelta object. I would recommend you pre-calculate an end_time and also use < rather than waiting for the times to match. In the event your PC is busy at the exact second, your loop might miss the match. By using < it will also catch it:
from datetime import datetime
import time
end_time = datetime(2018, 5, 5, 19, 30)
while datetime.now() < end_time:
print(end_time - datetime.now().replace(microsecond=0))
time.sleep(1.0)

Related

How to know whether two datetimes cover exactly one day (DST issues)

I have a piece of code that provided two timezone-aware Python datetime(s) tries to figure out if they are exactly the beginning and the end of the same day.
For most of the cases, checking that the difference (the timedelta) between the two dates is 23 hours, 59 minutes, 59 seconds and 999999 microseconds, works fine:
from datetime import datetime, time, timedelta, date
import pytz
ny = pytz.timezone('America/New_York')
day=date(2019, 3, 11)
start_naive=datetime.combine(day, time.min)
start=ny.localize(start_naive)
end_naive=datetime.combine(day, time.max)
end=ny.localize(end_naive)
same_day_check = timedelta(hours=time.max.hour,
minutes=time.max.minute,
seconds=time.max.second,
microseconds=time.max.microsecond)
print(f"Same day?")
(end - start) == same_day_check # This outputs True
⚠️ However...
On daylight savings time dates, a day doesn't last 23 hours, 59 min. 59 sec. and 999999 microseconds but +1 hour or -1 hour (in those dates, "a day" can last 22 hours, 59 min.. or 24 hour, 59 min...):
# ...
day=date(2019, 3, 10) # DST start in NY timezone
# ...
same_day_check = timedelta(hours=time.max.hour,
minutes=time.max.minute,
seconds=time.max.second,
microseconds=time.max.microsecond)
print(f"Same day?")
(end - start) == same_day_check # Now this is `False`
print(end-start) # This outputs 22:59:59.999999
Is there a more reliable way than this? Using timedelta like described above is clearly not a reliable solution.

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

Python check if date is within 24 hours

I have been trying some code for this, but I can't seem to completely wrap my head around it.
I have a set date, set_date which is just some random date as you'd expect and that one is just data I get.
Now I would like some error function that raises an error if datetime.now() is within 24 hours of the set_date.
I have been trying code with the timedelta(hours=24)
from datetime import datetime, timedelta
now = datetime.now()
if now < (set_date - timedelta(hours=24)):
raise ValidationError('')
I'm not sure whats right to do with this, what the good way to do is. How exactly do I check if the current time is 24 hours before the set date?
Like that?
if now-timedelta(hours=24) <= set_date <= now:
... #date less than 24 hours in the past
If you want to check for the date to be within 24 hours on either side:
if now-timedelta(hours=24) <= set_date <= now+timedelta(hours=24):
... #date within 24 hours
To check if the date is within 24 hours.
Take a difference between the current time and the past time and check if the no. of days is zero.
past_date = datetime(2018, 6, 6, 5, 27, 28, 369051)
difference = datetime.utcnow() - past_date
if difference.days == 0:
print "date is within 24 hours"
## Also you can check the difference between two dates in seconds
total_seconds = (difference.days * 24 * 60 * 60) + difference.seconds
# Edited. Also difference have in-built method which will return the elapsed seconds.
total_seconds = difference.total_seconds()
You can check if total_seconds is less than the desired time
It is as simple as that:
from datetime import datetime
#...some code...
if (datetime.now() - pastDate).days > 1:
print('24 hours have passed')
else:
print('Date is within 24 hours!')
What you do here is subtract the old date pastDate from the current date datetime.now(), which gives you a time delta datetime.timedelta(...) object. This object stores the number of days, seconds and microseconds which have passed since the old date.
That will do:
if now - timedelta(hours=24) <= set_date <= now + timedelta(hours=24):
#Do something
Which is equivalent to:
if now - timedelta(hours=24) <= set_date <= now or now <= set_date <= now + timedelta(hours=24):
# ---^--- in the past 24h ---^--- in the future 24h
#Do something

Python strftime clock

I am trying to write a countdown clock script. I want to use a set date in the future and have it count down in a nice readable format. Hours, Min, Sec. I am going to print to a 16x2 lCD display. The problem I'm having is trying to take the output of the difference between dates into a nice format. I have attached what I have so far. I receive the error:
AttributeError: 'datetime.timedelta' object has no attribute 'strftime'
This is my code:
from datetime import datetime
from time import strftime
deploy = datetime(2015, 3, 21, 0, 0)
mydate = datetime.now() - deploy
print (mydate.strftime("%b %d %H:%M:%S"))
I know how to print to my LCD and create a loop, just need help with this part.
There are two issues:
the time difference may be incorrect if you use local time represented as a naive datetime object if the corresponding local times have different utc offsets e.g., around a DST transition
the difference is timedelta object that has no strftime() method
To fix it, convert deploy from local timezone to UTC:
#!/usr/bin/env python
import time
from datetime import datetime, timedelta
deploy = datetime(2015, 3, 21, 0, 0) # assume local time
timestamp = time.mktime(deploy.timetuple()) # may fail, see the link below
deploy_utc = datetime.utcfromtimestamp(timestamp)
elapsed = deploy_utc - datetime.utcnow() # `deploy` is in the future
where elapsed is the elapsed time not counting leap seconds (such as 2015-07-01 00:59:60 BST+0100).
More details on when time.mktime() may fail see at Find if 24 hrs have passed between datetimes - Python.
To convert timedelta to string, you could use str() function:
print(elapsed) # print full timedelta
# remove microseconds
trunc_micros = timedelta(days=elapsed.days, seconds=elapsed.seconds)
print(trunc_micros) # -> 20 days, 13:44:14 <- 17 chars
# remove comma
print(str(trunc_micros).replace(',', ''))
# -> 20 days 13:44:14 <- 16 chars
If you want a different format then convert to hours, minutes, second using divmod() function:
seconds = elapsed.days*86400 + elapsed.seconds # drop microseconds
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
print("{hours:02d}:{minutes:02d}:{seconds:02d}".format(**vars()))
# -> 493:44:14

Subtracting Dates With Python

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

Categories