FreeWRL
view release on metacpan or search on metacpan
JS/js/jsdate.c view on Meta::CPAN
if (d <= (next = 30))
return d + 1;
step = next;
next += (InLeapYear(t) ? 29 : 28);
if (d <= next)
return d - step;
step = next;
if (d <= (next += 31))
return d - step;
step = next;
if (d <= (next += 30))
return d - step;
step = next;
if (d <= (next += 31))
return d - step;
step = next;
if (d <= (next += 30))
return d - step;
step = next;
if (d <= (next += 31))
return d - step;
step = next;
if (d <= (next += 31))
return d - step;
step = next;
if (d <= (next += 30))
return d - step;
step = next;
if (d <= (next += 31))
return d - step;
step = next;
if (d <= (next += 30))
return d - step;
step = next;
return d - step;
}
static intN
WeekDay(jsdouble t)
{
jsint result;
result = (jsint) Day(t) + 4;
result = result % 7;
if (result < 0)
result += 7;
return (intN) result;
}
/* LocalTZA gets set by js_InitDateClass() */
static jsdouble LocalTZA;
static jsdouble
DaylightSavingTA(jsdouble t)
{
int64 PR_t;
int64 ms2us;
int64 offset;
jsdouble result;
/* abort if NaN */
if (JSDOUBLE_IS_NaN(t))
return t;
/* put our t in an LL, and map it to usec for prtime */
LL_D2L(PR_t, t);
LL_I2L(ms2us, PR_USEC_PER_MSEC);
LL_MUL(PR_t, PR_t, ms2us);
offset = PR_DSTOffset(PR_t);
LL_DIV(offset, offset, ms2us);
LL_L2D(result, offset);
return result;
}
#define LocalTime(t) ((t) + LocalTZA + DaylightSavingTA(t))
static jsdouble
UTC(jsdouble t)
{
return t - LocalTZA - DaylightSavingTA(t - LocalTZA);
}
static intN
HourFromTime(jsdouble t)
{
intN result = (intN) fmod(floor(t/msPerHour), HoursPerDay);
if (result < 0)
result += (intN)HoursPerDay;
return result;
}
static intN
MinFromTime(jsdouble t)
{
intN result = (intN) fmod(floor(t / msPerMinute), MinutesPerHour);
if (result < 0)
result += (intN)MinutesPerHour;
return result;
}
static intN
SecFromTime(jsdouble t)
{
intN result = (intN) fmod(floor(t / msPerSecond), SecondsPerMinute);
if (result < 0)
result += (intN)SecondsPerMinute;
return result;
}
static intN
msFromTime(jsdouble t)
{
intN result = (intN) fmod(t, msPerSecond);
if (result < 0)
result += (intN)msPerSecond;
return result;
}
#define MakeTime(hour, min, sec, ms) \
(((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms)
static jsdouble
MakeDay(jsdouble year, jsdouble month, jsdouble date)
{
jsdouble result;
JSBool leap;
jsdouble yearday;
jsdouble monthday;
year += floor(month / 12);
month = fmod(month, 12);
if (month < 0)
month += 12;
leap = (DaysInYear((jsint) year) == 366);
yearday = floor(TimeFromYear(year) / msPerDay);
monthday = DayFromMonth(month, leap);
result = yearday
+ monthday
+ date - 1;
return result;
}
#define MakeDate(day, time) (day * msPerDay + time)
#define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \
&& !((d < 0 ? -d : d) > HalfTimeDomain)) \
? js_DoubleToInteger(d + (+0.)) : *(cx->runtime->jsNaN))
/**
* end of ECMA 'support' functions
*/
/*
* Other Support routines and definitions
*/
static JSClass date_class = {
"Date",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
/* for use by date_parse */
static char* wtb[] = {
"am", "pm",
"monday", "tuesday", "wednesday", "thursday", "friday",
"saturday", "sunday",
"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december",
"gmt", "ut", "utc",
"est", "edt",
"cst", "cdt",
"mst", "mdt",
"pst", "pdt"
/* time zone table needs to be expanded */
};
static int ttb[] = {
0, 1, 0, 0, 0, 0, 0, 0, 0,
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
10000 + 0, 10000 + 0, 10000 + 0, /* GMT/UT/UTC */
10000 + 5 * 60, 10000 + 4 * 60, /* EST/EDT */
10000 + 6 * 60, 10000 + 5 * 60, /* CST/CDT */
10000 + 7 * 60, 10000 + 6 * 60, /* MST/MDT */
10000 + 8 * 60, 10000 + 7 * 60 /* PST/PDT */
};
/* helper for date_parse */
static JSBool
date_regionMatches(const char* s1, int s1off, const jschar* s2, int s2off,
int count, int ignoreCase)
{
JSBool result = JS_FALSE;
/* return true if matches, otherwise, false */
while (count > 0 && s1[s1off] && s2[s2off]) {
if (ignoreCase) {
if (JS_TOLOWER((jschar)s1[s1off]) != JS_TOLOWER(s2[s2off])) {
break;
}
} else {
if ((jschar)s1[s1off] != s2[s2off]) {
break;
}
}
s1off++;
s2off++;
count--;
}
if (count == 0) {
result = JS_TRUE;
}
return result;
}
/* find UTC time from given date... no 1900 correction! */
static jsdouble
date_msecFromDate(jsdouble year, jsdouble mon, jsdouble mday, jsdouble hour,
jsdouble min, jsdouble sec, jsdouble msec)
{
jsdouble day;
jsdouble time;
jsdouble result;
day = MakeDay(year, mon, mday);
time = MakeTime(hour, min, sec, msec);
result = MakeDate(day, time);
return result;
}
/*
* See ECMA 15.9.4.[3-10];
*/
/* XXX this function must be above date_parseString to avoid a
horrid bug in the Win16 1.52 compiler */
#define MAXARGS 7
static JSBool
date_UTC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble array[MAXARGS];
uintN loop;
jsdouble d;
for (loop = 0; loop < MAXARGS; loop++) {
if (loop < argc) {
if (!js_ValueToNumber(cx, argv[loop], &d))
return JS_FALSE;
/* return NaN if any arg is NaN */
if (!JSDOUBLE_IS_FINITE(d)) {
return js_NewNumberValue(cx, d, rval);
}
array[loop] = floor(d);
} else {
array[loop] = 0;
}
}
/* adjust 2-digit years into the 20th century */
if (array[0] >= 0 && array[0] <= 99)
array[0] += 1900;
/* if we got a 0 for 'date' (which is out of range)
* pretend it's a 1. (So Date.UTC(1972, 5) works) */
if (array[2] < 1)
array[2] = 1;
d = date_msecFromDate(array[0], array[1], array[2],
array[3], array[4], array[5], array[6]);
d = TIMECLIP(d);
return js_NewNumberValue(cx, d, rval);
}
static JSBool
date_parseString(const jschar *s, jsdouble *result)
{
jsdouble msec;
int year = -1;
int mon = -1;
int mday = -1;
int hour = -1;
int min = -1;
int sec = -1;
int c = -1;
int i = 0;
int n = -1;
jsdouble tzoffset = -1; /* was an int, overflowed on win16!!! */
int prevc = 0;
int limit = 0;
JSBool seenplusminus = JS_FALSE;
if (s == 0)
goto syntax;
limit = js_strlen(s);
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];
JS/js/jsdate.c view on Meta::CPAN
if (action == 1) { /* pm */
if (hour > 12 || hour < 0) {
goto syntax;
} else {
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 time;
time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
*result = UTC(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->chars, &result)) {
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
return JS_TRUE;
}
result = TIMECLIP(result);
return js_NewNumberValue(cx, result, 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));
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))
JS/js/jsdate.c view on Meta::CPAN
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 time;
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
/* just return NaN if the date is already NaN */
if (!JSDOUBLE_IS_FINITE(result))
return js_NewNumberValue(cx, result, rval);
/* Satisfy the ECMA rule that if a function is called with
* fewer arguments than the specified formal arguments, the
* remaining arguments are set to undefined. Seems like all
* the Date.setWhatever functions in ECMA are only varargs
* beyond the first argument; this should be set to undefined
* if it's not given. This means that "d = new Date();
* d.setMilliseconds()" returns NaN. Blech.
*/
if (argc == 0)
argc = 1; /* should be safe, because length of all settors is 1 */
else if (argc > maxargs)
argc = maxargs; /* clamp argc */
for (i = 0; i < argc; i++) {
if (!js_ValueToNumber(cx, argv[i], &args[i]))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(args[i])) {
*date = *(cx->runtime->jsNaN);
return js_NewNumberValue(cx, *date, rval);
}
args[i] = js_DoubleToInteger(args[i]);
}
if (local)
lorutime = LocalTime(result);
else
lorutime = result;
argp = args;
stop = argp + argc;
if (maxargs >= 4 && argp < stop)
hour = *argp++;
else
hour = HourFromTime(lorutime);
if (maxargs >= 3 && argp < stop)
min = *argp++;
else
min = MinFromTime(lorutime);
if (maxargs >= 2 && argp < stop)
sec = *argp++;
else
sec = SecFromTime(lorutime);
if (maxargs >= 1 && argp < stop)
msec = *argp;
else
msec = msFromTime(lorutime);
time = MakeTime(hour, min, sec, msec);
result = MakeDate(Day(lorutime), time);
/* fprintf(stderr, "%f\n", result); */
if (local)
result = UTC(result);
/* fprintf(stderr, "%f\n", result); */
*date = TIMECLIP(result);
return js_NewNumberValue(cx, *date, rval);
}
static JSBool
date_setMilliseconds(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeTime(cx, obj, argc, argv, 1, JS_TRUE, rval);
}
static JSBool
date_setUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeTime(cx, obj, argc, argv, 1, JS_FALSE, rval);
}
JS/js/jsdate.c view on Meta::CPAN
date_setUTCSeconds(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeTime(cx, obj, argc, argv, 2, JS_FALSE, rval);
}
static JSBool
date_setMinutes(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeTime(cx, obj, argc, argv, 3, JS_TRUE, rval);
}
static JSBool
date_setUTCMinutes(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeTime(cx, obj, argc, argv, 3, JS_FALSE, rval);
}
static JSBool
date_setHours(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeTime(cx, obj, argc, argv, 4, JS_TRUE, rval);
}
static JSBool
date_setUTCHours(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeTime(cx, obj, argc, argv, 4, JS_FALSE, rval);
}
static JSBool
date_makeDate(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, uintN maxargs, JSBool local, jsval *rval)
{
uintN i;
jsdouble lorutime; /* local or UTC version of *date */
jsdouble args[3], *argp, *stop;
jsdouble year, month, day;
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
/* see complaint about ECMA in date_MakeTime */
if (argc == 0)
argc = 1; /* should be safe, because length of all settors is 1 */
else if (argc > maxargs)
argc = maxargs; /* clamp argc */
for (i = 0; i < argc; i++) {
if (!js_ValueToNumber(cx, argv[i], &args[i]))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(args[i])) {
*date = *(cx->runtime->jsNaN);
return js_NewNumberValue(cx, *date, rval);
}
args[i] = js_DoubleToInteger(args[i]);
}
/* return NaN if date is NaN and we're not setting the year,
* If we are, use 0 as the time. */
if (!(JSDOUBLE_IS_FINITE(result))) {
if (argc < 3)
return js_NewNumberValue(cx, result, rval);
else
lorutime = +0.;
} else {
if (local)
lorutime = LocalTime(result);
else
lorutime = result;
}
argp = args;
stop = argp + argc;
if (maxargs >= 3 && argp < stop)
year = *argp++;
else
year = YearFromTime(lorutime);
if (maxargs >= 2 && argp < stop)
month = *argp++;
else
month = MonthFromTime(lorutime);
if (maxargs >= 1 && argp < stop)
day = *argp++;
else
day = DateFromTime(lorutime);
day = MakeDay(year, month, day); /* day within year */
result = MakeDate(day, TimeWithinDay(lorutime));
if (local)
result = UTC(result);
*date = TIMECLIP(result);
return js_NewNumberValue(cx, *date, rval);
}
static JSBool
date_setDate(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeDate(cx, obj, argc, argv, 1, JS_TRUE, rval);
}
static JSBool
date_setUTCDate(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeDate(cx, obj, argc, argv, 1, JS_FALSE, rval);
}
static JSBool
date_setMonth(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeDate(cx, obj, argc, argv, 2, JS_TRUE, rval);
}
static JSBool
date_setUTCMonth(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeDate(cx, obj, argc, argv, 2, JS_FALSE, rval);
}
static JSBool
date_setFullYear(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeDate(cx, obj, argc, argv, 3, JS_TRUE, rval);
}
static JSBool
date_setUTCFullYear(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
return date_makeDate(cx, obj, argc, argv, 3, JS_FALSE, rval);
}
static JSBool
date_setYear(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
jsdouble t;
jsdouble year;
jsdouble day;
jsdouble result;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
result = *date;
if (!js_ValueToNumber(cx, argv[0], &year))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(year)) {
*date = *(cx->runtime->jsNaN);
return js_NewNumberValue(cx, *date, rval);
}
year = js_DoubleToInteger(year);
if (!JSDOUBLE_IS_FINITE(result)) {
t = +0.0;
} else {
t = LocalTime(result);
}
if (year >= 0 && year <= 99)
year += 1900;
day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
result = MakeDate(day, TimeWithinDay(t));
result = UTC(result);
*date = TIMECLIP(result);
return js_NewNumberValue(cx, *date, rval);
}
/* constants for toString, toUTCString */
static char js_NaN_date_str[] = "Invalid Date";
static const char* days[] =
{
"Sun","Mon","Tue","Wed","Thu","Fri","Sat"
};
static const char* months[] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static JSBool
date_toGMTString(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
char buf[100];
JSString *str;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(*date)) {
PR_snprintf(buf, sizeof buf, js_NaN_date_str);
} else {
jsdouble temp = *date;
/* Avoid dependence on PR_FormatTimeUSEnglish, because it
* requires a PRTime... which only has 16-bit years. Sub-ECMA.
*/
PR_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
days[WeekDay(temp)],
DateFromTime(temp),
months[MonthFromTime(temp)],
YearFromTime(temp),
HourFromTime(temp),
MinFromTime(temp),
SecFromTime(temp));
}
str = JS_NewStringCopyZ(cx, buf);
if (!str)
return JS_FALSE;
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
/* for Date.toLocaleString; interface to PRTime date struct. */
static void
new_explode(jsdouble time, PRTime *split)
{
jsint year = YearFromTime(time);
split->tm_usec = (int32) msFromTime(time) * 1000;
split->tm_sec = (int8) SecFromTime(time);
split->tm_min = (int8) MinFromTime(time);
split->tm_hour = (int8) HourFromTime(time);
split->tm_mday = (int8) DateFromTime(time);
split->tm_mon = (int8) MonthFromTime(time);
split->tm_wday = (int8) WeekDay(time);
split->tm_year = (int16) year;
split->tm_yday = (int16) DayWithinYear(time, year);
/* not sure how this affects things, but it doesn't seem
to matter. */
split->tm_isdst = (DaylightSavingTA(time) != 0);
}
static JSBool
date_toLocaleString(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
char buf[100];
JSString *str;
PRTime split;
jsdouble *date = date_getProlog(cx, obj, argv);
if (!date)
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(*date)) {
PR_snprintf(buf, sizeof buf, js_NaN_date_str);
} else {
jsdouble local = LocalTime(*date);
new_explode(local, &split);
/* let PRTime format it. Use '%#c' for windows, because '%c' is
* backward-compatible and non-y2k with msvc; '%#c' requests that a
* full year be used in the result string.
*/
PR_FormatTime(buf, sizeof buf,
#ifdef _WIN32
"%#c",
#else
"%c",
#endif
&split);
}
str = JS_NewStringCopyZ(cx, buf);
if (!str)
return JS_FALSE;
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
/* helper function */
static JSBool
date_format(JSContext *cx, jsdouble date, jsval *rval)
{
char buf[100];
JSString *str;
char tzbuf[100];
PRTime split;
if (!JSDOUBLE_IS_FINITE(date)) {
PR_snprintf(buf, sizeof buf, js_NaN_date_str);
} else {
jsdouble local = LocalTime(date);
/* offset from GMT in minutes. The offset includes daylight savings,
if it applies. */
jsint minutes = (jsint) floor((LocalTZA + DaylightSavingTA(date))
/ msPerMinute);
/* map 510 minutes to 0830 hours */
intN offset = (minutes / 60) * 100 + minutes % 60;
/* print as "Wed Nov 05 19:38:03 GMT-0800 (PST) 1997" The TZA is
* printed as 'GMT-0800' rather than as 'PST' to avoid
* operating-system dependence on strftime (which
* PR_FormatTimeUSEnglish calls, for %Z only.) win32 prints
* PST as 'Pacific Standard Time.' This way we always know
* what we're getting, and can parse it if we produce it.
* The OS TZA string is included as a comment.
*/
/* get a timezone string from the OS to include as a
comment. */
new_explode(date, &split);
PR_FormatTime(tzbuf, sizeof tzbuf, "(%Z) ", &split);
/* Avoid dependence on PR_FormatTimeUSEnglish, because it
* requires a PRTime... which only has 16-bit years. Sub-ECMA.
*/
PR_snprintf(buf, sizeof buf, "%s %s %.2d %.2d:%.2d:%.2d GMT%+.4d %s%.4d",
days[WeekDay(local)],
months[MonthFromTime(local)],
DateFromTime(local),
HourFromTime(local),
MinFromTime(local),
SecFromTime(local),
offset,
/* don't print anything for the TZA comment if we got '()'
* or something non-parenthesized from the OS.
*/
((tzbuf[0] == '(' && tzbuf[1] != ')') ? tzbuf : ""),
YearFromTime(local));
}
str = JS_NewStringCopyZ(cx, buf);
if (!str)
return JS_FALSE;
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
#if JS_HAS_TOSOURCE
#include "prdtoa.h"
static JSBool
date_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsdouble *date;
JS/js/jsdate.c view on Meta::CPAN
}
static JSBool
Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble *date;
JSString *str;
jsdouble d;
/* Date called as function */
if (!cx->fp->constructing) {
int64 us, ms, us2ms;
jsdouble time;
/* NSPR 2.0 docs say 'We do not support PR_NowMS and PR_NowS',
* so compute ms from PR_Now.
*/
us = PR_Now();
LL_UI2L(us2ms, PR_USEC_PER_MSEC);
LL_DIV(ms, us, us2ms);
LL_L2D(time, ms);
return date_format(cx, time, rval);
}
/* Date called as constructor */
if (argc == 0) {
int64 us, ms, us2ms;
jsdouble time;
date = date_constructor(cx, obj);
if (!date)
return JS_FALSE;
us = PR_Now();
LL_UI2L(us2ms, PR_USEC_PER_MSEC);
LL_DIV(ms, us, us2ms);
LL_L2D(time, ms);
*date = time;
} else if (argc == 1) {
if (!JSVAL_IS_STRING(argv[0])) {
/* the argument is a millisecond number */
if (!js_ValueToNumber(cx, argv[0], &d))
return JS_FALSE;
date = date_constructor(cx, obj);
if (!date)
return JS_FALSE;
*date = TIMECLIP(d);
} else {
/* the argument is a string; parse it. */
date = date_constructor(cx, obj);
if (!date)
return JS_FALSE;
str = js_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
if (!date_parseString(str->chars, date))
*date = *(cx->runtime->jsNaN);
*date = TIMECLIP(*date);
}
} else {
jsdouble array[MAXARGS];
uintN loop;
jsdouble d;
jsdouble day;
jsdouble time;
for (loop = 0; loop < MAXARGS; loop++) {
if (loop < argc) {
if (!js_ValueToNumber(cx, argv[loop], &d))
return JS_FALSE;
/* if any arg is NaN, make a NaN date object
and return */
if (!JSDOUBLE_IS_FINITE(d)) {
date = date_constructor(cx, obj);
if (!date)
return JS_FALSE;
*date = *(cx->runtime->jsNaN);
return JS_TRUE;
}
array[loop] = js_DoubleToInteger(d);
} else {
array[loop] = 0;
}
}
date = date_constructor(cx, obj);
if (!date)
return JS_FALSE;
/* adjust 2-digit years into the 20th century */
if (array[0] >= 0 && array[0] <= 99)
array[0] += 1900;
/* if we got a 0 for 'date' (which is out of range)
* pretend it's a 1 */
if (array[2] < 1)
array[2] = 1;
day = MakeDay(array[0], array[1], array[2]);
time = MakeTime(array[3], array[4], array[5], array[6]);
time = MakeDate(day, time);
time = UTC(time);
*date = TIMECLIP(time);
}
return JS_TRUE;
}
JSObject *
js_InitDateClass(JSContext *cx, JSObject *obj)
{
JSObject *proto;
jsdouble *proto_date;
/* set static LocalTZA */
LocalTZA = -(PR_LocalGMTDifference() * msPerSecond);
proto = JS_InitClass(cx, obj, NULL, &date_class, Date, MAXARGS,
NULL, date_methods, NULL, date_static_methods);
if (!proto)
return NULL;
/* Set the value of the Date.prototype date to NaN */
proto_date = date_constructor(cx, proto);
if (!proto_date)
return NULL;
*proto_date = *(cx->runtime->jsNaN);
return proto;
}
JS_FRIEND_API(JSObject *)
js_NewDateObject(JSContext* cx, int year, int mon, int mday,
int hour, int min, int sec)
{
JSObject *obj;
jsdouble *date;
jsdouble time;
obj = js_NewObject(cx, &date_class, NULL, NULL);
if (!obj)
return NULL;
JS_DefineFunctions(cx, obj, date_methods);
date = date_constructor(cx, obj);
if (!date)
return NULL;
time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
*date = UTC(time);
return obj;
}
JS_FRIEND_API(int)
js_DateGetYear(JSContext *cx, JSObject* obj)
{
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return 0;
return (int) YearFromTime(LocalTime(*date));
}
JS_FRIEND_API(int)
js_DateGetMonth(JSContext *cx, JSObject* obj)
{
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return 0;
return (int) MonthFromTime(LocalTime(*date));
}
JS_FRIEND_API(int)
js_DateGetDate(JSContext *cx, JSObject* obj)
{
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return 0;
return (int) DateFromTime(LocalTime(*date));
}
JS_FRIEND_API(int)
js_DateGetHours(JSContext *cx, JSObject* obj)
{
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return 0;
return (int) HourFromTime(LocalTime(*date));
}
JS_FRIEND_API(int)
js_DateGetMinutes(JSContext *cx, JSObject* obj)
{
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return 0;
return (int) MinFromTime(LocalTime(*date));
}
JS_FRIEND_API(int)
js_DateGetSeconds(JSContext *cx, JSObject* obj)
{
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return 0;
return (int) SecFromTime(*date);
}
extern JS_FRIEND_API(void)
js_DateSetYear(JSContext *cx, JSObject *obj, int year)
{
jsdouble local;
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return;
local = LocalTime(*date);
/* reset date if it was NaN */
if (JSDOUBLE_IS_NaN(local))
local = 0;
local = date_msecFromDate(year,
MonthFromTime(local),
DateFromTime(local),
HourFromTime(local),
MinFromTime(local),
SecFromTime(local),
msFromTime(local));
*date = UTC(local);
}
extern JS_FRIEND_API(void)
js_DateSetMonth(JSContext *cx, JSObject *obj, int month)
{
jsdouble local;
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return;
local = LocalTime(*date);
/* bail if date was NaN */
if (JSDOUBLE_IS_NaN(local))
return;
local = date_msecFromDate(YearFromTime(local),
month,
DateFromTime(local),
HourFromTime(local),
MinFromTime(local),
SecFromTime(local),
msFromTime(local));
*date = UTC(local);
}
extern JS_FRIEND_API(void)
js_DateSetDate(JSContext *cx, JSObject *obj, int date)
{
jsdouble local;
jsdouble *datep = date_getProlog(cx, obj, NULL);
if (!datep)
return;
local = LocalTime(*datep);
if (JSDOUBLE_IS_NaN(local))
return;
local = date_msecFromDate(YearFromTime(local),
MonthFromTime(local),
date,
HourFromTime(local),
MinFromTime(local),
SecFromTime(local),
msFromTime(local));
*datep = UTC(local);
}
extern JS_FRIEND_API(void)
js_DateSetHours(JSContext *cx, JSObject *obj, int hours)
{
jsdouble local;
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return;
local = LocalTime(*date);
if (JSDOUBLE_IS_NaN(local))
return;
local = date_msecFromDate(YearFromTime(local),
MonthFromTime(local),
DateFromTime(local),
hours,
MinFromTime(local),
SecFromTime(local),
msFromTime(local));
*date = UTC(local);
}
extern JS_FRIEND_API(void)
js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes)
{
jsdouble local;
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return;
local = LocalTime(*date);
if (JSDOUBLE_IS_NaN(local))
return;
local = date_msecFromDate(YearFromTime(local),
MonthFromTime(local),
DateFromTime(local),
HourFromTime(local),
minutes,
SecFromTime(local),
msFromTime(local));
*date = UTC(local);
}
extern JS_FRIEND_API(void)
js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds)
{
jsdouble local;
jsdouble *date = date_getProlog(cx, obj, NULL);
if (!date)
return;
local = LocalTime(*date);
if (JSDOUBLE_IS_NaN(local))
return;
local = date_msecFromDate(YearFromTime(local),
MonthFromTime(local),
DateFromTime(local),
HourFromTime(local),
MinFromTime(local),
seconds,
msFromTime(local));
*date = UTC(local);
}
( run in 1.146 second using v1.01-cache-2.11-cpan-39bf76dae61 )