JavaScript-QuickJS
view release on metacpan or search on metacpan
quickjs/quickjs.c view on Meta::CPAN
JS_PROP_DOUBLE_DEF("Infinity", 1.0 / 0.0, 0 ),
JS_PROP_DOUBLE_DEF("NaN", NAN, 0 ),
JS_PROP_UNDEFINED_DEF("undefined", 0 ),
};
/* Date */
static int64_t math_mod(int64_t a, int64_t b) {
/* return positive modulo */
int64_t m = a % b;
return m + (m < 0) * b;
}
static int64_t floor_div(int64_t a, int64_t b) {
/* integer division rounding toward -Infinity */
int64_t m = a % b;
return (a - (m + (m < 0) * b)) / b;
}
static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv);
static __exception int JS_ThisTimeValue(JSContext *ctx, double *valp, JSValueConst this_val)
{
if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) {
JSObject *p = JS_VALUE_GET_OBJ(this_val);
if (p->class_id == JS_CLASS_DATE && JS_IsNumber(p->u.object_data))
return JS_ToFloat64(ctx, valp, p->u.object_data);
}
JS_ThrowTypeError(ctx, "not a Date object");
return -1;
}
static JSValue JS_SetThisTimeValue(JSContext *ctx, JSValueConst this_val, double v)
{
if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) {
JSObject *p = JS_VALUE_GET_OBJ(this_val);
if (p->class_id == JS_CLASS_DATE) {
JS_FreeValue(ctx, p->u.object_data);
p->u.object_data = JS_NewFloat64(ctx, v);
return JS_DupValue(ctx, p->u.object_data);
}
}
return JS_ThrowTypeError(ctx, "not a Date object");
}
static int64_t days_from_year(int64_t y) {
return 365 * (y - 1970) + floor_div(y - 1969, 4) -
floor_div(y - 1901, 100) + floor_div(y - 1601, 400);
}
static int64_t days_in_year(int64_t y) {
return 365 + !(y % 4) - !(y % 100) + !(y % 400);
}
/* return the year, update days */
static int64_t year_from_days(int64_t *days) {
int64_t y, d1, nd, d = *days;
y = floor_div(d * 10000, 3652425) + 1970;
/* the initial approximation is very good, so only a few
iterations are necessary */
for(;;) {
d1 = d - days_from_year(y);
if (d1 < 0) {
y--;
d1 += days_in_year(y);
} else {
nd = days_in_year(y);
if (d1 < nd)
break;
d1 -= nd;
y++;
}
}
*days = d1;
return y;
}
static int const month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static char const month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
static char const day_names[] = "SunMonTueWedThuFriSat";
static __exception int get_date_fields(JSContext *ctx, JSValueConst obj,
double fields[9], int is_local, int force)
{
double dval;
int64_t d, days, wd, y, i, md, h, m, s, ms, tz = 0;
if (JS_ThisTimeValue(ctx, &dval, obj))
return -1;
if (isnan(dval)) {
if (!force)
return FALSE; /* NaN */
d = 0; /* initialize all fields to 0 */
} else {
d = dval;
if (is_local) {
tz = -getTimezoneOffset(d);
d += tz * 60000;
}
}
/* result is >= 0, we can use % */
h = math_mod(d, 86400000);
days = (d - h) / 86400000;
ms = h % 1000;
h = (h - ms) / 1000;
s = h % 60;
h = (h - s) / 60;
m = h % 60;
h = (h - m) / 60;
wd = math_mod(days + 4, 7); /* week day */
y = year_from_days(&days);
for(i = 0; i < 11; i++) {
md = month_days[i];
if (i == 1)
md += days_in_year(y) - 365;
if (days < md)
break;
( run in 1.133 second using v1.01-cache-2.11-cpan-71847e10f99 )