jsdate.c
来自「一个基于alice开发的机器人」· C语言 代码 · 共 2,235 行 · 第 1/4 页
C
2,235 行
int mon = -1;
int mday = -1;
int hour = -1;
int min = -1;
int sec = -1;
int c = -1;
int n = -1;
jsdouble tzoffset = -1; /* was an int, overflowed on win16!!! */
int prevc = 0;
JSBool seenplusminus = JS_FALSE;
if (limit == 0)
goto syntax;
while (i < limit) {
c = s[i];
i++;
if (c <= ' ' || c == ',' || c == '-') {
if (c == '-' && '0' <= s[i] && s[i] <= '9') {
prevc = c;
}
continue;
}
if (c == '(') { /* comments) */
int depth = 1;
while (i < limit) {
c = s[i];
i++;
if (c == '(') depth++;
else if (c == ')')
if (--depth <= 0)
break;
}
continue;
}
if ('0' <= c && c <= '9') {
n = c - '0';
while (i < limit && '0' <= (c = s[i]) && c <= '9') {
n = n * 10 + c - '0';
i++;
}
/* allow TZA before the year, so
* 'Wed Nov 05 21:49:11 GMT-0800 1997'
* works */
/* uses of seenplusminus allow : in TZA, so Java
* no-timezone style of GMT+4:30 works
*/
if ((prevc == '+' || prevc == '-')/* && year>=0 */) {
/* make ':' case below change tzoffset */
seenplusminus = JS_TRUE;
/* offset */
if (n < 24)
n = n * 60; /* EG. "GMT-3" */
else
n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
if (prevc == '+') /* plus means east of GMT */
n = -n;
if (tzoffset != 0 && tzoffset != -1)
goto syntax;
tzoffset = n;
} else if (n >= 70 ||
(prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) {
if (year >= 0)
goto syntax;
else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
year = n < 100 ? n + 1900 : n;
else
goto syntax;
} else if (c == ':') {
if (hour < 0)
hour = /*byte*/ n;
else if (min < 0)
min = /*byte*/ n;
else
goto syntax;
} else if (c == '/') {
if (mon < 0)
mon = /*byte*/ n-1;
else if (mday < 0)
mday = /*byte*/ n;
else
goto syntax;
} else if (i < limit && c != ',' && c > ' ' && c != '-') {
goto syntax;
} else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
if (tzoffset < 0)
tzoffset -= n;
else
tzoffset += n;
} else if (hour >= 0 && min < 0) {
min = /*byte*/ n;
} else if (min >= 0 && sec < 0) {
sec = /*byte*/ n;
} else if (mday < 0) {
mday = /*byte*/ n;
} else {
goto syntax;
}
prevc = 0;
} else if (c == '/' || c == ':' || c == '+' || c == '-') {
prevc = c;
} else {
size_t st = i - 1;
int k;
while (i < limit) {
c = s[i];
if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
break;
i++;
}
if (i <= st + 1)
goto syntax;
for (k = (sizeof(wtb)/sizeof(char*)); --k >= 0;)
if (date_regionMatches(wtb[k], 0, s, st, i-st, 1)) {
int action = ttb[k];
if (action != 0) {
if (action < 0) {
/*
* AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
* 12:30, instead of blindly adding 12 if PM.
*/
JS_ASSERT(action == -1 || action == -2);
if (hour > 12 || hour < 0) {
goto syntax;
} else {
if (action == -1 && hour == 12) { /* am */
hour = 0;
} else if (action == -2 && hour != 12) { /* pm */
hour += 12;
}
}
} else if (action <= 13) { /* month! */
if (mon < 0) {
mon = /*byte*/ (action - 2);
} else {
goto syntax;
}
} else {
tzoffset = action - 10000;
}
}
break;
}
if (k < 0)
goto syntax;
prevc = 0;
}
}
if (year < 0 || mon < 0 || mday < 0)
goto syntax;
if (sec < 0)
sec = 0;
if (min < 0)
min = 0;
if (hour < 0)
hour = 0;
if (tzoffset == -1) { /* no time zone specified, have to use local */
jsdouble msec_time;
msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
*result = UTC(msec_time);
return JS_TRUE;
}
msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
msec += tzoffset * msPerMinute;
*result = msec;
return JS_TRUE;
syntax:
/* syntax error */
*result = 0;
return JS_FALSE;
}
static JSBool
date_parse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSString *str;
jsdouble result;
str = js_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
if (!date_parseString(str, &result)) {
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
return JS_TRUE;
}
result = TIMECLIP(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_now(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
int64 us, ms, us2ms;
jsdouble msec_time;
us = PRMJ_Now();
JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
JSLL_DIV(ms, us, us2ms);
JSLL_L2D(msec_time, ms);
return js_NewDoubleValue(cx, msec_time, rval);
}
/*
* Check that obj is an object of class Date, and get the date value.
* Return NULL on failure.
*/
static jsdouble *
date_getProlog(JSContext *cx, JSObject *obj, jsval *argv)
{
if (!JS_InstanceOf(cx, obj, &date_class, argv))
return NULL;
return JSVAL_TO_DOUBLE(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE));
}
/*
* See ECMA 15.9.5.4 thru 15.9.5.23
*/
static JSBool
date_getTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
return js_NewNumberValue(cx, *date, rval);
}
static JSBool
date_getYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = YearFromTime(LocalTime(result));
/*
* During the great date rewrite of 1.3, we tried to track the evolving ECMA
* standard, which then had a definition of getYear which always subtracted
* 1900. Which we implemented, not realizing that it was incompatible with
* the old behavior... now, rather than thrash the behavior yet again,
* we've decided to leave it with the - 1900 behavior and point people to
* the getFullYear method. But we try to protect existing scripts that
* have specified a version...
*/
if (cx->version == JSVERSION_1_0 ||
cx->version == JSVERSION_1_1 ||
cx->version == JSVERSION_1_2)
{
if (result >= 1900 && result < 2000)
result -= 1900;
} else {
result -= 1900;
}
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = YearFromTime(LocalTime(result));
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getUTCFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = YearFromTime(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = MonthFromTime(LocalTime(result));
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getUTCMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = MonthFromTime(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = LocalTime(result);
result = DateFromTime(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getUTCDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = DateFromTime(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = LocalTime(result);
result = WeekDay(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getUTCDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = WeekDay(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = HourFromTime(LocalTime(result));
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getUTCHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = HourFromTime(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = MinFromTime(LocalTime(result));
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getUTCMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = MinFromTime(result);
return js_NewNumberValue(cx, result, rval);
}
/* Date.getSeconds is mapped to getUTCSeconds */
static JSBool
date_getUTCSeconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = SecFromTime(result);
return js_NewNumberValue(cx, result, rval);
}
/* Date.getMilliseconds is mapped to getUTCMilliseconds */
static JSBool
date_getUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
result = msFromTime(result);
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_getTimezoneOffset(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
/*
* Return the time zone offset in minutes for the current locale
* that is appropriate for this time. This value would be a
* constant except for daylight savings time.
*/
result = (result - LocalTime(result)) / msPerMinute;
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_setTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
if (!js_ValueToNumber(cx, argv[0], &result))
return JS_FALSE;
result = TIMECLIP(result);
*date = result;
return js_NewNumberValue(cx, result, rval);
}
static JSBool
date_makeTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
uintN maxargs, JSBool local, jsval *rval)
{
uintN i;
jsdouble args[4], *argp, *stop;
jsdouble hour, min, sec, msec;
jsdouble lorutime; /* Local or UTC version of *date */
jsdouble msec_time;
jsdouble result;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?