Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/mujs/jsdate.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 #include "jsi.h" | |
| 2 | |
| 3 #include <time.h> | |
| 4 | |
| 5 #if defined(__unix__) || defined(__APPLE__) | |
| 6 #include <sys/time.h> | |
| 7 #elif defined(_WIN32) | |
| 8 #include <sys/timeb.h> | |
| 9 #endif | |
| 10 | |
| 11 #define js_optnumber(J,I,V) (js_isdefined(J,I) ? js_tonumber(J,I) : V) | |
| 12 | |
| 13 static double Now(void) | |
| 14 { | |
| 15 #if defined(__unix__) || defined(__APPLE__) | |
| 16 struct timeval tv; | |
| 17 gettimeofday(&tv, NULL); | |
| 18 return floor(tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0); | |
| 19 #elif defined(_WIN32) | |
| 20 struct _timeb tv; | |
| 21 _ftime(&tv); | |
| 22 return tv.time * 1000.0 + tv.millitm; | |
| 23 #else | |
| 24 return time(NULL) * 1000.0; | |
| 25 #endif | |
| 26 } | |
| 27 | |
| 28 static double LocalTZA(void) | |
| 29 { | |
| 30 static int once = 1; | |
| 31 static double tza = 0; | |
| 32 if (once) { | |
| 33 time_t now = time(NULL); | |
| 34 time_t utc = mktime(gmtime(&now)); | |
| 35 time_t loc = mktime(localtime(&now)); | |
| 36 tza = (loc - utc) * 1000; | |
| 37 once = 0; | |
| 38 } | |
| 39 return tza; | |
| 40 } | |
| 41 | |
| 42 static double DaylightSavingTA(double t) | |
| 43 { | |
| 44 return 0; /* TODO */ | |
| 45 } | |
| 46 | |
| 47 /* Helpers from the ECMA 262 specification */ | |
| 48 | |
| 49 #define HoursPerDay 24.0 | |
| 50 #define MinutesPerDay (HoursPerDay * MinutesPerHour) | |
| 51 #define MinutesPerHour 60.0 | |
| 52 #define SecondsPerDay (MinutesPerDay * SecondsPerMinute) | |
| 53 #define SecondsPerHour (MinutesPerHour * SecondsPerMinute) | |
| 54 #define SecondsPerMinute 60.0 | |
| 55 | |
| 56 #define msPerDay (SecondsPerDay * msPerSecond) | |
| 57 #define msPerHour (SecondsPerHour * msPerSecond) | |
| 58 #define msPerMinute (SecondsPerMinute * msPerSecond) | |
| 59 #define msPerSecond 1000.0 | |
| 60 | |
| 61 static double pmod(double x, double y) | |
| 62 { | |
| 63 x = fmod(x, y); | |
| 64 if (x < 0) | |
| 65 x += y; | |
| 66 return x; | |
| 67 } | |
| 68 | |
| 69 static int Day(double t) | |
| 70 { | |
| 71 return floor(t / msPerDay); | |
| 72 } | |
| 73 | |
| 74 static double TimeWithinDay(double t) | |
| 75 { | |
| 76 return pmod(t, msPerDay); | |
| 77 } | |
| 78 | |
| 79 static int DaysInYear(int y) | |
| 80 { | |
| 81 return y % 4 == 0 && (y % 100 || (y % 400 == 0)) ? 366 : 365; | |
| 82 } | |
| 83 | |
| 84 static int DayFromYear(int y) | |
| 85 { | |
| 86 return 365 * (y - 1970) + | |
| 87 floor((y - 1969) / 4.0) - | |
| 88 floor((y - 1901) / 100.0) + | |
| 89 floor((y - 1601) / 400.0); | |
| 90 } | |
| 91 | |
| 92 static double TimeFromYear(int y) | |
| 93 { | |
| 94 return DayFromYear(y) * msPerDay; | |
| 95 } | |
| 96 | |
| 97 static int YearFromTime(double t) | |
| 98 { | |
| 99 int y = floor(t / (msPerDay * 365.2425)) + 1970; | |
| 100 double t2 = TimeFromYear(y); | |
| 101 if (t2 > t) | |
| 102 --y; | |
| 103 else if (t2 + msPerDay * DaysInYear(y) <= t) | |
| 104 ++y; | |
| 105 return y; | |
| 106 } | |
| 107 | |
| 108 static int InLeapYear(double t) | |
| 109 { | |
| 110 return DaysInYear(YearFromTime(t)) == 366; | |
| 111 } | |
| 112 | |
| 113 static int DayWithinYear(double t) | |
| 114 { | |
| 115 return Day(t) - DayFromYear(YearFromTime(t)); | |
| 116 } | |
| 117 | |
| 118 static int MonthFromTime(double t) | |
| 119 { | |
| 120 int day = DayWithinYear(t); | |
| 121 int leap = InLeapYear(t); | |
| 122 if (day < 31) return 0; | |
| 123 if (day < 59 + leap) return 1; | |
| 124 if (day < 90 + leap) return 2; | |
| 125 if (day < 120 + leap) return 3; | |
| 126 if (day < 151 + leap) return 4; | |
| 127 if (day < 181 + leap) return 5; | |
| 128 if (day < 212 + leap) return 6; | |
| 129 if (day < 243 + leap) return 7; | |
| 130 if (day < 273 + leap) return 8; | |
| 131 if (day < 304 + leap) return 9; | |
| 132 if (day < 334 + leap) return 10; | |
| 133 return 11; | |
| 134 } | |
| 135 | |
| 136 static int DateFromTime(double t) | |
| 137 { | |
| 138 int day = DayWithinYear(t); | |
| 139 int leap = InLeapYear(t); | |
| 140 switch (MonthFromTime(t)) { | |
| 141 case 0: return day + 1; | |
| 142 case 1: return day - 30; | |
| 143 case 2: return day - 58 - leap; | |
| 144 case 3: return day - 89 - leap; | |
| 145 case 4: return day - 119 - leap; | |
| 146 case 5: return day - 150 - leap; | |
| 147 case 6: return day - 180 - leap; | |
| 148 case 7: return day - 211 - leap; | |
| 149 case 8: return day - 242 - leap; | |
| 150 case 9: return day - 272 - leap; | |
| 151 case 10: return day - 303 - leap; | |
| 152 default : return day - 333 - leap; | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 static int WeekDay(double t) | |
| 157 { | |
| 158 return pmod(Day(t) + 4, 7); | |
| 159 } | |
| 160 | |
| 161 static double LocalTime(double utc) | |
| 162 { | |
| 163 return utc + LocalTZA() + DaylightSavingTA(utc); | |
| 164 } | |
| 165 | |
| 166 static double UTC(double loc) | |
| 167 { | |
| 168 return loc - LocalTZA() - DaylightSavingTA(loc - LocalTZA()); | |
| 169 } | |
| 170 | |
| 171 static int HourFromTime(double t) | |
| 172 { | |
| 173 return pmod(floor(t / msPerHour), HoursPerDay); | |
| 174 } | |
| 175 | |
| 176 static int MinFromTime(double t) | |
| 177 { | |
| 178 return pmod(floor(t / msPerMinute), MinutesPerHour); | |
| 179 } | |
| 180 | |
| 181 static int SecFromTime(double t) | |
| 182 { | |
| 183 return pmod(floor(t / msPerSecond), SecondsPerMinute); | |
| 184 } | |
| 185 | |
| 186 static int msFromTime(double t) | |
| 187 { | |
| 188 return pmod(t, msPerSecond); | |
| 189 } | |
| 190 | |
| 191 static double MakeTime(double hour, double min, double sec, double ms) | |
| 192 { | |
| 193 return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms; | |
| 194 } | |
| 195 | |
| 196 static double MakeDay(double y, double m, double date) | |
| 197 { | |
| 198 /* | |
| 199 * The following array contains the day of year for the first day of | |
| 200 * each month, where index 0 is January, and day 0 is January 1. | |
| 201 */ | |
| 202 static const double firstDayOfMonth[2][12] = { | |
| 203 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, | |
| 204 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} | |
| 205 }; | |
| 206 | |
| 207 double yd, md; | |
| 208 int im; | |
| 209 | |
| 210 y += floor(m / 12); | |
| 211 m = pmod(m, 12); | |
| 212 | |
| 213 im = (int)m; | |
| 214 if (im < 0 || im >= 12) | |
| 215 return NAN; | |
| 216 | |
| 217 yd = floor(TimeFromYear(y) / msPerDay); | |
| 218 md = firstDayOfMonth[DaysInYear(y) == 366][im]; | |
| 219 | |
| 220 return yd + md + date - 1; | |
| 221 } | |
| 222 | |
| 223 static double MakeDate(double day, double time) | |
| 224 { | |
| 225 return day * msPerDay + time; | |
| 226 } | |
| 227 | |
| 228 static double TimeClip(double t) | |
| 229 { | |
| 230 if (!isfinite(t)) | |
| 231 return NAN; | |
| 232 if (fabs(t) > 8.64e15) | |
| 233 return NAN; | |
| 234 return t < 0 ? -floor(-t) : floor(t); | |
| 235 } | |
| 236 | |
| 237 static int toint(const char **sp, int w, int *v) | |
| 238 { | |
| 239 const char *s = *sp; | |
| 240 *v = 0; | |
| 241 while (w--) { | |
| 242 if (*s < '0' || *s > '9') | |
| 243 return 0; | |
| 244 *v = *v * 10 + (*s++ - '0'); | |
| 245 } | |
| 246 *sp = s; | |
| 247 return 1; | |
| 248 } | |
| 249 | |
| 250 static double parseDateTime(const char *s) | |
| 251 { | |
| 252 int y = 1970, m = 1, d = 1, H = 0, M = 0, S = 0, ms = 0; | |
| 253 int tza = 0; | |
| 254 double t; | |
| 255 | |
| 256 /* Parse ISO 8601 formatted date and time: */ | |
| 257 /* YYYY("-"MM("-"DD)?)?("T"HH":"mm(":"ss("."sss)?)?("Z"|[+-]HH(":"mm)?)?)? */ | |
| 258 | |
| 259 if (!toint(&s, 4, &y)) return NAN; | |
| 260 if (*s == '-') { | |
| 261 s += 1; | |
| 262 if (!toint(&s, 2, &m)) return NAN; | |
| 263 if (*s == '-') { | |
| 264 s += 1; | |
| 265 if (!toint(&s, 2, &d)) return NAN; | |
| 266 } | |
| 267 } | |
| 268 | |
| 269 if (*s == 'T') { | |
| 270 s += 1; | |
| 271 if (!toint(&s, 2, &H)) return NAN; | |
| 272 if (*s != ':') return NAN; | |
| 273 s += 1; | |
| 274 if (!toint(&s, 2, &M)) return NAN; | |
| 275 if (*s == ':') { | |
| 276 s += 1; | |
| 277 if (!toint(&s, 2, &S)) return NAN; | |
| 278 if (*s == '.') { | |
| 279 s += 1; | |
| 280 if (!toint(&s, 3, &ms)) return NAN; | |
| 281 } | |
| 282 } | |
| 283 if (*s == 'Z') { | |
| 284 s += 1; | |
| 285 tza = 0; | |
| 286 } else if (*s == '+' || *s == '-') { | |
| 287 int tzh = 0, tzm = 0; | |
| 288 int tzs = *s == '+' ? 1 : -1; | |
| 289 s += 1; | |
| 290 if (!toint(&s, 2, &tzh)) return NAN; | |
| 291 if (*s == ':') { | |
| 292 s += 1; | |
| 293 if (!toint(&s, 2, &tzm)) return NAN; | |
| 294 } | |
| 295 if (tzh > 23 || tzm > 59) return NAN; | |
| 296 tza = tzs * (tzh * msPerHour + tzm * msPerMinute); | |
| 297 } else { | |
| 298 tza = LocalTZA(); | |
| 299 } | |
| 300 } | |
| 301 | |
| 302 if (*s) return NAN; | |
| 303 | |
| 304 if (m < 1 || m > 12) return NAN; | |
| 305 if (d < 1 || d > 31) return NAN; | |
| 306 if (H < 0 || H > 24) return NAN; | |
| 307 if (M < 0 || M > 59) return NAN; | |
| 308 if (S < 0 || S > 59) return NAN; | |
| 309 if (ms < 0 || ms > 999) return NAN; | |
| 310 if (H == 24 && (M != 0 || S != 0 || ms != 0)) return NAN; | |
| 311 | |
| 312 /* TODO: DaylightSavingTA on local times */ | |
| 313 t = MakeDate(MakeDay(y, m-1, d), MakeTime(H, M, S, ms)); | |
| 314 return t - tza; | |
| 315 } | |
| 316 | |
| 317 /* date formatting */ | |
| 318 | |
| 319 static char *fmtdate(char *buf, double t) | |
| 320 { | |
| 321 int y = YearFromTime(t); | |
| 322 int m = MonthFromTime(t); | |
| 323 int d = DateFromTime(t); | |
| 324 if (!isfinite(t)) | |
| 325 return "Invalid Date"; | |
| 326 sprintf(buf, "%04d-%02d-%02d", y, m+1, d); | |
| 327 return buf; | |
| 328 } | |
| 329 | |
| 330 static char *fmttime(char *buf, double t, double tza) | |
| 331 { | |
| 332 int H = HourFromTime(t); | |
| 333 int M = MinFromTime(t); | |
| 334 int S = SecFromTime(t); | |
| 335 int ms = msFromTime(t); | |
| 336 int tzh = HourFromTime(fabs(tza)); | |
| 337 int tzm = MinFromTime(fabs(tza)); | |
| 338 if (!isfinite(t)) | |
| 339 return "Invalid Date"; | |
| 340 if (tza == 0) | |
| 341 sprintf(buf, "%02d:%02d:%02d.%03dZ", H, M, S, ms); | |
| 342 else if (tza < 0) | |
| 343 sprintf(buf, "%02d:%02d:%02d.%03d-%02d:%02d", H, M, S, ms, tzh, tzm); | |
| 344 else | |
| 345 sprintf(buf, "%02d:%02d:%02d.%03d+%02d:%02d", H, M, S, ms, tzh, tzm); | |
| 346 return buf; | |
| 347 } | |
| 348 | |
| 349 static char *fmtdatetime(char *buf, double t, double tza) | |
| 350 { | |
| 351 char dbuf[20], tbuf[20]; | |
| 352 if (!isfinite(t)) | |
| 353 return "Invalid Date"; | |
| 354 fmtdate(dbuf, t); | |
| 355 fmttime(tbuf, t, tza); | |
| 356 sprintf(buf, "%sT%s", dbuf, tbuf); | |
| 357 return buf; | |
| 358 } | |
| 359 | |
| 360 /* Date functions */ | |
| 361 | |
| 362 static double js_todate(js_State *J, int idx) | |
| 363 { | |
| 364 js_Object *self = js_toobject(J, idx); | |
| 365 if (self->type != JS_CDATE) | |
| 366 js_typeerror(J, "not a date"); | |
| 367 return self->u.number; | |
| 368 } | |
| 369 | |
| 370 static void js_setdate(js_State *J, int idx, double t) | |
| 371 { | |
| 372 js_Object *self = js_toobject(J, idx); | |
| 373 if (self->type != JS_CDATE) | |
| 374 js_typeerror(J, "not a date"); | |
| 375 self->u.number = TimeClip(t); | |
| 376 js_pushnumber(J, self->u.number); | |
| 377 } | |
| 378 | |
| 379 static void D_parse(js_State *J) | |
| 380 { | |
| 381 double t = parseDateTime(js_tostring(J, 1)); | |
| 382 js_pushnumber(J, t); | |
| 383 } | |
| 384 | |
| 385 static void D_UTC(js_State *J) | |
| 386 { | |
| 387 double y, m, d, H, M, S, ms, t; | |
| 388 y = js_tonumber(J, 1); | |
| 389 if (y < 100) y += 1900; | |
| 390 m = js_tonumber(J, 2); | |
| 391 d = js_optnumber(J, 3, 1); | |
| 392 H = js_optnumber(J, 4, 0); | |
| 393 M = js_optnumber(J, 5, 0); | |
| 394 S = js_optnumber(J, 6, 0); | |
| 395 ms = js_optnumber(J, 7, 0); | |
| 396 t = MakeDate(MakeDay(y, m, d), MakeTime(H, M, S, ms)); | |
| 397 t = TimeClip(t); | |
| 398 js_pushnumber(J, t); | |
| 399 } | |
| 400 | |
| 401 static void D_now(js_State *J) | |
| 402 { | |
| 403 js_pushnumber(J, Now()); | |
| 404 } | |
| 405 | |
| 406 static void jsB_Date(js_State *J) | |
| 407 { | |
| 408 char buf[64]; | |
| 409 js_pushstring(J, fmtdatetime(buf, LocalTime(Now()), LocalTZA())); | |
| 410 } | |
| 411 | |
| 412 static void jsB_new_Date(js_State *J) | |
| 413 { | |
| 414 int top = js_gettop(J); | |
| 415 js_Object *obj; | |
| 416 double t; | |
| 417 | |
| 418 if (top == 1) | |
| 419 t = Now(); | |
| 420 else if (top == 2) { | |
| 421 js_toprimitive(J, 1, JS_HNONE); | |
| 422 if (js_isstring(J, 1)) | |
| 423 t = parseDateTime(js_tostring(J, 1)); | |
| 424 else | |
| 425 t = TimeClip(js_tonumber(J, 1)); | |
| 426 } else { | |
| 427 double y, m, d, H, M, S, ms; | |
| 428 y = js_tonumber(J, 1); | |
| 429 if (y < 100) y += 1900; | |
| 430 m = js_tonumber(J, 2); | |
| 431 d = js_optnumber(J, 3, 1); | |
| 432 H = js_optnumber(J, 4, 0); | |
| 433 M = js_optnumber(J, 5, 0); | |
| 434 S = js_optnumber(J, 6, 0); | |
| 435 ms = js_optnumber(J, 7, 0); | |
| 436 t = MakeDate(MakeDay(y, m, d), MakeTime(H, M, S, ms)); | |
| 437 t = TimeClip(UTC(t)); | |
| 438 } | |
| 439 | |
| 440 obj = jsV_newobject(J, JS_CDATE, J->Date_prototype); | |
| 441 obj->u.number = t; | |
| 442 | |
| 443 js_pushobject(J, obj); | |
| 444 } | |
| 445 | |
| 446 static void Dp_valueOf(js_State *J) | |
| 447 { | |
| 448 double t = js_todate(J, 0); | |
| 449 js_pushnumber(J, t); | |
| 450 } | |
| 451 | |
| 452 static void Dp_toString(js_State *J) | |
| 453 { | |
| 454 char buf[64]; | |
| 455 double t = js_todate(J, 0); | |
| 456 js_pushstring(J, fmtdatetime(buf, LocalTime(t), LocalTZA())); | |
| 457 } | |
| 458 | |
| 459 static void Dp_toDateString(js_State *J) | |
| 460 { | |
| 461 char buf[64]; | |
| 462 double t = js_todate(J, 0); | |
| 463 js_pushstring(J, fmtdate(buf, LocalTime(t))); | |
| 464 } | |
| 465 | |
| 466 static void Dp_toTimeString(js_State *J) | |
| 467 { | |
| 468 char buf[64]; | |
| 469 double t = js_todate(J, 0); | |
| 470 js_pushstring(J, fmttime(buf, LocalTime(t), LocalTZA())); | |
| 471 } | |
| 472 | |
| 473 static void Dp_toUTCString(js_State *J) | |
| 474 { | |
| 475 char buf[64]; | |
| 476 double t = js_todate(J, 0); | |
| 477 js_pushstring(J, fmtdatetime(buf, t, 0)); | |
| 478 } | |
| 479 | |
| 480 static void Dp_toISOString(js_State *J) | |
| 481 { | |
| 482 char buf[64]; | |
| 483 double t = js_todate(J, 0); | |
| 484 if (!isfinite(t)) | |
| 485 js_rangeerror(J, "invalid date"); | |
| 486 js_pushstring(J, fmtdatetime(buf, t, 0)); | |
| 487 } | |
| 488 | |
| 489 static void Dp_getFullYear(js_State *J) | |
| 490 { | |
| 491 double t = js_todate(J, 0); | |
| 492 if (isnan(t)) | |
| 493 js_pushnumber(J, NAN); | |
| 494 else | |
| 495 js_pushnumber(J, YearFromTime(LocalTime(t))); | |
| 496 } | |
| 497 | |
| 498 static void Dp_getMonth(js_State *J) | |
| 499 { | |
| 500 double t = js_todate(J, 0); | |
| 501 if (isnan(t)) | |
| 502 js_pushnumber(J, NAN); | |
| 503 else | |
| 504 js_pushnumber(J, MonthFromTime(LocalTime(t))); | |
| 505 } | |
| 506 | |
| 507 static void Dp_getDate(js_State *J) | |
| 508 { | |
| 509 double t = js_todate(J, 0); | |
| 510 if (isnan(t)) | |
| 511 js_pushnumber(J, NAN); | |
| 512 else | |
| 513 js_pushnumber(J, DateFromTime(LocalTime(t))); | |
| 514 } | |
| 515 | |
| 516 static void Dp_getDay(js_State *J) | |
| 517 { | |
| 518 double t = js_todate(J, 0); | |
| 519 if (isnan(t)) | |
| 520 js_pushnumber(J, NAN); | |
| 521 else | |
| 522 js_pushnumber(J, WeekDay(LocalTime(t))); | |
| 523 } | |
| 524 | |
| 525 static void Dp_getHours(js_State *J) | |
| 526 { | |
| 527 double t = js_todate(J, 0); | |
| 528 if (isnan(t)) | |
| 529 js_pushnumber(J, NAN); | |
| 530 else | |
| 531 js_pushnumber(J, HourFromTime(LocalTime(t))); | |
| 532 } | |
| 533 | |
| 534 static void Dp_getMinutes(js_State *J) | |
| 535 { | |
| 536 double t = js_todate(J, 0); | |
| 537 if (isnan(t)) | |
| 538 js_pushnumber(J, NAN); | |
| 539 else | |
| 540 js_pushnumber(J, MinFromTime(LocalTime(t))); | |
| 541 } | |
| 542 | |
| 543 static void Dp_getSeconds(js_State *J) | |
| 544 { | |
| 545 double t = js_todate(J, 0); | |
| 546 if (isnan(t)) | |
| 547 js_pushnumber(J, NAN); | |
| 548 else | |
| 549 js_pushnumber(J, SecFromTime(LocalTime(t))); | |
| 550 } | |
| 551 | |
| 552 static void Dp_getMilliseconds(js_State *J) | |
| 553 { | |
| 554 double t = js_todate(J, 0); | |
| 555 if (isnan(t)) | |
| 556 js_pushnumber(J, NAN); | |
| 557 else | |
| 558 js_pushnumber(J, msFromTime(LocalTime(t))); | |
| 559 } | |
| 560 | |
| 561 static void Dp_getUTCFullYear(js_State *J) | |
| 562 { | |
| 563 double t = js_todate(J, 0); | |
| 564 if (isnan(t)) | |
| 565 js_pushnumber(J, NAN); | |
| 566 else | |
| 567 js_pushnumber(J, YearFromTime(t)); | |
| 568 } | |
| 569 | |
| 570 static void Dp_getUTCMonth(js_State *J) | |
| 571 { | |
| 572 double t = js_todate(J, 0); | |
| 573 if (isnan(t)) | |
| 574 js_pushnumber(J, NAN); | |
| 575 else | |
| 576 js_pushnumber(J, MonthFromTime(t)); | |
| 577 } | |
| 578 | |
| 579 static void Dp_getUTCDate(js_State *J) | |
| 580 { | |
| 581 double t = js_todate(J, 0); | |
| 582 if (isnan(t)) | |
| 583 js_pushnumber(J, NAN); | |
| 584 else | |
| 585 js_pushnumber(J, DateFromTime(t)); | |
| 586 } | |
| 587 | |
| 588 static void Dp_getUTCDay(js_State *J) | |
| 589 { | |
| 590 double t = js_todate(J, 0); | |
| 591 if (isnan(t)) | |
| 592 js_pushnumber(J, NAN); | |
| 593 else | |
| 594 js_pushnumber(J, WeekDay(t)); | |
| 595 } | |
| 596 | |
| 597 static void Dp_getUTCHours(js_State *J) | |
| 598 { | |
| 599 double t = js_todate(J, 0); | |
| 600 if (isnan(t)) | |
| 601 js_pushnumber(J, NAN); | |
| 602 else | |
| 603 js_pushnumber(J, HourFromTime(t)); | |
| 604 } | |
| 605 | |
| 606 static void Dp_getUTCMinutes(js_State *J) | |
| 607 { | |
| 608 double t = js_todate(J, 0); | |
| 609 if (isnan(t)) | |
| 610 js_pushnumber(J, NAN); | |
| 611 else | |
| 612 js_pushnumber(J, MinFromTime(t)); | |
| 613 } | |
| 614 | |
| 615 static void Dp_getUTCSeconds(js_State *J) | |
| 616 { | |
| 617 double t = js_todate(J, 0); | |
| 618 if (isnan(t)) | |
| 619 js_pushnumber(J, NAN); | |
| 620 else | |
| 621 js_pushnumber(J, SecFromTime(t)); | |
| 622 } | |
| 623 | |
| 624 static void Dp_getUTCMilliseconds(js_State *J) | |
| 625 { | |
| 626 double t = js_todate(J, 0); | |
| 627 if (isnan(t)) | |
| 628 js_pushnumber(J, NAN); | |
| 629 else | |
| 630 js_pushnumber(J, msFromTime(t)); | |
| 631 } | |
| 632 | |
| 633 static void Dp_getTimezoneOffset(js_State *J) | |
| 634 { | |
| 635 double t = js_todate(J, 0); | |
| 636 if (isnan(t)) | |
| 637 js_pushnumber(J, NAN); | |
| 638 else | |
| 639 js_pushnumber(J, (t - LocalTime(t)) / msPerMinute); | |
| 640 } | |
| 641 | |
| 642 static void Dp_setTime(js_State *J) | |
| 643 { | |
| 644 js_setdate(J, 0, js_tonumber(J, 1)); | |
| 645 } | |
| 646 | |
| 647 static void Dp_setMilliseconds(js_State *J) | |
| 648 { | |
| 649 double t = LocalTime(js_todate(J, 0)); | |
| 650 double h = HourFromTime(t); | |
| 651 double m = MinFromTime(t); | |
| 652 double s = SecFromTime(t); | |
| 653 double ms = js_tonumber(J, 1); | |
| 654 js_setdate(J, 0, UTC(MakeDate(Day(t), MakeTime(h, m, s, ms)))); | |
| 655 } | |
| 656 | |
| 657 static void Dp_setSeconds(js_State *J) | |
| 658 { | |
| 659 double t = LocalTime(js_todate(J, 0)); | |
| 660 double h = HourFromTime(t); | |
| 661 double m = MinFromTime(t); | |
| 662 double s = js_tonumber(J, 1); | |
| 663 double ms = js_optnumber(J, 2, msFromTime(t)); | |
| 664 js_setdate(J, 0, UTC(MakeDate(Day(t), MakeTime(h, m, s, ms)))); | |
| 665 } | |
| 666 | |
| 667 static void Dp_setMinutes(js_State *J) | |
| 668 { | |
| 669 double t = LocalTime(js_todate(J, 0)); | |
| 670 double h = HourFromTime(t); | |
| 671 double m = js_tonumber(J, 1); | |
| 672 double s = js_optnumber(J, 2, SecFromTime(t)); | |
| 673 double ms = js_optnumber(J, 3, msFromTime(t)); | |
| 674 js_setdate(J, 0, UTC(MakeDate(Day(t), MakeTime(h, m, s, ms)))); | |
| 675 } | |
| 676 | |
| 677 static void Dp_setHours(js_State *J) | |
| 678 { | |
| 679 double t = LocalTime(js_todate(J, 0)); | |
| 680 double h = js_tonumber(J, 1); | |
| 681 double m = js_optnumber(J, 2, MinFromTime(t)); | |
| 682 double s = js_optnumber(J, 3, SecFromTime(t)); | |
| 683 double ms = js_optnumber(J, 4, msFromTime(t)); | |
| 684 js_setdate(J, 0, UTC(MakeDate(Day(t), MakeTime(h, m, s, ms)))); | |
| 685 } | |
| 686 | |
| 687 static void Dp_setDate(js_State *J) | |
| 688 { | |
| 689 double t = LocalTime(js_todate(J, 0)); | |
| 690 double y = YearFromTime(t); | |
| 691 double m = MonthFromTime(t); | |
| 692 double d = js_tonumber(J, 1); | |
| 693 js_setdate(J, 0, UTC(MakeDate(MakeDay(y, m, d), TimeWithinDay(t)))); | |
| 694 } | |
| 695 | |
| 696 static void Dp_setMonth(js_State *J) | |
| 697 { | |
| 698 double t = LocalTime(js_todate(J, 0)); | |
| 699 double y = YearFromTime(t); | |
| 700 double m = js_tonumber(J, 1); | |
| 701 double d = js_optnumber(J, 2, DateFromTime(t)); | |
| 702 js_setdate(J, 0, UTC(MakeDate(MakeDay(y, m, d), TimeWithinDay(t)))); | |
| 703 } | |
| 704 | |
| 705 static void Dp_setFullYear(js_State *J) | |
| 706 { | |
| 707 double t = LocalTime(js_todate(J, 0)); | |
| 708 double y = js_tonumber(J, 1); | |
| 709 double m = js_optnumber(J, 2, MonthFromTime(t)); | |
| 710 double d = js_optnumber(J, 3, DateFromTime(t)); | |
| 711 js_setdate(J, 0, UTC(MakeDate(MakeDay(y, m, d), TimeWithinDay(t)))); | |
| 712 } | |
| 713 | |
| 714 static void Dp_setUTCMilliseconds(js_State *J) | |
| 715 { | |
| 716 double t = js_todate(J, 0); | |
| 717 double h = HourFromTime(t); | |
| 718 double m = MinFromTime(t); | |
| 719 double s = SecFromTime(t); | |
| 720 double ms = js_tonumber(J, 1); | |
| 721 js_setdate(J, 0, MakeDate(Day(t), MakeTime(h, m, s, ms))); | |
| 722 } | |
| 723 | |
| 724 static void Dp_setUTCSeconds(js_State *J) | |
| 725 { | |
| 726 double t = js_todate(J, 0); | |
| 727 double h = HourFromTime(t); | |
| 728 double m = MinFromTime(t); | |
| 729 double s = js_tonumber(J, 1); | |
| 730 double ms = js_optnumber(J, 2, msFromTime(t)); | |
| 731 js_setdate(J, 0, MakeDate(Day(t), MakeTime(h, m, s, ms))); | |
| 732 } | |
| 733 | |
| 734 static void Dp_setUTCMinutes(js_State *J) | |
| 735 { | |
| 736 double t = js_todate(J, 0); | |
| 737 double h = HourFromTime(t); | |
| 738 double m = js_tonumber(J, 1); | |
| 739 double s = js_optnumber(J, 2, SecFromTime(t)); | |
| 740 double ms = js_optnumber(J, 3, msFromTime(t)); | |
| 741 js_setdate(J, 0, MakeDate(Day(t), MakeTime(h, m, s, ms))); | |
| 742 } | |
| 743 | |
| 744 static void Dp_setUTCHours(js_State *J) | |
| 745 { | |
| 746 double t = js_todate(J, 0); | |
| 747 double h = js_tonumber(J, 1); | |
| 748 double m = js_optnumber(J, 2, HourFromTime(t)); | |
| 749 double s = js_optnumber(J, 3, SecFromTime(t)); | |
| 750 double ms = js_optnumber(J, 4, msFromTime(t)); | |
| 751 js_setdate(J, 0, MakeDate(Day(t), MakeTime(h, m, s, ms))); | |
| 752 } | |
| 753 | |
| 754 static void Dp_setUTCDate(js_State *J) | |
| 755 { | |
| 756 double t = js_todate(J, 0); | |
| 757 double y = YearFromTime(t); | |
| 758 double m = MonthFromTime(t); | |
| 759 double d = js_tonumber(J, 1); | |
| 760 js_setdate(J, 0, MakeDate(MakeDay(y, m, d), TimeWithinDay(t))); | |
| 761 } | |
| 762 | |
| 763 static void Dp_setUTCMonth(js_State *J) | |
| 764 { | |
| 765 double t = js_todate(J, 0); | |
| 766 double y = YearFromTime(t); | |
| 767 double m = js_tonumber(J, 1); | |
| 768 double d = js_optnumber(J, 2, DateFromTime(t)); | |
| 769 js_setdate(J, 0, MakeDate(MakeDay(y, m, d), TimeWithinDay(t))); | |
| 770 } | |
| 771 | |
| 772 static void Dp_setUTCFullYear(js_State *J) | |
| 773 { | |
| 774 double t = js_todate(J, 0); | |
| 775 double y = js_tonumber(J, 1); | |
| 776 double m = js_optnumber(J, 2, MonthFromTime(t)); | |
| 777 double d = js_optnumber(J, 3, DateFromTime(t)); | |
| 778 js_setdate(J, 0, MakeDate(MakeDay(y, m, d), TimeWithinDay(t))); | |
| 779 } | |
| 780 | |
| 781 static void Dp_toJSON(js_State *J) | |
| 782 { | |
| 783 js_copy(J, 0); | |
| 784 js_toprimitive(J, -1, JS_HNUMBER); | |
| 785 if (js_isnumber(J, -1) && !isfinite(js_tonumber(J, -1))) { | |
| 786 js_pushnull(J); | |
| 787 return; | |
| 788 } | |
| 789 js_pop(J, 1); | |
| 790 | |
| 791 js_getproperty(J, 0, "toISOString"); | |
| 792 if (!js_iscallable(J, -1)) | |
| 793 js_typeerror(J, "this.toISOString is not a function"); | |
| 794 js_copy(J, 0); | |
| 795 js_call(J, 0); | |
| 796 } | |
| 797 | |
| 798 void jsB_initdate(js_State *J) | |
| 799 { | |
| 800 J->Date_prototype->u.number = 0; | |
| 801 | |
| 802 js_pushobject(J, J->Date_prototype); | |
| 803 { | |
| 804 jsB_propf(J, "Date.prototype.valueOf", Dp_valueOf, 0); | |
| 805 jsB_propf(J, "Date.prototype.toString", Dp_toString, 0); | |
| 806 jsB_propf(J, "Date.prototype.toDateString", Dp_toDateString, 0); | |
| 807 jsB_propf(J, "Date.prototype.toTimeString", Dp_toTimeString, 0); | |
| 808 jsB_propf(J, "Date.prototype.toLocaleString", Dp_toString, 0); | |
| 809 jsB_propf(J, "Date.prototype.toLocaleDateString", Dp_toDateString, 0); | |
| 810 jsB_propf(J, "Date.prototype.toLocaleTimeString", Dp_toTimeString, 0); | |
| 811 jsB_propf(J, "Date.prototype.toUTCString", Dp_toUTCString, 0); | |
| 812 | |
| 813 jsB_propf(J, "Date.prototype.getTime", Dp_valueOf, 0); | |
| 814 jsB_propf(J, "Date.prototype.getFullYear", Dp_getFullYear, 0); | |
| 815 jsB_propf(J, "Date.prototype.getUTCFullYear", Dp_getUTCFullYear, 0); | |
| 816 jsB_propf(J, "Date.prototype.getMonth", Dp_getMonth, 0); | |
| 817 jsB_propf(J, "Date.prototype.getUTCMonth", Dp_getUTCMonth, 0); | |
| 818 jsB_propf(J, "Date.prototype.getDate", Dp_getDate, 0); | |
| 819 jsB_propf(J, "Date.prototype.getUTCDate", Dp_getUTCDate, 0); | |
| 820 jsB_propf(J, "Date.prototype.getDay", Dp_getDay, 0); | |
| 821 jsB_propf(J, "Date.prototype.getUTCDay", Dp_getUTCDay, 0); | |
| 822 jsB_propf(J, "Date.prototype.getHours", Dp_getHours, 0); | |
| 823 jsB_propf(J, "Date.prototype.getUTCHours", Dp_getUTCHours, 0); | |
| 824 jsB_propf(J, "Date.prototype.getMinutes", Dp_getMinutes, 0); | |
| 825 jsB_propf(J, "Date.prototype.getUTCMinutes", Dp_getUTCMinutes, 0); | |
| 826 jsB_propf(J, "Date.prototype.getSeconds", Dp_getSeconds, 0); | |
| 827 jsB_propf(J, "Date.prototype.getUTCSeconds", Dp_getUTCSeconds, 0); | |
| 828 jsB_propf(J, "Date.prototype.getMilliseconds", Dp_getMilliseconds, 0); | |
| 829 jsB_propf(J, "Date.prototype.getUTCMilliseconds", Dp_getUTCMilliseconds, 0); | |
| 830 jsB_propf(J, "Date.prototype.getTimezoneOffset", Dp_getTimezoneOffset, 0); | |
| 831 | |
| 832 jsB_propf(J, "Date.prototype.setTime", Dp_setTime, 1); | |
| 833 jsB_propf(J, "Date.prototype.setMilliseconds", Dp_setMilliseconds, 1); | |
| 834 jsB_propf(J, "Date.prototype.setUTCMilliseconds", Dp_setUTCMilliseconds, 1); | |
| 835 jsB_propf(J, "Date.prototype.setSeconds", Dp_setSeconds, 2); | |
| 836 jsB_propf(J, "Date.prototype.setUTCSeconds", Dp_setUTCSeconds, 2); | |
| 837 jsB_propf(J, "Date.prototype.setMinutes", Dp_setMinutes, 3); | |
| 838 jsB_propf(J, "Date.prototype.setUTCMinutes", Dp_setUTCMinutes, 3); | |
| 839 jsB_propf(J, "Date.prototype.setHours", Dp_setHours, 4); | |
| 840 jsB_propf(J, "Date.prototype.setUTCHours", Dp_setUTCHours, 4); | |
| 841 jsB_propf(J, "Date.prototype.setDate", Dp_setDate, 1); | |
| 842 jsB_propf(J, "Date.prototype.setUTCDate", Dp_setUTCDate, 1); | |
| 843 jsB_propf(J, "Date.prototype.setMonth", Dp_setMonth, 2); | |
| 844 jsB_propf(J, "Date.prototype.setUTCMonth", Dp_setUTCMonth, 2); | |
| 845 jsB_propf(J, "Date.prototype.setFullYear", Dp_setFullYear, 3); | |
| 846 jsB_propf(J, "Date.prototype.setUTCFullYear", Dp_setUTCFullYear, 3); | |
| 847 | |
| 848 /* ES5 */ | |
| 849 jsB_propf(J, "Date.prototype.toISOString", Dp_toISOString, 0); | |
| 850 jsB_propf(J, "Date.prototype.toJSON", Dp_toJSON, 1); | |
| 851 } | |
| 852 js_newcconstructor(J, jsB_Date, jsB_new_Date, "Date", 0); /* 1 */ | |
| 853 { | |
| 854 jsB_propf(J, "Date.parse", D_parse, 1); | |
| 855 jsB_propf(J, "Date.UTC", D_UTC, 7); | |
| 856 | |
| 857 /* ES5 */ | |
| 858 jsB_propf(J, "Date.now", D_now, 0); | |
| 859 } | |
| 860 js_defglobal(J, "Date", JS_DONTENUM); | |
| 861 } |
