folder reorganization

This commit is contained in:
cttynul
2019-04-23 14:32:53 +02:00
parent 659751b2f4
commit 8e7ee78a87
1195 changed files with 267003 additions and 2 deletions
@@ -0,0 +1 @@
__author__ = 'Piotr Dabkowski'
@@ -0,0 +1,28 @@
from ..conversions import *
from ..func_utils import *
def Array(this, args):
return ArrayConstructor(args, args.space)
def ArrayConstructor(args, space):
if len(args) == 1:
l = get_arg(args, 0)
if type(l) == float:
if to_uint32(l) == l:
return space.NewArray(l)
else:
raise MakeError(
'RangeError',
'Invalid length specified for Array constructor (must be uint32)'
)
else:
return space.ConstructArray([l])
else:
return space.ConstructArray(list(args))
def isArray(this, args):
x = get_arg(args, 0)
return is_object(x) and x.Class == u'Array'
@@ -0,0 +1,14 @@
from ..conversions import *
from ..func_utils import *
def Boolean(this, args):
return to_boolean(get_arg(args, 0))
def BooleanConstructor(args, space):
temp = space.NewObject()
temp.prototype = space.BooleanPrototype
temp.Class = 'Boolean'
temp.value = to_boolean(get_arg(args, 0))
return temp
@@ -0,0 +1,11 @@
from __future__ import unicode_literals
from js2py.internals.conversions import *
from js2py.internals.func_utils import *
class ConsoleMethods:
def log(this, args):
x = ' '.join(to_string(e) for e in args)
print(x)
return undefined
+405
View File
@@ -0,0 +1,405 @@
from ..base import *
from .time_helpers import *
TZ_OFFSET = (time.altzone // 3600)
ABS_OFFSET = abs(TZ_OFFSET)
TZ_NAME = time.tzname[1]
ISO_FORMAT = '%s-%s-%sT%s:%s:%s.%sZ'
@Js
def Date(year, month, date, hours, minutes, seconds, ms):
return now().to_string()
Date.Class = 'Date'
def now():
return PyJsDate(int(time.time() * 1000), prototype=DatePrototype)
@Js
def UTC(year, month, date, hours, minutes, seconds, ms): # todo complete this
args = arguments
y = args[0].to_number()
m = args[1].to_number()
l = len(args)
dt = args[2].to_number() if l > 2 else Js(1)
h = args[3].to_number() if l > 3 else Js(0)
mi = args[4].to_number() if l > 4 else Js(0)
sec = args[5].to_number() if l > 5 else Js(0)
mili = args[6].to_number() if l > 6 else Js(0)
if not y.is_nan() and 0 <= y.value <= 99:
y = y + Js(1900)
t = TimeClip(MakeDate(MakeDay(y, m, dt), MakeTime(h, mi, sec, mili)))
return PyJsDate(t, prototype=DatePrototype)
@Js
def parse(string):
return PyJsDate(
TimeClip(parse_date(string.to_string().value)),
prototype=DatePrototype)
Date.define_own_property('now', {
'value': Js(now),
'enumerable': False,
'writable': True,
'configurable': True
})
Date.define_own_property('parse', {
'value': parse,
'enumerable': False,
'writable': True,
'configurable': True
})
Date.define_own_property('UTC', {
'value': UTC,
'enumerable': False,
'writable': True,
'configurable': True
})
class PyJsDate(PyJs):
Class = 'Date'
extensible = True
def __init__(self, value, prototype=None):
self.value = value
self.own = {}
self.prototype = prototype
# todo fix this problematic datetime part
def to_local_dt(self):
return datetime.datetime.utcfromtimestamp(
UTCToLocal(self.value) // 1000)
def to_utc_dt(self):
return datetime.datetime.utcfromtimestamp(self.value // 1000)
def local_strftime(self, pattern):
if self.value is NaN:
return 'Invalid Date'
try:
dt = self.to_local_dt()
except:
raise MakeError(
'TypeError',
'unsupported date range. Will fix in future versions')
try:
return dt.strftime(pattern)
except:
raise MakeError(
'TypeError',
'Could not generate date string from this date (limitations of python.datetime)'
)
def utc_strftime(self, pattern):
if self.value is NaN:
return 'Invalid Date'
try:
dt = self.to_utc_dt()
except:
raise MakeError(
'TypeError',
'unsupported date range. Will fix in future versions')
try:
return dt.strftime(pattern)
except:
raise MakeError(
'TypeError',
'Could not generate date string from this date (limitations of python.datetime)'
)
def parse_date(py_string): # todo support all date string formats
try:
try:
dt = datetime.datetime.strptime(py_string, "%Y-%m-%dT%H:%M:%S.%fZ")
except:
dt = datetime.datetime.strptime(py_string, "%Y-%m-%dT%H:%M:%SZ")
return MakeDate(
MakeDay(Js(dt.year), Js(dt.month - 1), Js(dt.day)),
MakeTime(
Js(dt.hour), Js(dt.minute), Js(dt.second),
Js(dt.microsecond // 1000)))
except:
raise MakeError(
'TypeError',
'Could not parse date %s - unsupported date format. Currently only supported format is RFC3339 utc. Sorry!'
% py_string)
def date_constructor(*args):
if len(args) >= 2:
return date_constructor2(*args)
elif len(args) == 1:
return date_constructor1(args[0])
else:
return date_constructor0()
def date_constructor0():
return now()
def date_constructor1(value):
v = value.to_primitive()
if v._type() == 'String':
v = parse_date(v.value)
else:
v = v.to_int()
return PyJsDate(TimeClip(v), prototype=DatePrototype)
def date_constructor2(*args):
y = args[0].to_number()
m = args[1].to_number()
l = len(args)
dt = args[2].to_number() if l > 2 else Js(1)
h = args[3].to_number() if l > 3 else Js(0)
mi = args[4].to_number() if l > 4 else Js(0)
sec = args[5].to_number() if l > 5 else Js(0)
mili = args[6].to_number() if l > 6 else Js(0)
if not y.is_nan() and 0 <= y.value <= 99:
y = y + Js(1900)
t = TimeClip(
LocalToUTC(MakeDate(MakeDay(y, m, dt), MakeTime(h, mi, sec, mili))))
return PyJsDate(t, prototype=DatePrototype)
Date.create = date_constructor
DatePrototype = PyJsDate(float('nan'), prototype=ObjectPrototype)
def check_date(obj):
if obj.Class != 'Date':
raise MakeError('TypeError', 'this is not a Date object')
class DateProto:
def toString():
check_date(this)
if this.value is NaN:
return 'Invalid Date'
offset = (UTCToLocal(this.value) - this.value) // msPerHour
return this.local_strftime(
'%a %b %d %Y %H:%M:%S GMT') + '%s00 (%s)' % (pad(
offset, 2, True), GetTimeZoneName(this.value))
def toDateString():
check_date(this)
return this.local_strftime('%d %B %Y')
def toTimeString():
check_date(this)
return this.local_strftime('%H:%M:%S')
def toLocaleString():
check_date(this)
return this.local_strftime('%d %B %Y %H:%M:%S')
def toLocaleDateString():
check_date(this)
return this.local_strftime('%d %B %Y')
def toLocaleTimeString():
check_date(this)
return this.local_strftime('%H:%M:%S')
def valueOf():
check_date(this)
return this.value
def getTime():
check_date(this)
return this.value
def getFullYear():
check_date(this)
if this.value is NaN:
return NaN
return YearFromTime(UTCToLocal(this.value))
def getUTCFullYear():
check_date(this)
if this.value is NaN:
return NaN
return YearFromTime(this.value)
def getMonth():
check_date(this)
if this.value is NaN:
return NaN
return MonthFromTime(UTCToLocal(this.value))
def getDate():
check_date(this)
if this.value is NaN:
return NaN
return DateFromTime(UTCToLocal(this.value))
def getUTCMonth():
check_date(this)
if this.value is NaN:
return NaN
return MonthFromTime(this.value)
def getUTCDate():
check_date(this)
if this.value is NaN:
return NaN
return DateFromTime(this.value)
def getDay():
check_date(this)
if this.value is NaN:
return NaN
return WeekDay(UTCToLocal(this.value))
def getUTCDay():
check_date(this)
if this.value is NaN:
return NaN
return WeekDay(this.value)
def getHours():
check_date(this)
if this.value is NaN:
return NaN
return HourFromTime(UTCToLocal(this.value))
def getUTCHours():
check_date(this)
if this.value is NaN:
return NaN
return HourFromTime(this.value)
def getMinutes():
check_date(this)
if this.value is NaN:
return NaN
return MinFromTime(UTCToLocal(this.value))
def getUTCMinutes():
check_date(this)
if this.value is NaN:
return NaN
return MinFromTime(this.value)
def getSeconds():
check_date(this)
if this.value is NaN:
return NaN
return SecFromTime(UTCToLocal(this.value))
def getUTCSeconds():
check_date(this)
if this.value is NaN:
return NaN
return SecFromTime(this.value)
def getMilliseconds():
check_date(this)
if this.value is NaN:
return NaN
return msFromTime(UTCToLocal(this.value))
def getUTCMilliseconds():
check_date(this)
if this.value is NaN:
return NaN
return msFromTime(this.value)
def getTimezoneOffset():
check_date(this)
if this.value is NaN:
return NaN
return (this.value - UTCToLocal(this.value)) // 60000
def setTime(time):
check_date(this)
this.value = TimeClip(time.to_number().to_int())
return this.value
def setMilliseconds(ms):
check_date(this)
t = UTCToLocal(this.value)
tim = MakeTime(
HourFromTime(t), MinFromTime(t), SecFromTime(t), ms.to_int())
u = TimeClip(LocalToUTC(MakeDate(Day(t), tim)))
this.value = u
return u
def setUTCMilliseconds(ms):
check_date(this)
t = this.value
tim = MakeTime(
HourFromTime(t), MinFromTime(t), SecFromTime(t), ms.to_int())
u = TimeClip(MakeDate(Day(t), tim))
this.value = u
return u
# todo Complete all setters!
def toUTCString():
check_date(this)
return this.utc_strftime('%d %B %Y %H:%M:%S')
def toISOString():
check_date(this)
t = this.value
year = YearFromTime(t)
month, day, hour, minute, second, milli = pad(
MonthFromTime(t) + 1), pad(DateFromTime(t)), pad(
HourFromTime(t)), pad(MinFromTime(t)), pad(
SecFromTime(t)), pad(msFromTime(t))
return ISO_FORMAT % (unicode(year) if 0 <= year <= 9999 else pad(
year, 6, True), month, day, hour, minute, second, milli)
def toJSON(key):
o = this.to_object()
tv = o.to_primitive('Number')
if tv.Class == 'Number' and not tv.is_finite():
return this.null
toISO = o.get('toISOString')
if not toISO.is_callable():
raise this.MakeError('TypeError', 'toISOString is not callable')
return toISO.call(o, ())
def pad(num, n=2, sign=False):
'''returns n digit string representation of the num'''
s = unicode(abs(num))
if len(s) < n:
s = '0' * (n - len(s)) + s
if not sign:
return s
if num >= 0:
return '+' + s
else:
return '-' + s
fill_prototype(DatePrototype, DateProto, default_attrs)
Date.define_own_property(
'prototype', {
'value': DatePrototype,
'enumerable': False,
'writable': False,
'configurable': False
})
DatePrototype.define_own_property('constructor', {
'value': Date,
'enumerable': False,
'writable': True,
'configurable': True
})
@@ -0,0 +1,75 @@
from ..base import *
from ..conversions import *
from ..func_utils import *
from pyjsparser import parse
from ..byte_trans import ByteCodeGenerator, Code
def Function(this, args):
# convert arguments to python list of strings
a = map(to_string, tuple(args))
_body = u';'
_args = ()
if len(a):
_body = u'%s;' % a[-1]
_args = a[:-1]
return executable_function(_body, _args, args.space, global_context=True)
def executable_function(_body, _args, space, global_context=True):
func_str = u'(function (%s) { ; %s ; });' % (u', '.join(_args), _body)
co = executable_code(
code_str=func_str, space=space, global_context=global_context)
return co()
# you can use this one lovely piece of function to compile and execute code on the fly! Watch out though as it may generate lots of code.
# todo tape cleanup? we dont know which pieces are needed and which are not so rather impossible without smarter machinery something like GC,
# a one solution would be to have a separate tape for functions
def executable_code(code_str, space, global_context=True):
# parse first to check if any SyntaxErrors
parsed = parse(code_str)
old_tape_len = len(space.byte_generator.exe.tape)
space.byte_generator.record_state()
start = space.byte_generator.exe.get_new_label()
skip = space.byte_generator.exe.get_new_label()
space.byte_generator.emit('JUMP', skip)
space.byte_generator.emit('LABEL', start)
space.byte_generator.emit(parsed)
space.byte_generator.emit('NOP')
space.byte_generator.emit('LABEL', skip)
space.byte_generator.emit('NOP')
space.byte_generator.restore_state()
space.byte_generator.exe.compile(
start_loc=old_tape_len
) # dont read the code from the beginning, dont be stupid!
ctx = space.GlobalObj if global_context else space.exe.current_ctx
def ex_code():
ret, status, token = space.byte_generator.exe.execute_fragment_under_context(
ctx, start, skip)
# todo Clean up the tape!
# this is NOT a way to do that because the fragment may contain the executable code! We dont want to remove it
#del space.byte_generator.exe.tape[old_tape_len:]
if status == 0:
return ret
elif status == 3:
raise token
else:
raise RuntimeError(
'Unexpected return status during JIT execution: %d' % status)
return ex_code
def _eval(this, args):
code_str = to_string(get_arg(args, 0))
return executable_code(code_str, args.space, global_context=True)()
def log(this, args):
print ' '.join(map(to_string, args))
return undefined
+157
View File
@@ -0,0 +1,157 @@
from __future__ import unicode_literals
from ..conversions import *
from ..func_utils import *
import math
import random
CONSTANTS = {
'E': 2.7182818284590452354,
'LN10': 2.302585092994046,
'LN2': 0.6931471805599453,
'LOG2E': 1.4426950408889634,
'LOG10E': 0.4342944819032518,
'PI': 3.1415926535897932,
'SQRT1_2': 0.7071067811865476,
'SQRT2': 1.4142135623730951
}
class MathFunctions:
def abs(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
return abs(a)
def acos(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
try:
return math.acos(a)
except:
return NaN
def asin(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
try:
return math.asin(a)
except:
return NaN
def atan(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
return math.atan(a)
def atan2(this, args):
x = get_arg(args, 0)
y = get_arg(args, 1)
a = to_number(x)
b = to_number(y)
if a != a or b != b: # it must be a nan
return NaN
return math.atan2(a, b)
def ceil(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
return float(math.ceil(a))
def floor(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
return float(math.floor(a))
def round(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
return float(round(a))
def sin(this, args):
x = get_arg(args, 0)
a = to_number(x)
if not is_finite(a): # it must be a nan
return NaN
return math.sin(a)
def cos(this, args):
x = get_arg(args, 0)
a = to_number(x)
if not is_finite(a): # it must be a nan
return NaN
return math.cos(a)
def tan(this, args):
x = get_arg(args, 0)
a = to_number(x)
if not is_finite(a): # it must be a nan
return NaN
return math.tan(a)
def log(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
try:
return math.log(a)
except:
return NaN
def exp(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
return math.exp(a)
def pow(this, args):
x = get_arg(args, 0)
y = get_arg(args, 1)
a = to_number(x)
b = to_number(y)
if a != a or b != b: # it must be a nan
return NaN
try:
return a**b
except:
return NaN
def sqrt(this, args):
x = get_arg(args, 0)
a = to_number(x)
if a != a: # it must be a nan
return NaN
try:
return a**0.5
except:
return NaN
def min(this, args):
if len(args) == 0:
return Infinity
return min(map(to_number, tuple(args)))
def max(this, args):
if len(args) == 0:
return -Infinity
return max(map(to_number, tuple(args)))
def random(this, args):
return random.random()
@@ -0,0 +1,27 @@
from __future__ import unicode_literals
from ..conversions import *
from ..func_utils import *
def Number(this, args):
if len(args) == 0:
return 0.
return to_number(args[0])
def NumberConstructor(args, space):
temp = space.NewObject()
temp.prototype = space.NumberPrototype
temp.Class = 'Number'
temp.value = float(to_number(get_arg(args, 0)) if len(args) > 0 else 0.)
return temp
CONSTS = {
'MAX_VALUE': 1.7976931348623157e308,
'MIN_VALUE': 5.0e-324,
'NaN': NaN,
'NEGATIVE_INFINITY': Infinity,
'POSITIVE_INFINITY': -Infinity
}
@@ -0,0 +1,204 @@
from __future__ import unicode_literals
from ..conversions import *
from ..func_utils import *
from ..base import is_data_descriptor
import six
def Object(this, args):
val = get_arg(args, 0)
if is_null(val) or is_undefined(val):
return args.space.NewObject()
return to_object(val, args.space)
def ObjectCreate(args, space):
if len(args):
val = get_arg(args, 0)
if is_object(val):
# Implementation dependent, but my will simply return :)
return val
elif type(val) in (NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE):
return to_object(val, space)
return space.NewObject()
class ObjectMethods:
def getPrototypeOf(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError('TypeError',
'Object.getPrototypeOf called on non-object')
return null if obj.prototype is None else obj.prototype
def getOwnPropertyDescriptor(this, args):
obj = get_arg(args, 0)
prop = get_arg(args, 1)
if not is_object(obj):
raise MakeError(
'TypeError',
'Object.getOwnPropertyDescriptor called on non-object')
desc = obj.own.get(to_string(prop))
return convert_to_js_type(desc, args.space)
def getOwnPropertyNames(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError(
'TypeError',
'Object.getOwnPropertyDescriptor called on non-object')
return args.space.ConstructArray(obj.own.keys())
def create(this, args):
obj = get_arg(args, 0)
if not (is_object(obj) or is_null(obj)):
raise MakeError('TypeError',
'Object prototype may only be an Object or null')
temp = args.space.NewObject()
temp.prototype = None if is_null(obj) else obj
if len(args) > 1 and not is_undefined(args[1]):
if six.PY2:
args.tup = (args[1], )
ObjectMethods.defineProperties.__func__(temp, args)
else:
args.tup = (args[1], )
ObjectMethods.defineProperties(temp, args)
return temp
def defineProperty(this, args):
obj = get_arg(args, 0)
prop = get_arg(args, 1)
attrs = get_arg(args, 2)
if not is_object(obj):
raise MakeError('TypeError',
'Object.defineProperty called on non-object')
name = to_string(prop)
if not obj.define_own_property(name, ToPropertyDescriptor(attrs),
False):
raise MakeError('TypeError', 'Cannot redefine property: %s' % name)
return obj
def defineProperties(this, args):
obj = get_arg(args, 0)
properties = get_arg(args, 1)
if not is_object(obj):
raise MakeError('TypeError',
'Object.defineProperties called on non-object')
props = to_object(properties, args.space)
for k, v in props.own.items():
if not v.get('enumerable'):
continue
desc = ToPropertyDescriptor(props.get(unicode(k)))
if not obj.define_own_property(unicode(k), desc, False):
raise MakeError('TypeError',
'Failed to define own property: %s' % k)
return obj
def seal(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError('TypeError', 'Object.seal called on non-object')
for desc in obj.own.values():
desc['configurable'] = False
obj.extensible = False
return obj
def freeze(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError('TypeError', 'Object.freeze called on non-object')
for desc in obj.own.values():
desc['configurable'] = False
if is_data_descriptor(desc):
desc['writable'] = False
obj.extensible = False
return obj
def preventExtensions(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError('TypeError',
'Object.preventExtensions on non-object')
obj.extensible = False
return obj
def isSealed(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError('TypeError',
'Object.isSealed called on non-object')
if obj.extensible:
return False
for desc in obj.own.values():
if desc.get('configurable'):
return False
return True
def isFrozen(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError('TypeError',
'Object.isFrozen called on non-object')
if obj.extensible:
return False
for desc in obj.own.values():
if desc.get('configurable'):
return False
if is_data_descriptor(desc) and desc.get('writable'):
return False
return True
def isExtensible(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError('TypeError',
'Object.isExtensible called on non-object')
return obj.extensible
def keys(this, args):
obj = get_arg(args, 0)
if not is_object(obj):
raise MakeError('TypeError', 'Object.keys called on non-object')
return args.space.ConstructArray([
unicode(e) for e, d in six.iteritems(obj.own)
if d.get('enumerable')
])
# some utility functions:
def ToPropertyDescriptor(obj): # page 38 (50 absolute)
if not is_object(obj):
raise MakeError('TypeError',
'Can\'t convert non-object to property descriptor')
desc = {}
if obj.has_property('enumerable'):
desc['enumerable'] = to_boolean(obj.get('enumerable'))
if obj.has_property('configurable'):
desc['configurable'] = to_boolean(obj.get('configurable'))
if obj.has_property('value'):
desc['value'] = obj.get('value')
if obj.has_property('writable'):
desc['writable'] = to_boolean(obj.get('writable'))
if obj.has_property('get'):
cand = obj.get('get')
if not (is_undefined(cand) or is_callable(cand)):
raise MakeError(
'TypeError',
'Invalid getter (it has to be a function or undefined)')
desc['get'] = cand
if obj.has_property('set'):
cand = obj.get('set')
if not (is_undefined(cand) or is_callable(cand)):
raise MakeError(
'TypeError',
'Invalid setter (it has to be a function or undefined)')
desc['set'] = cand
if ('get' in desc or 'set' in desc) and ('value' in desc
or 'writable' in desc):
raise MakeError(
'TypeError',
'Invalid property. A property cannot both have accessors and be writable or have a value.'
)
return desc
@@ -0,0 +1,41 @@
from __future__ import unicode_literals
from ..conversions import *
from ..func_utils import *
from ..base import SpaceTuple
REG_EXP_FLAGS = ('g', 'i', 'm')
def RegExp(this, args):
pattern = get_arg(args, 0)
flags = get_arg(args, 1)
if GetClass(pattern) == 'RegExp':
if not is_undefined(flags):
raise MakeError(
'TypeError',
'Cannot supply flags when constructing one RegExp from another'
)
# return unchanged
return pattern
#pattern is not a regexp
if is_undefined(pattern):
pattern = u''
else:
pattern = to_string(pattern)
flags = to_string(flags) if not is_undefined(flags) else u''
for flag in flags:
if flag not in REG_EXP_FLAGS:
raise MakeError(
'SyntaxError',
'Invalid flags supplied to RegExp constructor "%s"' % flag)
if len(set(flags)) != len(flags):
raise MakeError(
'SyntaxError',
'Invalid flags supplied to RegExp constructor "%s"' % flags)
return args.space.NewRegExp(pattern, flags)
def RegExpCreate(args, space):
_args = SpaceTuple(args)
_args.space = space
return RegExp(undefined, _args)
@@ -0,0 +1,23 @@
from ..conversions import *
from ..func_utils import *
def fromCharCode(this, args):
res = u''
for e in args:
res += unichr(to_uint16(e))
return res
def String(this, args):
if len(args) == 0:
return u''
return to_string(args[0])
def StringConstructor(args, space):
temp = space.NewObject()
temp.prototype = space.StringPrototype
temp.Class = 'String'
temp.value = to_string(get_arg(args, 0)) if len(args) > 0 else u''
return temp
@@ -0,0 +1,209 @@
from __future__ import unicode_literals
# NOTE: t must be INT!!!
import time
import datetime
import warnings
try:
from tzlocal import get_localzone
LOCAL_ZONE = get_localzone()
except: # except all problems...
warnings.warn(
'Please install or fix tzlocal library (pip install tzlocal) in order to make Date object work better. Otherwise I will assume DST is in effect all the time'
)
class LOCAL_ZONE:
@staticmethod
def dst(*args):
return 1
from js2py.base import MakeError
CUM = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365)
msPerDay = 86400000
msPerYear = int(86400000 * 365.242)
msPerSecond = 1000
msPerMinute = 60000
msPerHour = 3600000
HoursPerDay = 24
MinutesPerHour = 60
SecondsPerMinute = 60
NaN = float('nan')
LocalTZA = -time.timezone * msPerSecond
def DaylightSavingTA(t):
if t is NaN:
return t
try:
return int(
LOCAL_ZONE.dst(datetime.datetime.utcfromtimestamp(
t // 1000)).seconds) * 1000
except:
warnings.warn(
'Invalid datetime date, assumed DST time, may be inaccurate...',
Warning)
return 1
#raise MakeError('TypeError', 'date not supported by python.datetime. I will solve it in future versions')
def GetTimeZoneName(t):
return time.tzname[DaylightSavingTA(t) > 0]
def LocalToUTC(t):
return t - LocalTZA - DaylightSavingTA(t - LocalTZA)
def UTCToLocal(t):
return t + LocalTZA + DaylightSavingTA(t)
def Day(t):
return t // 86400000
def TimeWithinDay(t):
return t % 86400000
def DaysInYear(y):
if y % 4:
return 365
elif y % 100:
return 366
elif y % 400:
return 365
else:
return 366
def DayFromYear(y):
return 365 * (y - 1970) + (y - 1969) // 4 - (y - 1901) // 100 + (
y - 1601) // 400
def TimeFromYear(y):
return 86400000 * DayFromYear(y)
def YearFromTime(t):
guess = 1970 - t // 31556908800 # msPerYear
gt = TimeFromYear(guess)
if gt <= t:
while gt <= t:
guess += 1
gt = TimeFromYear(guess)
return guess - 1
else:
while gt > t:
guess -= 1
gt = TimeFromYear(guess)
return guess
def DayWithinYear(t):
return Day(t) - DayFromYear(YearFromTime(t))
def InLeapYear(t):
y = YearFromTime(t)
if y % 4:
return 0
elif y % 100:
return 1
elif y % 400:
return 0
else:
return 1
def MonthFromTime(t):
day = DayWithinYear(t)
leap = InLeapYear(t)
if day < 31:
return 0
day -= leap
if day < 59:
return 1
elif day < 90:
return 2
elif day < 120:
return 3
elif day < 151:
return 4
elif day < 181:
return 5
elif day < 212:
return 6
elif day < 243:
return 7
elif day < 273:
return 8
elif day < 304:
return 9
elif day < 334:
return 10
else:
return 11
def DateFromTime(t):
mon = MonthFromTime(t)
day = DayWithinYear(t)
return day - CUM[mon] - (1 if InLeapYear(t) and mon >= 2 else 0) + 1
def WeekDay(t):
# 0 == sunday
return (Day(t) + 4) % 7
def msFromTime(t):
return t % 1000
def SecFromTime(t):
return (t // 1000) % 60
def MinFromTime(t):
return (t // 60000) % 60
def HourFromTime(t):
return (t // 3600000) % 24
def MakeTime(hour, Min, sec, ms):
# takes PyJs objects and returns t
if not (hour.is_finite() and Min.is_finite() and sec.is_finite()
and ms.is_finite()):
return NaN
h, m, s, milli = hour.to_int(), Min.to_int(), sec.to_int(), ms.to_int()
return h * 3600000 + m * 60000 + s * 1000 + milli
def MakeDay(year, month, date):
# takes PyJs objects and returns t
if not (year.is_finite() and month.is_finite() and date.is_finite()):
return NaN
y, m, dt = year.to_int(), month.to_int(), date.to_int()
y += m // 12
mn = m % 12
d = DayFromYear(y) + CUM[mn] + dt - 1 + (1 if DaysInYear(y) == 366
and mn >= 2 else 0)
return d # ms per day
def MakeDate(day, time):
return 86400000 * day + time
def TimeClip(t):
if t != t or abs(t) == float('inf'):
return NaN
if abs(t) > 8.64 * 10**15:
return NaN
return int(t)