1from __future__ import unicode_literals 2 3# NOTE: t must be INT!!! 4import time 5import datetime 6import warnings 7 8try: 9 from tzlocal import get_localzone 10 LOCAL_ZONE = get_localzone() 11except: # except all problems... 12 warnings.warn( 13 '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' 14 ) 15 16 class LOCAL_ZONE: 17 @staticmethod 18 def dst(*args): 19 return 1 20 21 22from js2py.base import MakeError 23CUM = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365) 24msPerDay = 86400000 25msPerYear = int(86400000 * 365.242) 26msPerSecond = 1000 27msPerMinute = 60000 28msPerHour = 3600000 29HoursPerDay = 24 30MinutesPerHour = 60 31SecondsPerMinute = 60 32NaN = float('nan') 33LocalTZA = -time.timezone * msPerSecond 34 35 36def DaylightSavingTA(t): 37 if t is NaN: 38 return t 39 try: 40 return int( 41 LOCAL_ZONE.dst(datetime.datetime(1970, 1, 1) + datetime.timedelta( 42 seconds=t // 1000)).seconds) * 1000 43 except: 44 warnings.warn( 45 'Invalid datetime date, assumed DST time, may be inaccurate...', 46 Warning) 47 return 1 48 #raise MakeError('TypeError', 'date not supported by python.datetime. I will solve it in future versions') 49 50 51def GetTimeZoneName(t): 52 return time.tzname[DaylightSavingTA(t) > 0] 53 54 55def LocalToUTC(t): 56 return t - LocalTZA - DaylightSavingTA(t - LocalTZA) 57 58 59def UTCToLocal(t): 60 return t + LocalTZA + DaylightSavingTA(t) 61 62 63def Day(t): 64 return t // 86400000 65 66 67def TimeWithinDay(t): 68 return t % 86400000 69 70 71def DaysInYear(y): 72 if y % 4: 73 return 365 74 elif y % 100: 75 return 366 76 elif y % 400: 77 return 365 78 else: 79 return 366 80 81 82def DayFromYear(y): 83 return 365 * (y - 1970) + (y - 1969) // 4 - (y - 1901) // 100 + ( 84 y - 1601) // 400 85 86 87def TimeFromYear(y): 88 return 86400000 * DayFromYear(y) 89 90 91def YearFromTime(t): 92 guess = 1970 - t // 31556908800 # msPerYear 93 gt = TimeFromYear(guess) 94 if gt <= t: 95 while gt <= t: 96 guess += 1 97 gt = TimeFromYear(guess) 98 return guess - 1 99 else: 100 while gt > t: 101 guess -= 1 102 gt = TimeFromYear(guess) 103 return guess 104 105 106def DayWithinYear(t): 107 return Day(t) - DayFromYear(YearFromTime(t)) 108 109 110def InLeapYear(t): 111 y = YearFromTime(t) 112 if y % 4: 113 return 0 114 elif y % 100: 115 return 1 116 elif y % 400: 117 return 0 118 else: 119 return 1 120 121 122def MonthFromTime(t): 123 day = DayWithinYear(t) 124 leap = InLeapYear(t) 125 if day < 31: 126 return 0 127 day -= leap 128 if day < 59: 129 return 1 130 elif day < 90: 131 return 2 132 elif day < 120: 133 return 3 134 elif day < 151: 135 return 4 136 elif day < 181: 137 return 5 138 elif day < 212: 139 return 6 140 elif day < 243: 141 return 7 142 elif day < 273: 143 return 8 144 elif day < 304: 145 return 9 146 elif day < 334: 147 return 10 148 else: 149 return 11 150 151 152def DateFromTime(t): 153 mon = MonthFromTime(t) 154 day = DayWithinYear(t) 155 return day - CUM[mon] - (1 if InLeapYear(t) and mon >= 2 else 0) + 1 156 157 158def WeekDay(t): 159 # 0 == sunday 160 return (Day(t) + 4) % 7 161 162 163def msFromTime(t): 164 return t % 1000 165 166 167def SecFromTime(t): 168 return (t // 1000) % 60 169 170 171def MinFromTime(t): 172 return (t // 60000) % 60 173 174 175def HourFromTime(t): 176 return (t // 3600000) % 24 177 178 179def MakeTime(hour, Min, sec, ms): 180 # takes PyJs objects and returns t 181 if not (hour.is_finite() and Min.is_finite() and sec.is_finite() 182 and ms.is_finite()): 183 return NaN 184 h, m, s, milli = hour.to_int(), Min.to_int(), sec.to_int(), ms.to_int() 185 return h * 3600000 + m * 60000 + s * 1000 + milli 186 187 188def MakeDay(year, month, date): 189 # takes PyJs objects and returns t 190 if not (year.is_finite() and month.is_finite() and date.is_finite()): 191 return NaN 192 y, m, dt = year.to_int(), month.to_int(), date.to_int() 193 y += m // 12 194 mn = m % 12 195 d = DayFromYear(y) + CUM[mn] + dt - 1 + (1 if DaysInYear(y) == 366 196 and mn >= 2 else 0) 197 return d # ms per day 198 199 200def MakeDate(day, time): 201 return 86400000 * day + time 202 203 204def TimeClip(t): 205 if t != t or abs(t) == float('inf'): 206 return NaN 207 if abs(t) > 8.64 * 10**15: 208 return NaN 209 return int(t) 210