⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsdate.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 4 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * JS date methods. *//* * "For example, OS/360 devotes 26 bytes of the permanently *  resident date-turnover routine to the proper handling of *  December 31 on leap years (when it is Day 366).  That *  might have been left to the operator." * * Frederick Brooks, 'The Second-System Effect'. */#include "jsstddef.h"#include <ctype.h>#include <math.h>#include <stdlib.h>#include <string.h>#include "jstypes.h"#include "jsprf.h"#include "prmjtime.h"#include "jsutil.h" /* Added by JSIFY */#include "jsapi.h"#include "jsconfig.h"#include "jscntxt.h"#include "jsdate.h"#include "jsinterp.h"#include "jsnum.h"#include "jsobj.h"#include "jsstr.h"/* * The JS 'Date' object is patterned after the Java 'Date' object. * Here is an script: * *    today = new Date(); * *    print(today.toLocaleString()); * *    weekDay = today.getDay(); * * * These Java (and ECMA-262) methods are supported: * *     UTC *     getDate (getUTCDate) *     getDay (getUTCDay) *     getHours (getUTCHours) *     getMinutes (getUTCMinutes) *     getMonth (getUTCMonth) *     getSeconds (getUTCSeconds) *     getMilliseconds (getUTCMilliseconds) *     getTime *     getTimezoneOffset *     getYear *     getFullYear (getUTCFullYear) *     parse *     setDate (setUTCDate) *     setHours (setUTCHours) *     setMinutes (setUTCMinutes) *     setMonth (setUTCMonth) *     setSeconds (setUTCSeconds) *     setMilliseconds (setUTCMilliseconds) *     setTime *     setYear (setFullYear, setUTCFullYear) *     toGMTString (toUTCString) *     toLocaleString *     toString * * * These Java methods are not supported * *     setDay *     before *     after *     equals *     hashCode *//* * 11/97 - jsdate.c has been rewritten to conform to the ECMA-262 language * definition and reduce dependence on NSPR.  NSPR is used to get the current * time in milliseconds, the time zone offset, and the daylight savings time * offset for a given time.  NSPR is also used for Date.toLocaleString(), for * locale-specific formatting, and to get a string representing the timezone. * (Which turns out to be platform-dependent.) * * To do: * (I did some performance tests by timing how long it took to run what *  I had of the js ECMA conformance tests.) * * - look at saving results across multiple calls to supporting * functions; the toString functions compute some of the same values * multiple times.  Although - I took a quick stab at this, and I lost * rather than gained.  (Fractionally.)  Hard to tell what compilers/processors * are doing these days. * * - look at tweaking function return types to return double instead * of int; this seems to make things run slightly faster sometimes. * (though it could be architecture-dependent.)  It'd be good to see * how this does on win32.  (Tried it on irix.)  Types could use a * general going-over. *//* * Supporting functions - ECMA 15.9.1.* */#define HalfTimeDomain  8.64e15#define HoursPerDay     24.0#define MinutesPerDay   (HoursPerDay * MinutesPerHour)#define MinutesPerHour  60.0#define SecondsPerDay   (MinutesPerDay * SecondsPerMinute)#define SecondsPerHour  (MinutesPerHour * SecondsPerMinute)#define SecondsPerMinute 60.0#if defined(XP_WIN) || defined(XP_OS2)/* Work around msvc double optimization bug by making these runtime values; if * they're available at compile time, msvc optimizes division by them by * computing the reciprocal and multiplying instead of dividing - this loses * when the reciprocal isn't representable in a double. */static jsdouble msPerSecond = 1000.0;static jsdouble msPerDay = SecondsPerDay * 1000.0;static jsdouble msPerHour = SecondsPerHour * 1000.0;static jsdouble msPerMinute = SecondsPerMinute * 1000.0;#else#define msPerDay        (SecondsPerDay * msPerSecond)#define msPerHour       (SecondsPerHour * msPerSecond)#define msPerMinute     (SecondsPerMinute * msPerSecond)#define msPerSecond     1000.0#endif#define Day(t)          floor((t) / msPerDay)static jsdoubleTimeWithinDay(jsdouble t){    jsdouble result;    result = fmod(t, msPerDay);    if (result < 0)	result += msPerDay;    return result;}#define DaysInYear(y)   ((y) % 4 == 0 && ((y) % 100 || ((y) % 400 == 0))  \			 ? 366 : 365)/* math here has to be f.p, because we need *  floor((1968 - 1969) / 4) == -1 */#define DayFromYear(y)  (365 * ((y)-1970) + floor(((y)-1969)/4.0)            \			 - floor(((y)-1901)/100.0) + floor(((y)-1601)/400.0))#define TimeFromYear(y) (DayFromYear(y) * msPerDay)static jsintYearFromTime(jsdouble t){    jsint y = (jsint) floor(t /(msPerDay*365.2425)) + 1970;    jsdouble t2 = (jsdouble) TimeFromYear(y);    if (t2 > t) {        y--;    } else {        if (t2 + msPerDay * DaysInYear(y) <= t)            y++;    }    return y;}#define InLeapYear(t)   (JSBool) (DaysInYear(YearFromTime(t)) == 366)#define DayWithinYear(t, year) ((intN) (Day(t) - DayFromYear(year)))/* * The following array contains the day of year for the first day of * each month, where index 0 is January, and day 0 is January 1. */static jsdouble firstDayOfMonth[2][12] = {    {0.0, 31.0, 59.0, 90.0, 120.0, 151.0, 181.0, 212.0, 243.0, 273.0, 304.0, 334.0},    {0.0, 31.0, 60.0, 91.0, 121.0, 152.0, 182.0, 213.0, 244.0, 274.0, 305.0, 335.0}};#define DayFromMonth(m, leap) firstDayOfMonth[leap][(intN)m];static intNMonthFromTime(jsdouble t){    intN d, step;    jsint year = YearFromTime(t);    d = DayWithinYear(t, year);    if (d < (step = 31))	return 0;    step += (InLeapYear(t) ? 29 : 28);    if (d < step)	return 1;    if (d < (step += 31))	return 2;    if (d < (step += 30))	return 3;    if (d < (step += 31))	return 4;    if (d < (step += 30))	return 5;    if (d < (step += 31))	return 6;    if (d < (step += 31))	return 7;    if (d < (step += 30))	return 8;    if (d < (step += 31))	return 9;    if (d < (step += 30))	return 10;    return 11;}static intNDateFromTime(jsdouble t){    intN d, step, next;    jsint year = YearFromTime(t);    d = DayWithinYear(t, year);    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 intNWeekDay(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 jsdoubleDaylightSavingTA(jsdouble t){    volatile 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 */    JSLL_D2L(PR_t, t);    JSLL_I2L(ms2us, PRMJ_USEC_PER_MSEC);    JSLL_MUL(PR_t, PR_t, ms2us);    offset = PRMJ_DSTOffset(PR_t);    JSLL_DIV(offset, offset, ms2us);    JSLL_L2D(result, offset);    return result;}#define AdjustTime(t)   fmod(LocalTZA + DaylightSavingTA(t), msPerDay)#define LocalTime(t)    ((t) + AdjustTime(t))static jsdoubleUTC(jsdouble t){    return t - AdjustTime(t - LocalTZA);}static intNHourFromTime(jsdouble t){    intN result = (intN) fmod(floor(t/msPerHour), HoursPerDay);    if (result < 0)	result += (intN)HoursPerDay;    return result;}static intNMinFromTime(jsdouble t){    intN result = (intN) fmod(floor(t / msPerMinute), MinutesPerHour);    if (result < 0)	result += (intN)MinutesPerHour;    return result;}static intNSecFromTime(jsdouble t){    intN result = (intN) fmod(floor(t / msPerSecond), SecondsPerMinute);    if (result < 0)	result += (intN)SecondsPerMinute;    return result;}static intNmsFromTime(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 jsdoubleMakeDay(jsdouble year, jsdouble month, jsdouble date){    jsdouble result;    JSBool leap;    jsdouble yearday;    jsdouble monthday;    year += floor(month / 12);    month = fmod(month, 12.0);    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 = {    js_Date_str,    JSCLASS_HAS_PRIVATE,    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub,    JSCLASS_NO_OPTIONAL_MEMBERS};/* for use by date_parse */static const 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[] = {    -1, -2, 0, 0, 0, 0, 0, 0, 0,       /* AM/PM */    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 JSBooldate_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 jsdoubledate_msecFromDate(jsdouble year, jsdouble mon, jsdouble mday, jsdouble hour,		  jsdouble min, jsdouble sec, jsdouble msec){    jsdouble day;    jsdouble msec_time;    jsdouble result;    day = MakeDay(year, mon, mday);    msec_time = MakeTime(hour, min, sec, msec);    result = MakeDate(day, msec_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        7static JSBooldate_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 JSBooldate_parseString(JSString *str, jsdouble *result){    jsdouble msec;    const jschar *s = JSSTRING_CHARS(str);    size_t limit = JSSTRING_LENGTH(str);    size_t i = 0;    int year = -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -