I want to take a string
"9:09am Jan 23"
and compare it with datetime.now() to get the amount of difference in hours only.
So if I did something like
now = datetime.datetime.now()
if now - (string in hours) > 24:
return True
else:
return False
I've been messing with it for a little while and cant seem to successfully compare a string (or converted string object) with datetime.now.
You can convert the string to datetime using strptime in conjunction with the relevant format. You'll need to add the current year though:
import datetime
now = datetime.datetime.now()
year = now.year
datestring = "9:09am Jan 23 " + year
dt = datetime.datetime.strptime(datestring, "%H:%M%p %b %d %Y")
Subtracting two datetimes gives you a timedelta object, so you'll need to extract the days:
diff = now - dt
days_diff = diff.days
Here is a function that will grab two instances of current time and return the difference in seconds. This is done mostly with datetime's 'strptime', in which I convert the current time to strings. If you want to ditch the current time, replace the 'time' or 'xvar' variables with a string. I used seconds here, but you can return hours of difference just as easily.
import datetime, sys
def time_passed():
while True:
inp = raw_input("Press [Y] to start, or [X] to exit.: ").lower()
if inp == 'y':
now = datetime.datetime.now()
xvar = now.strftime("%b %d %H:%M:%S")
time = datetime.datetime.strptime(xvar, "%b %d %H:%M:%S")
time = time.replace(year = 2016)
print "The first recording of the time is: {0}".format(time)
print "The second recording of the time is: {0}".format(now)
yvar = (now - time)
print "Between the two times, there is a difference of {0} seconds".format(yvar.total_seconds())
continue
elif inp == 'x':
sys.exit()
break
else:
print "Command Error!"
continue
if __name__ == '__main__':
time_passed()
Thanks for the help guys! What I wanted was how to compare the hours only, so I did a little hacking. What I needed to do was get
diff = now - dt
then to get the hours of that, which is what I was stuck on. The solution was to get the seconds of diff and divide by 3600.
My solution: a function that takes a string time and hour param to determine which messages to delete. (writing a web automation script)
def to_delete(self, date, accepted_range):
""" decides to delete a message based on certain criteria """
now = datetime.datetime.now()
date_str = "%s %s" % (date, now.year)
dt = datetime.datetime.strptime(date_str, "%H:%M%p %b %d %Y")
diff = now - dt
if diff.seconds/3600 > accepted_range:
return True
else:
return False
It gives me the hours only and now I can delete posts if they're over x hours old
Related
in python, if I have a date string in the following format yyyy-mm-dd, I would like to write a function to check if the date is in the past, present or future. However, I am having some trouble with this. I have written the following code...
from datetime import datetime
def check_date(date_string):
this_date = datetime.strptime(date_string, '%Y-%m-%d')
now = datetime.today()
if this_date < now:
print("the date is in the past")
elif this_date > now:
print("the day is in the future")
else:
print("the day is today")
however, when I tested this, it gives me...
>>check_date('2022-08-08')
the date is in the past
>>check_date('2022-10-10')
the day is in the future
>>check_date('2022-09-22') #this is todays date
the date is in the past
I'm not sure why it is giving this unexpected behaviour.
thanks
datetime.datetime.today() includes both date and time, as a quick debug print would have shown. Use this:
import datetime
def check_date(date_string):
this_date = datetime.datetime.strptime(date_string, '%Y-%m-%d')
now = datetime.date.today()
...
Try this!
from datetime import datetime
def check_date(date_string):
this_date = datetime.strptime(date_string, '%Y-%m-%d').date()
now = datetime.today().date()
print(now, this_date)
if this_date < now:
print("the date is in the past")
elif this_date > now:
print("the day is in the future")
else:
print("the day is today")
I believe the problem is where you get the today's date. datetime.today() create an instance which includes hours, minutes, seconds in addition to year, month, day. However, you are trying to compare them with date only (i.e., year, month, day format.
If you consider date.today() instead of datetime.today(), you should be good to go.
from datetime import datetime
year = 2022
month = 9
day = 22
Date_to_check = datetime.date(datetime(year,month,day))
current_day = datetime.date(datetime.now())
if Date_to_check == current_day:
print("it is present")
elif Date_to_check > current_day:
print("it is future")
else:
print("it is past")
please review this code and you'll get some idea how it is working.
I am running into following error while calculating time diff?how to fix it?
from datetime import datetime, date
import time
print "Start : %s" % time.ctime()
start_time = time.ctime()
#do something
print "How to calculate time diff?"
end_time = time.ctime()
total_elapsed_time = datetime.combine(date.today(), end_time) - datetime.combine(date.today(), start_time)
print "TOTAL ELAPSED TIME" + str(total_elapsed_time)
Error:-
Traceback (most recent call last):
File "time_diff.py", line 8, in <module>
total_elapsed_time = datetime.combine(date.today(), end_time) - datetime.combine(date.today(), start_time)
TypeError: combine() argument 2 must be datetime.time, not str
The error clearly states that argument 2 of combine() must be datetime.time.
You should have an instance of datetime.time which is something like:
d = datetime.now()
timepart = d.time()
datepart = d.date()
datetime.combine(datepart, timepart)
First of all you are mixin 3 data types, so your approach is fundamentally wrong.
There are two (basic) ways, how to get and store time in python (two from std lib):
timestamp - you import time module, then time.time() will return a float - a number of seconds from epoch, then any comparison is just like comparing float numbers, if number is greater - then time that it represents is in the future, any difference between dates is a number too - representing number of seconds between dates - so it is as well simple to convert it minutes, hours etc. by dividing by 60, 3600 etc.
datetime object you import datetime.datetime to get an object which you can operate on, it is much simpler to operate on than timestamp, because it is automatically converted to human readable format, all comparison operators works and any difference between dates (date2-date1) is returned as datetime.timedelta where you can extract number of days, seconds and milliseconds it represents.
so in your code you can use:
timestamps:
import time
date1 = time.time()
print 'Start time: %s' % time.ctime(date1)
...
date2 = time.time()
print 'End time: %s' % time.ctime(date2)
print 'Time it took: %0.2f seconds' % (date2 - date1)
datetime
from datetime import datetime
date1 = datetime.now()
print 'Start time: %s' % date1
...
date2 = datetime.now()
print 'End time: %s' % date2
print 'Time it took: %s' % (date2 - date1)
from datetime import datetime, timedelta
def calc():
s = datetime.now()
e = datetime(day=21, month=7, year=2016, hour=12, minute=0)
diff = e - s
diff is datetime.timedelta instance now. On this instance you have properties such as days, seconds, microseconds and function by name total_seconds.
PS: This is for reference only. I hope it helps to achieve a solution
time.ctime() returns a string, that is the source of your error.
See Python time.ctime
time.time() is probably what you are looking for:
See Python ticks
Your start_time and end_time are strings. Also your datetime.combine should have the 2nd argument as a datetime.time object. Your time.ctime returns the date and year information as well. So first extract only the time information and then convert it to a datetime.time object.
You can store the start and end time both using ctime and then do something like this:
import datetime
import time
#store at start time
a=datetime.datetime.strptime(time.ctime(), "%a %b %d %H:%M:%S %Y")
#store at end time
b=datetime.datetime.strptime(time.ctime(), "%a %b %d %H:%M:%S %Y")
print b-a
As #Jerzyk pointed out, there is no need to parse it unless you want to display it in a particular format. So alternatively, you could do:
a=datetime.datetime.now()
b=datetime.datetime.now()
print b-a
This will return a datetime.timedelta that you can parse in order to display the result in the way you want.
I have a script built that takes a date and time of an observation at a telescope and converts it to just a date with a decimal day. This script also takes in half the exposure time and adds it to the decimal day so that I can get the most accurate astrometric calculation. This is then submitted to The Minor Planet Center that only accepts the time of observation in Year Month Day.XXXXX What is the most accurate way to 5 decimal points to do this? This is the current way I use, yes it is very messy but it does get me the decimal day. Occasionally it is off by one second in the time conversion.
expmpc = float.("10")
utcstartmpc = "05:45:19.03"
datempc = "2015-02-14"
ddexposure = expmpc/(60.0*60.0*24.0)
ddexposure = round(ddexposure, 5)
seconds = int(utcstartmpc[6:8]) / 60.0
minutes = (int(utcstartmpc[3:5]) + seconds) / 60
hours = (int(utcstartmpc[:2]) + minutes) / 24
hours = round(hours, 5)
expadd = str(hours + ddexposure)
datempc = datempc.replace("-", " ")
utcmpc = "C%s%s" % (datempc, expadd[1:])
utcmpc = utcmpc.ljust(17, "0")
As you can see this is very messy and it involves rounding a lot of data and I believe I am losing accuracy with the rounding. The finished outcome of the code leaves a time such as this:
C2015 02 14.23986
Is there a module that works better?
Thank you for the help.
Here's something that uses more of the built-in time/date modules (and I think it does what you want):
import time
import datetime
def my_date_converter(date_in):
parse_str, _ = date_in.split(".")
date_str, time_str = parse_str.split(" ")
parsed_time = time.strptime(time_str, "%H:%M:%S")
total_seconds = datetime.timedelta(hours=parsed_time.tm_hour,minutes=parsed_time.tm_min,seconds=parsed_time.tm_sec).total_seconds()
seconds_in_day = 86400.0
decimal_seconds = total_seconds / seconds_in_day
utcmpc = "C%s%s" % (date_str.replace("-", " "), str(round(decimal_seconds, 5))[1:])
utcmpc = utcmpc.ljust(17, "0")
return utcmpc
def main():
to_convert = "2015-02-14 05:45:19.03"
converted = my_date_converter(to_convert)
print "%s => %s" % (to_convert, converted)
if __name__ == '__main__':
main()
Example output: 2015-02-14 05:45:19.03 => C2015 02 14.23980
Have you tried the excellent astropy library? They have a package to deal with time and conversions: astropy.time
You could separate your problem into 2 tasks:
get datetime object that represent UTC time from the input expmpc, utcstartmpc, datempc
convert datetime object to string in the Year Month Day.XXXXX format.
Get datetime object from the input expmpc, utcstartmpc, datempc
from datetime import datetime, timedelta
expmpc = "10"
utcstartmpc = "05:45:19.03"
datempc = "2015-02-14"
dt = datetime.strptime(datempc + " " + utcstartmpc, "%Y-%m-%d %H:%M:%S.%f")
dt += timedelta(seconds=int(expmpc))
Convert datetime object to string in the Year Month Day.XXXXX format
from datetime import datetime, time, timedelta
s = dt.strftime("C%Y %m %d.")
day_fraction = dt - datetime.combine(dt, time.min)
s += ("%.0f" % (100000*day_fraction / timedelta(days=1)))
# -> C2015 02 14.23992
Note: the result is slightly different from the one in your question (92 vs. 86 at the end).
In Python 2, you need to replace td / timedelta(1) with td.total_seconds() / 86400.
Here's another way:
>>> from __future__ import division
>>> assert day_fraction.days == 0
>>> '%.0f' % ((day_fraction.seconds*10**6 + day_fraction.microseconds) / 864000)
'23992'
All arithmetic operations before the true division are performed with infinite precision.
Yet another way also produces 92:
>>> from datetime import timezone
>>> ('%.5f' % ((dt.replace(tzinfo=timezone.utc).timestamp() % 86400) / 86400))[2:]
'23992'
I am trying to get an easy to read time format to list events from google calendar for the current day. I can pull in the data, but I'm having a problem formatting the data to be just the Hour and minute for both start time and end time.
I want to display the information in an easy to read list, so I want to drop the date and seconds and only display the time in order. I have tried several different methods including slicing and trying to convert into date time with no luck.
date = datetime.datetime.now()
tomorrow = date.today() + datetime.timedelta(days=2)
yesterday = date.today() - datetime.timedelta(days=1)
now = str
data = '{:%Y-%m-%d}'.format(date)
tdata = '{:%Y-%m-%d}'.format(tomorrow)
ydata = '{:%Y-%m-%d}'.format(yesterday)
def DateQuery(calendar_service, start_date=data, end_date=tdata):
print 'Date query for events on Primary Calendar: %s to %s' % (start_date, end_date,)
query = gdata.calendar.service.CalendarEventQuery('default', 'private', 'full')
query.start_min = start_date
query.start_max = end_date
feed = calendar_service.CalendarQuery(query)
for i, an_event in enumerate(feed.entry):
print '\'%s\'' % (an_event.title.text)
for a_when in an_event.when:
dstime = (a_when.start_time,)
detime = (a_when.end_time,)
print '\t\tEnd time: %s' % (dstime)
print '\t\tEnd time: %s' % (detime)
It prints like this
End time: 2013-03-23T04:00:00.000-05:00
and I would prefer it be
End time: 04:00
Using the dateutil module:
>>> import dateutil.parser
>>> dateutil.parser.parse('2013-03-23T04:00:00.000-05:00')
>>> dt = dateutil.parser.parse('2013-03-23T04:00:00.000-05:00')
>>> dt.strftime('%I:%M')
'04:00'
If you don't want to use dateutil, you an also parse the string using the specific format with strptime.
I want to be able to format a datetime object, while leaving it as an object. I have worked a way to do it, but it doesn't seem very efficient.
My specific aim is to limit the extra digits on the seconds to 2. This is how I am currently doing it:
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
now_frmt = datetime.datetime.strptime(now, '%Y-%m-%d %H:%M:%S')
Cheers,
JJ
You could do this to subtract off the microseconds:
now = datetime.datetime.now()
now_frmt = now - datetime.timedelta(microseconds=now.microsecond)
To round to the nearest second you can do the following:
now = datetime.datetime.now()
delta = (0 if now.microsecond < 500000 else 1000000) - now.microsecond
now_frmt = now + datetime.timedelta(microseconds=delta)