4 // Author: Cesar Octavio Lopez Nataren
6 // (C) 2003, Cesar Octavio Lopez Nataren, <cesar@ciencias.unam.mx>
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 namespace Microsoft.JScript {
34 public class DateConstructor : ScriptFunction {
36 const double SECONDS_PER_MINUTE = 60.0;
37 const double HOURS_PER_DAY = 24.0;
38 const double MINUTES_PER_HOUR = 60.0;
39 const double MINUTES_PER_DAY = HOURS_PER_DAY * MINUTES_PER_HOUR;
40 const double SECONDS_PER_DAY = MINUTES_PER_DAY * SECONDS_PER_MINUTE;
41 const double MS_PER_SECOND = 1000.0;
42 const double MS_PER_MINUTE = SECONDS_PER_MINUTE * MS_PER_SECOND;
43 const double MS_PER_DAY = SECONDS_PER_DAY * MS_PER_SECOND;
45 internal static DateConstructor Ctr = new DateConstructor ();
47 internal DateConstructor ()
51 [JSFunctionAttribute (JSFunctionAttributeEnum.HasVarArgs)]
52 public new DateObject CreateInstance (params Object[] args)
54 throw new NotImplementedException ();
57 public String Invoke ()
59 throw new NotImplementedException ();
62 [JSFunctionAttribute(0, JSBuiltin.Date_parse)]
63 public static double parse (String str)
84 bool seenplusminus = false;
91 if (c <= ' ' || c == ',' || c == '-') {
94 if (c == '-' && '0' <= si && si <= '9')
100 if (c == '(') { /* comments) */
114 if ('0' <= c && c <= '9') {
116 while (i < limit && '0' <= (c = str [i]) && c <= '9') {
117 n = n * 10 + c - '0';
121 /* allow TZA before the year, so
122 * 'Wed Nov 05 21:49:11 GMT-0800 1997'
125 /* uses of seenplusminus allow : in TZA, so Java
126 * no-timezone style of GMT+4:30 works
128 if ((prevc == '+' || prevc == '-') /* && year >= 0 */) {
129 /* make ':' case below change tzoffset */
130 seenplusminus = true;
134 n = n * 60; /* EG. "GMT-3" */
136 n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
137 if (prevc == '+') /* plus means east of GMT */
139 if (tzoffset != 0 && tzoffset != -1)
142 } else if (n >= 70 || (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) {
145 else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
146 year = n < 100 ? n + 1900 : n;
149 } else if (c == ':') {
156 } else if (c == '/') {
158 mon = /* byte */ n - 1;
163 } else if (i < limit && c != ',' && c > ' ' && c != '-')
165 else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
170 } else if (hour >= 0 && min < 0)
172 else if (min >= 0 && sec < 0)
179 } else if (c == '/' || c == ':' || c == '+' || c == '-')
185 if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
190 int letterCount = i - st;
195 * Use ported code from jsdate.c rather than the locale-specific
196 * date-parsing code from Java, to keep js and rhino consistent.
197 * Is this the right strategy?
199 string wtb = "am;pm;"
200 + "monday;tuesday;wednesday;thursday;friday;"
202 + "january;february;march;april;may;june;"
203 + "july;august;september;october;november;december;"
204 + "gmt;ut;utc;est;edt;cst;cdt;mst;mdt;pst;pdt;";
208 for (int wtbOffset = 0;;) {
209 int wtbNext = wtb.IndexOf (';', wtbOffset);
214 if (String.Compare (wtb, wtbOffset, str, st, letterCount, true) == 0)
217 wtbOffset = wtbNext + 1;
223 * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
224 * 12:30, instead of blindly adding 12 if PM.
226 if (hour > 12 || hour < 0)
228 else if (index == 0) {
237 } else if ((index -= 2) < 7) {
239 } else if ((index -= 7) < 12) {
297 if (year < 0 || mon < 0 || mday < 0)
306 double msec = msec_from_date (year, mon, mday, hour, min, sec, 0);
308 if (tzoffset == -1) { // no time zone specified, have to use local
309 Console.WriteLine ("FIXME: no time zone specified.");
310 throw new NotImplementedException ();
312 return msec + tzoffset * MS_PER_MINUTE;
316 // find UTC time from given date... no 1900 correction!
318 static double msec_from_date (double year, double mon, double mday, double hour, double min, double sec, double msec)
320 double day, time, result;
321 day = MakeDay (year, mon, mday);
322 time = MakeTime (hour, min, sec, msec);
323 result = MakeDate (day, time);
327 static double MakeDay (double year, double month, double date)
329 year += Math.Floor (month / 12);
335 double year_day = Math.Floor (TimeFromYear (year) / MS_PER_DAY);
336 double month_day = DayFromMonth ((int) month, (int) year);
337 return year_day + month_day + date - 1;
340 static double MakeTime (double hour, double min, double sec, double ms)
342 return ((hour * MINUTES_PER_HOUR + min) * SECONDS_PER_MINUTE + sec) * MS_PER_SECOND + ms;
345 static double MakeDate (double day, double time)
347 return day * MS_PER_DAY + time;
350 static double TimeFromYear (double y)
352 return DayFromYear (y) * MS_PER_DAY;
355 static double DayFromYear (double y)
357 return ((365 * ((y) - 1970) + Math.Floor (((y) - 1969) / 4.0) - Math.Floor(((y) - 1901) / 100.0) + Math.Floor (((y) - 1601) / 400.0)));
360 static double DayFromMonth (int m , int year)
367 day += (m - 1) / 2 - 1;
371 if (m >= 2 && IsLeapYear (year))
377 static bool IsLeapYear (int year)
379 return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
382 [JSFunctionAttribute(0, JSBuiltin.Date_UTC)]
383 public static double UTC (Object year, Object month, Object date,
384 Object hours, Object minutes, Object seconds, Object ms)
386 throw new NotImplementedException ();