I'm trying to get the difference between two time-stamps: 1606294772889 and 1606295867656. But I keep getting OSError: [Errno 22] Invalid argument
Here is my code:
from datetime import datetime
def get_duration(start , end):
fmt = '%Y-%m-%d %H:%M:%S'
start = datetime.utcfromtimestamp(start).strftime(fmt)
end = datetime.utcfromtimestamp(end).strftime(fmt)
tstamp1 = datetime.strptime(start, fmt)
tstamp2 = datetime.strptime(end, fmt)
if tstamp1 > tstamp2:
td = tstamp1 - tstamp2
else:
td = tstamp2 - tstamp1
td_mins = int(round(td.total_seconds() / 60))
print('The difference is approx. %s minutes' % td_mins)
get_duration(start = 1606294772889 , end = 1606295867656)
Traceback:
Traceback (most recent call last):
File "c:/Users/Yas_!_ru/Documents/GitHub/Mindustry-Ranked/webdriver.py", line 220, in <module>
Match.get_duration(start = 1606294772889 , end = 1606295867656)
File "c:/Users/Yas_!_ru/Documents/GitHub/Mindustry-Ranked/webdriver.py", line 207, in get_duration
start = datetime.utcfromtimestamp(start).strftime(fmt)
OSError: [Errno 22] Invalid argument
The problem here is that your timestamps seems to be in some subdivision of a second. Probably milliseconds.
When I tried your code I had the same error as Tomerikoo in the comments, I divided the timestamps by 1000 it gave me 182 minutes.
Be sure to check in which format the timestamp are given (miliseconds, tenth of a second etc...), in order to convert them back to seconds to use the datetime functions.
Related
I've written a basic wrapper around sched.scheduler, but I'm getting:
File "/usr/local/anaconda3/lib/python3.7/sched.py", line 149, in run
delayfunc(time - now)
OSError: [Errno 22] Invalid argument
What is the cause of this error? I'm following https://docs.python.org/3/library/sched.html
Code:
#!/usr/local/anaconda3/bin/python
from time import time, sleep
from datetime import datetime, timezone
from sched import scheduler
class Scheduler:
# specify one or t'other e.g. "2021-03-17 02:29:00"
def __init__(self, event_time_utc:str='', local_unix_timestamp_override:float=0):
self.event_local_timestamp = Scheduler.to_local_unix_timestamp(event_time_utc) \
if event_time_utc else local_unix_timestamp_override
# self.seconds_until_event = event_local_timestamp - time()
print(self.event_local_timestamp - time())
self.sch = scheduler()
def run(self, blocking=False):
self.sch.run(blocking)
#staticmethod
def to_local_unix_timestamp(time_utc: str):
dt_utc = datetime.strptime(time_utc, "%Y-%m-%d %H:%M:%S")
dt_local = dt_utc.replace(tzinfo=timezone.utc)
return dt_local.timestamp()
#staticmethod
def to_human_readable(unix_timestamp):
return datetime.fromtimestamp(unix_timestamp).strftime('%Y-%m-%d %H:%M:%S.%f')
def schedule(self, offset_from_event_time_s:float, callback):
print('Event scheduled for local unix timestamp:', self.event_local_timestamp + offset_from_event_time_s)
self.sch.enterabs(
time = self.event_local_timestamp + offset_from_event_time_s,
priority = 1,
action = callback
)
if __name__ == '__main__':
sch = Scheduler(local_unix_timestamp_override=time()+5)
print(f'Started at time: {Scheduler.to_human_readable(time())}')
def callback():
print(f'Callback at time: {Scheduler.to_human_readable(time())}')
sch.schedule(offset_from_event_time_s=1, callback=callback)
sch.run(blocking=True)
Output:
> ./scheduler.py
4.999997854232788
Started at time: 2021-03-17 11:00:03.424191
f 1615953609.424139
Traceback (most recent call last):
File "./scheduler.py", line 55, in <module>
sch.run(blocking=True)
File "./scheduler.py", line 20, in run
self.sch.run(blocking)
File "/usr/local/anaconda3/lib/python3.7/sched.py", line 149, in run
delayfunc(time - now)
OSError: [Errno 22] Invalid argument
The root of the problem is that YOU are assuming that the sched module is using time.time() for its timing function. That is a false assumption. It is using time.monotonic() by default, which returns the time since your program started. That is going to be a small number, like 6. When you try to delay until 1615644884.1231558, that makes it go crazy.
Change this:
self.sch = scheduler()
to this:
self.sch = scheduler(time)
I tried debugging the issue and found that the max length of floating point value allowed in time.sleep() is 8 (I couldn't find any resource on why only 8) but since you are using timestamp the value exceeds that. You can try following code on your machine and check that:
import time
# Will work fine
time.sleep(16156448)
# Will result in error
time.sleep(1615644884.1231558)
I'm looking for a conversion of just am/pm string into time so I could do comparison between 2 different time of the day. I tried using time.strptime or something similar but it seems they all require date as well as time.
My code below:
current_hour = 12
current_minute = 37
current_section = "PM"
due_hour = 9
due_minute = 0
due_section = "AM"
import datetime
ct_time = str(datetime.time(current_hour, current_minute))+current_section
print(ct_time)
due_time = str(datetime.time(due_hour, due_minute))+due_section
print(due_time)
ct_time_str = time.strptime(ct_time, '%H:%M:%S') # how to format this to time?
due_time_str= time.strptime(due_time,'%H:%M:%S') # how to format this to time?
if (ct_time_str>due_time_str):
print("still have time to turn in assignment")
else:
print("too late")
Getting the below error, not sure how to convert to 'time' from str.
Traceback (most recent call last):
File "main.py", line 15, in <module>
ct_time_str = time.strptime(ct_time, '%H:%M:%S')
NameError: name 'time' is not defined
datetime can be confusing because both the module and class are called datetime.
Change your import to from datetime import datetime, time. Also imports should go at the very top, but it's not strictly necessary.
When assigning ct_time and due_time, you use str(datetime.time(args)), it should just be str(time(args)).
strptime is from datetime, not time, so change time.strptime(args) to datetime.strptime(args)
Also like DeepSpace & martineau said, you need to add '%p' to the format string to account for the AM/PM part.
Final code:
from datetime import datetime, time
current_hour = 12
current_minute = 37
current_section = "PM"
due_hour = 9
due_minute = 0
due_section = "AM"
ct_time = str(time(current_hour, current_minute))+current_section
print(ct_time)
due_time = str(time(due_hour, due_minute))+due_section
print(due_time)
ct_time_str = datetime.strptime(ct_time, '%H:%M:%S%p')
due_time_str= datetime.strptime(due_time,'%H:%M:%S%p')
if (ct_time_str < due_time_str):
print("still have time to turn in assignment")
else:
print("too late")
edit:
changed if (ct_time_str < due_time_str): to if (ct_time_str > due_time_str):
I am trying to add expiry time to JWE which I am generating using jwcrypto library in the following way
from jwcrypto import jwe, jwk, jwt
from datetime import datetime, timedelta
import time
# create JWK from existing key
jwk_str = '{"k":"29Js2yXM6P_4v9K1mHDlYVHw8Xvm_GEhvMTvKTRLRzY","kty":"oct"}'
jwk_key = jwk.JWK.from_json(jwk_str)
# calculate expiry time
d = datetime.now() + timedelta(seconds=5)
epoch = datetime.utcfromtimestamp(0)
total_seconds = (d - epoch).total_seconds()
# Add exp to the claims
claims={"exp": total_seconds, "sub": "Some random payload"}
print(claims)
jwttoken = jwt.JWT(header={"alg": "A256KW", "enc": "A256CBC-HS512"}, claims=claims)
jwttoken.make_encrypted_token(jwk_key)
jwetokenstr = jwttoken.serialize()
print(jwetokenstr)
# wait for 10 seconds to cross the expiry time
time.sleep(10)
jwttoken = jwt.JWT()
jwttoken.deserialize(token, jwk_key) # Ideally this line should fail as expiry is reached but it doesn't
print(jwttoken.claims)
I am getting the payload, but expiry claim is not read and doesn't fail on expiry.
What I am doing wrong ?
This ends up reducing to a datetime manipulation bug.
The exp claim of a JSON web token should filled out with the seconds from epoch of the expiration time.
datetime.now() returns a local time (not UTC time) datetime.datetime object. The code above then goes on to subtract this local time datetime.datetime object from the UTC time datetime.datetime object of 0-epoch time and evaluates the total seconds between these two to determine the expiry time. However, because this is comparing a local time datetime to a UTC time datetime, the number of seconds here is actually off of the epoch time by a constant factor of your local timezone difference from UTC.
For example, if I live in a place where the time is 5 hours earlier than UTC, I will actually use an epoch time that is 5 * 60 * 60 seconds off of the true epoch time I want for the expiry with this code.
Instead you could simply use round(time.time()) + x where x is the number of seconds forward in the future the JWT should expire. time.time() returns the seconds from epoch (but as a float so you need to round) from epoch.
For example:
from jwcrypto import jwe, jwk, jwt
from datetime import datetime, timedelta
import time
jwk_str = '{"k":"29Js2yXM6P_4v9K1mHDlYVHw8Xvm_GEhvMTvKTRLRzY","kty":"oct"}'
jwk_key = jwk.JWK.from_json(jwk_str)
jwt_valid_seconds = 3
expiry_time = round(time.time()) + jwt_valid_seconds
claims={"exp": expiry_time, "sub": "Some random payload"}
jwttoken = jwt.JWT(header={"alg": "A256KW", "enc": "A256CBC-HS512"}, claims=claims)
jwttoken.make_encrypted_token(jwk_key)
jwetokenstr = jwttoken.serialize()
jwttoken2 = jwt.JWT()
jwttoken2.deserialize(jwetokenstr, jwk_key)
print('This should succeed because we are deserializing immediately before the JWT has expired:')
print(jwttoken2.claims)
# Wait for the JWT to expire, and then extra time for the leeway.
leeway = 60
time.sleep(leeway + jwt_valid_seconds + 1)
jwttoken2 = jwt.JWT()
print('\nThis should fail due to the JWT expiring:')
jwttoken2.deserialize(jwetokenstr, jwk_key)
gives the output
(env) $ python jwe_expiry.py
This should succeed because we are deserializing immediately before the JWT has expired:
{"exp":1576737332,"sub":"Some random payload"}
This should fail due to the JWT expiring:
Traceback (most recent call last):
File "jwe_expiry.py", line 26, in <module>
jwttoken2.deserialize(jwetokenstr, jwk_key)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 493, in deserialize
self._check_provided_claims()
File "... python3.7/site-packages/jwcrypto/jwt.py", line 370, in _check_provided_claims
self._check_default_claims(claims)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 351, in _check_default_claims
self._check_exp(claims['exp'], time.time(), self._leeway)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 333, in _check_exp
claim, limit, leeway))
jwcrypto.jwt.JWTExpired: Expired at 1576737332, time: 1576737392(leeway: 60)
I'm trying to make a simple clock and I want the format to have the numeric hour without a padding zero. According to every source I can find on google the symbol for that is %l but that gives me a traceback error? It works fine if I use %I though.
def count():
global time1
global date1
time2 = time.strftime('%l:%M %p')
date2 = time.strftime('%A, %B %d %Y')
if time2 != time1:
time1 = time2
clock.config(text=time2)
if date2 != date1:
date1=date2
date.config(text=date2)
clock.after(500, count)
Traceback (most recent call last):
File "D:/Program Files (x86)/pycharm/Projects/test.py", line 48, in count
time2 = time.strftime('%l:%M %p')
ValueError: Invalid format string
Process finished with exit code 1
You want %-I:
time2 = time.strftime('%-I:%M %p')
http://strftime.org/ is a nice reference for Python's strftime format strings.
I'm Salech and I'm learning Python. Python is my really first programming language. It is my second day that I following the youtube video "from zero to hero". And my first problem that I can't solve is related to time and date.
The challenge:
Ask a user to enter a deadline for their project
Tell them how many days they have to complete the project
For Extra Credit give them the answer as a combination of weeks & days
I made all of that, but then I thought to add an additional feature, which takes an input of time(hh:mm:ss) and prints this time minus the current time. Here's how I thought to do it:
import math
import datetime
currentDate = datetime.date.today()
currentTime = datetime.datetime.now()
deadLine = input('Hello, enter the deadline date for your project (mm/dd/yyyy)')
deadLineDate = datetime.datetime.strptime(deadLine, '%m/%d/%Y').date()
deadLineTime = input('insert time')
deadTime = datetime.datetime.strptime(deadLineTime, '%H:%M:%S').time()
print(deadTime)
daysLeft = deadLineDate - currentDate
print('%d days left' % daysLeft.days)
weeksLeft = math.floor(daysLeft.days/7)
newDaysLeft = daysLeft .days- 7*(math.floor(daysLeft.days/7))
print('You have %d weeks' % weeksLeft, ' and %d days left.' % newDaysLeft)
timeLeft = deadTime - currentTime
print(timeLeft.hours)
With the input 02/04/2016 and 15:00 I get the following error:
Hello, enter the deadline date for your project (mm/dd/yyyy)02/04/2016
insert time15:00
15:00:00
5 days left
You have 0 weeks and 5 days left.
Traceback (most recent call last):
File "/Users/PYTHON/challenge04.py", line 31, in <module>
timeLeft = deadTime - currentTime
TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.datetime'
>>>
Edit: As jonatan said, testing the code without any input:
Hello, enter the deadline date for your project (mm/dd/yyyy)
Traceback (most recent call last):
File "/Users/PYTHON/challenge04.py", line 14, in <module>
deadLineDate = datetime.datetime.strptime(deadLine, '%m/%d/%Y').date()
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/_strptime.py", line 507, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/_strptime.py", line 344, in _strptime
(data_string, format))
ValueError: time data '' does not match format '%m/%d/%Y'
Thank You.
You need to combine your date and your time into a datetime.
deadline = datetime.datetime.combine(deadLineDate, deadlineTime)
timeLeft = deadline - currentTime
The reason for the error is because it doesn't really make much sense to subtract a date from a time. e.g. What is "4PM - Fri, Jan 29th?".
import datetime
import math
currentDate=datetime.date.today()
currentTime=datetime.datetime.now()
UserInput1=input("What is the deadline for your project? mm/dd/yyyy ")
deadLine=datetime.datetime.strptime(UserInput1, "%m/%d/%Y").date()
UserInput2=input("Please insert the time hh/mm/ss ")
deadTime=datetime.datetime.strptime(UserInput2, "%H/%M/%S").time()
daysLeft= deadLine-currentDate
print("%d days left" % daysLeft.days)
weeksLeft=math.floor(daysLeft.days/7)
newDaysLeft=daysLeft.days-7*(math.floor(daysLeft.days/7))
print("You have %d weeks" % weeksLeft, "and %d days left."% newDaysLeft)
deadLine=datetime.datetime.combine(deadLine,deadTime)
timeLeft=deadLine-currentTime
print(timeLeft)