Show More
Commit Description:
Merge pull request #17 from nattee/master...
Commit Description:
Merge pull request #17 from nattee/master upgrade to current working snapshot
References:
File last commit:
Show/Diff file:
Action:
lib/assets/Lib/time.py | 383 lines | 11.9 KiB | text/x-python | PythonLexer |
merge with algo and add brython files that were missing
r584 from browser import window
import javascript
# use Javascript Date constructor
date = javascript.JSConstructor(window.Date)
#daylight = 0 # fix me.. returns Non zero if DST timezone is defined
##############################################
# Added to pass some tests
# Are there timezone always in the browser?
# I'm assuming we don't have always this info
_STRUCT_TM_ITEMS = 9
##############################################
##############################################
## Helper functions
def _get_day_of_year(arg):
"""
Get the day position in the year starting from 1
Parameters
----------
arg : tuple
Returns
-------
int with the correct day of the year starting from 1
"""
ml = [31,28,31,30,31,30,31,31,30,31,30,31]
if arg[0]%4==0:
ml[1] += 1
i=1
yday=0
while i<arg[1]:
yday += ml[i-1]
i += 1
yday += arg[2]
return yday
def _get_week_of_year(arg):
"""
Get the week position in the year starting from 0. All days in a new
year preceding the first Monday are considered to be in week 0.
Parameters
----------
arg : tuple
Returns
-------
int with the correct iso week (weeks starting on Monday) of the year.
"""
d1 = date(arg[0], arg[1]-1, arg[2])
d0 = date(arg[0], 0, 1)
firstday = d0.getDay()
if firstday == 0 : firstday = 7
firstweek = 8 - firstday
doy = arg[7]
if firstday != 1:
doy = doy - firstweek
if doy % 7 == 0:
week_number = doy // 7
else:
week_number = doy // 7 + 1
return week_number
def _check_struct_time(t):
mm = t[1]
if mm == 0: mm = 1
if -1 > mm > 13: raise ValueError("month out of range")
dd = t[2]
if dd == 0: dd = 1
if -1 > dd > 32: raise ValueError("day of month out of range")
hh = t[3]
if -1 > hh > 24: raise ValueError("hour out of range")
minu = t[4]
if -1 > minu > 60: raise ValueError("minute out of range")
ss = t[5]
if -1 > ss > 62: raise ValueError("seconds out of range")
wd = t[6] % 7
if wd < -2: raise ValueError("day of week out of range")
dy = t[7]
if dy == 0: dy = 1
if -1 > dy > 367: raise ValueError("day of year out of range")
return t[0], mm, dd, hh, minu, ss, wd, dy, t[-1]
def _is_dst(secs = None):
"Check if data has daylight saving time"
d = date()
if secs is not None:
d = date(secs*1000)
# calculate if we are in daylight savings time or not.
# borrowed from http://stackoverflow.com/questions/11887934/check-if-daylight-saving-time-is-in-effect-and-if-it-is-for-how-many-hours
jan = date(d.getFullYear(), 0, 1)
jul = date(d.getFullYear(), 6, 1)
dst = int(d.getTimezoneOffset() < max(abs(jan.getTimezoneOffset()), abs(jul.getTimezoneOffset())))
return dst
def _get_tzname():
"check if timezone is available, if not return a tuple of empty str"
d = date()
d = d.toTimeString()
try:
d = d.split('(')[1].split(')')[0]
return (d, 'NotAvailable')
except:
return ('', '')
def _set_altzone():
d = date()
jan = date(d.getFullYear(), 0, 1)
jul = date(d.getFullYear(), 6, 1)
result = timezone - (jan.getTimezoneOffset() - jul.getTimezoneOffset()) * 60
return result
def _check_input(t):
if t and isinstance(t, struct_time) and len(t.args) == 9:
t = t.args
elif t and isinstance(t, tuple) and len(t) == 9:
t = t
elif t and isinstance(t, struct_time) and len(t.args) != 9:
raise TypeError("function takes exactly 9 arguments ({} given)".format(len(t.args)))
elif t and isinstance(t, tuple) and len(t) != 9:
raise TypeError("function takes exactly 9 arguments ({} given)".format(len(t.args)))
elif t and not isinstance(t, (tuple, struct_time)):
raise TypeError("Tuple or struct_time argument required")
else:
t = localtime().args
return t
## end of helper functions
##############################################
##############################################
## Values depending the timezone of the browser.
daylight = _is_dst()
timezone = date().getTimezoneOffset() * 60
tzname = _get_tzname()
altzone = _set_altzone() if daylight else timezone
##############################################
def asctime(t = None):
weekdays = {0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu",
4: "Fri", 5: "Sat", 6: "Sun"}
months = {1:'Jan',2:'Feb',3:'Mar',4:'Apr',5:'May',6:'Jun',
7:'Jul',8:'Aug',9:'Sep',10:'Oct',11:'Nov',12:'Dec'}
t = _check_input(t)
t = _check_struct_time(t)
result = "%s %s %2d %02d:%02d:%02d %d" % (
weekdays[t[6]], months[t[1]], t[2], t[3], t[4], t[5], t[0])
return result
def ctime(timestamp=None):
return asctime(localtime(timestamp))
def gmtime(secs = None):
d = date()
if secs is not None:
d = date(secs*1000)
wday = d.getUTCDay() - 1 if d.getUTCDay() - 1 >= 0 else 6
tmp = struct_time([d.getUTCFullYear(),
d.getUTCMonth()+1, d.getUTCDate(),
d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(),
wday, 0, 0])
tmp.args[7] = _get_day_of_year(tmp.args)
return tmp
def localtime(secs = None):
d = date()
if secs is not None:
d = date(secs * 1000)
dst = _is_dst(secs)
wday = d.getDay() - 1 if d.getDay() - 1 >= 0 else 6
tmp = struct_time([d.getFullYear(),
d.getMonth()+1, d.getDate(),
d.getHours(), d.getMinutes(), d.getSeconds(),
wday, 0, dst])
tmp.args[7] = _get_day_of_year(tmp.args)
return tmp
def mktime(t):
if isinstance(t, struct_time):
d1 = date(t.tm_year, t.tm_mon - 1, t.tm_mday,
t.tm_hour, t.tm_min, t.tm_sec, 0).getTime()
elif isinstance(t, tuple):
d1 = date(t[0], t[1] - 1, t[2], t[3], t[4], t[5], 0).getTime()
else:
raise ValueError("Tuple or struct_time argument required")
d2 = date(0).getTime()
return (d1 - d2) / 1000.
def monotonic():
return javascript.JSObject(window.performance.now)()/1000.
def perf_counter():
return float(date().getTime()/1000.0)
def time():
return float(date().getTime()/1000)
def sleep(secs):
"""Javascript can't block execution for a given time, expect by an
infinite loop that freezes the browser. It's better to raise an
exception"""
#start = date().getTime()
#while date().getTime() - start < secs * 1000.:
# pass
raise NotImplementedError("Blocking functions like time.sleep() are not "
"supported in the browser. Use functions in module browser.timer "
"instead.")
def strftime(_format,t = None):
def ns(t,nb):
# left padding with 0
res = str(t)
while len(res)<nb:
res = '0'+res
return res
t = _check_input(t)
t = _check_struct_time(t)
YY = ns(t[0],4)
yy = ns(t[0],4)[2:]
mm = ns(t[1],2)
dd = ns(t[2],2)
HH = t[3]
HH24 = ns(HH,2)
HH12 = ns(HH % 12,2)
if HH12 == 0:HH12 = 12
AMPM = 'AM' if 0 <= HH < 12 else 'PM'
MM = ns(t[4],2)
SS = ns(t[5],2)
DoY = ns(t[7],3)
w = t[6] + 1 if t[6] < 6 else 0
W = ns(_get_week_of_year(t),2)
abb_weekdays = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
full_weekdays = ['Sunday','Monday','Tuesday','Wednesday',
'Thursday','Friday','Saturday']
abb_months = ['Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec']
full_months = ['January','February','March','April','May','June',
'July','August','September','October','November','December']
res = _format
res = res.replace("%H",HH24)
res = res.replace("%I",HH12)
res = res.replace("%p",AMPM)
res = res.replace("%M",MM)
res = res.replace("%S",SS)
res = res.replace("%Y",YY)
res = res.replace("%y",yy)
res = res.replace("%m",mm)
res = res.replace("%d",dd)
res = res.replace("%a",abb_weekdays[w])
res = res.replace("%A",full_weekdays[w])
res = res.replace("%b",abb_months[int(mm)-1])
res = res.replace("%B",full_months[int(mm)-1])
res = res.replace("%j", DoY)
res = res.replace("%w", str(w))
res = res.replace("%W", W)
res = res.replace("%x", mm+'/'+dd+'/'+yy)
res = res.replace("%X", HH24+':'+MM+':'+SS)
res = res.replace("%c", abb_weekdays[w]+' '+abb_months[int(mm)-1]+
' '+dd+' '+HH24+':'+MM+':'+SS+' '+YY)
res = res.replace("%%", '%')
return res
class struct_time:
def __init__(self, args):
if len(args)!=9:
raise TypeError("time.struct_time() takes a 9-sequence (%s-sequence given)" %len(args))
self.args = args
@property
def tm_year(self):
return self.args[0]
@property
def tm_mon(self):
return self.args[1]
@property
def tm_mday(self):
return self.args[2]
@property
def tm_hour(self):
return self.args[3]
@property
def tm_min(self):
return self.args[4]
@property
def tm_sec(self):
return self.args[5]
@property
def tm_wday(self):
return self.args[6]
@property
def tm_yday(self):
return self.args[7]
@property
def tm_isdst(self):
return self.args[8]
def __getitem__(self, i):
return self.args[i]
def __iter__(self):
return iter(self.args)
def __repr__(self):
return ("time.structime(tm_year={}, tm_mon={}, tm_day={}, "+\
"tm_hour={}, tm_min={}, tm_sec={}, tm_wday={}, "+\
"tm_yday={}, tm_isdst={})").format(*self.args)
def __str__(self):
return self.__repr__()
def to_struct_time(*arg):
arg = list(arg)
# The tuple received from module _strptime has 7 elements, we must add
# the rank of day in the year in the range [1, 366]
ml = [31,28,31,30,31,30,31,31,30,31,30,31]
if arg[0]%4==0:
ml[1] += 1
i=1
yday=0
while i<arg[1]:
yday += ml[i-1]
i += 1
yday += arg[2]
arg.append(yday)
arg.append(-1)
return struct_time(tuple(arg))
def strptime(string, _format):
import _strptime
return _strptime._strptime_datetime(to_struct_time, string, _format)
# All the clock_xx machinery shouldn't work in the browser so some
# NotImplementedErrors or messages are shown
_clock_msg = """Browser cannot access CPU. See '%s'"""
def _clock_xx(url):
raise NotImplementedError(_clock_msg % url)
clock = lambda: _clock_xx("https://docs.python.org/3/library/time.html#time.clock")
clock_getres = lambda: _clock_xx("https://docs.python.org/3/library/time.html#time.clock_getres")
clock_gettime = lambda: _clock_xx("https://docs.python.org/3/library/time.html#time.clock_gettime")
clock_settime = lambda: _clock_xx("https://docs.python.org/3/library/time.html#time.clock_settime")
CLOCK_HIGHRES = _clock_msg % "https://docs.python.org/3/library/time.html#time.CLOCK_HIGHRES"
CLOCK_MONOTONIC = _clock_msg % "https://docs.python.org/3/library/time.html#time.CLOCK_MONOTONIC"
CLOCK_MONOTONIC_RAW = _clock_msg % "https://docs.python.org/3/library/time.html#time.CLOCK_MONOTONIC_RAW"
CLOCK_PROCESS_CPUTIME_ID = _clock_msg % "https://docs.python.org/3/library/time.html#time.CLOCK_PROCESS_CPUTIME_ID"
CLOCK_REALTIME = _clock_msg % "https://docs.python.org/3/library/time.html#time.CLOCK_REALTIME"
CLOCK_THREAD_CPUTIME_ID = _clock_msg % "https://docs.python.org/3/library/time.html#time.CLOCK_THREAD_CPUTIME_ID"
get_clock_info = lambda: _clock_xx("https://docs.python.org/3/library/time.html#time.get_clock_info")
process_time = lambda: _clock_xx("https://docs.python.org/3/library/time.html#time.process_time")
def tzset():
raise NotImplementedError()