js/src/tests/ecma_3/Date/shell.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/tests/ecma_3/Date/shell.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,530 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +
    1.10 +/*
    1.11 + * Date functions used by tests in Date suite
    1.12 + *
    1.13 + */
    1.14 +var msPerDay =   86400000;
    1.15 +var HoursPerDay =  24;
    1.16 +var MinutesPerHour = 60;
    1.17 +var SecondsPerMinute = 60;
    1.18 +var msPerSecond =  1000;
    1.19 +var msPerMinute =  60000;  // msPerSecond * SecondsPerMinute
    1.20 +var msPerHour =   3600000; // msPerMinute * MinutesPerHour
    1.21 +var TZ_DIFF = getTimeZoneDiff();  // offset of tester's timezone from UTC
    1.22 +var TZ_ADJUST = TZ_DIFF * msPerHour;
    1.23 +var TZ_PST = -8;  // offset of Pacific Standard Time from UTC
    1.24 +var PST_DIFF = TZ_DIFF - TZ_PST;  // offset of tester's timezone from PST
    1.25 +var TIME_1970  = 0;
    1.26 +var TIME_2000  = 946684800000;
    1.27 +var TIME_1900  = -2208988800000;
    1.28 +var UTC_29_FEB_2000 = TIME_2000 + 31*msPerDay + 28*msPerDay;
    1.29 +var UTC_1_JAN_2005 = TIME_2000 + TimeInYear(2000) + TimeInYear(2001) +
    1.30 +  TimeInYear(2002) + TimeInYear(2003) + TimeInYear(2004);
    1.31 +var now = new Date();
    1.32 +var TIME_NOW = now.valueOf();  //valueOf() is to accurate to the millisecond
    1.33 +                               //Date.parse() is accurate only to the second
    1.34 +
    1.35 +/*
    1.36 + * Originally, the test suite used a hard-coded value TZ_DIFF = -8.
    1.37 + * But that was only valid for testers in the Pacific Standard Time Zone!
    1.38 + * We calculate the proper number dynamically for any tester. We just
    1.39 + * have to be careful not to use a date subject to Daylight Savings Time...
    1.40 + */
    1.41 +function getTimeZoneDiff()
    1.42 +{
    1.43 +  return -((new Date(2000, 1, 1)).getTimezoneOffset())/60;
    1.44 +}
    1.45 +
    1.46 +
    1.47 +/*
    1.48 + * Date test "ResultArrays" are hard-coded for Pacific Standard Time.
    1.49 + * We must adjust them for the tester's own timezone -
    1.50 + */
    1.51 +function adjustResultArray(ResultArray, msMode)
    1.52 +{
    1.53 +  // If the tester's system clock is in PST, no need to continue -
    1.54 +  if (!PST_DIFF) {return;}
    1.55 +
    1.56 +  /* The date testcases instantiate Date objects in two different ways:
    1.57 +   *
    1.58 +   *        millisecond mode: e.g.   dt = new Date(10000000);
    1.59 +   *        year-month-day mode:  dt = new Date(2000, 5, 1, ...);
    1.60 +   *
    1.61 +   * In the first case, the date is measured from Time 0 in Greenwich (i.e. UTC).
    1.62 +   * In the second case, it is measured with reference to the tester's local timezone.
    1.63 +   *
    1.64 +   * In the first case we must correct those values expected for local measurements,
    1.65 +   * like dt.getHours() etc. No correction is necessary for dt.getUTCHours() etc.
    1.66 +   *
    1.67 +   * In the second case, it is exactly the other way around -
    1.68 +   */
    1.69 +  if (msMode)
    1.70 +  {
    1.71 +    // The hard-coded UTC milliseconds from Time 0 derives from a UTC date.
    1.72 +    // Shift to the right by the offset between UTC and the tester.
    1.73 +    var t = ResultArray[TIME]  +  TZ_DIFF*msPerHour;
    1.74 +
    1.75 +    // Use our date arithmetic functions to determine the local hour, day, etc.
    1.76 +    ResultArray[HOURS] = HourFromTime(t);
    1.77 +    ResultArray[DAY] = WeekDay(t);
    1.78 +    ResultArray[DATE] = DateFromTime(t);
    1.79 +    ResultArray[MONTH] = MonthFromTime(t);
    1.80 +    ResultArray[YEAR] = YearFromTime(t); 
    1.81 +  }
    1.82 +  else
    1.83 +  {
    1.84 +    // The hard-coded UTC milliseconds from Time 0 derives from a PST date.
    1.85 +    // Shift to the left by the offset between PST and the tester.
    1.86 +    var t = ResultArray[TIME]  -  PST_DIFF*msPerHour;
    1.87 +
    1.88 +    // Use our date arithmetic functions to determine the UTC hour, day, etc.
    1.89 +    ResultArray[TIME] = t;
    1.90 +    ResultArray[UTC_HOURS] = HourFromTime(t);
    1.91 +    ResultArray[UTC_DAY] = WeekDay(t);
    1.92 +    ResultArray[UTC_DATE] = DateFromTime(t);
    1.93 +    ResultArray[UTC_MONTH] = MonthFromTime(t);
    1.94 +    ResultArray[UTC_YEAR] = YearFromTime(t);
    1.95 +  }
    1.96 +}
    1.97 +
    1.98 +
    1.99 +function Day( t ) {
   1.100 +  return ( Math.floor(t/msPerDay ) );
   1.101 +}
   1.102 +function DaysInYear( y ) {
   1.103 +  if ( y % 4 != 0 ) {
   1.104 +    return 365;
   1.105 +  }
   1.106 +  if ( (y % 4 == 0) && (y % 100 != 0) ) {
   1.107 +    return 366;
   1.108 +  }
   1.109 +  if ( (y % 100 == 0) && (y % 400 != 0) ) {
   1.110 +    return 365;
   1.111 +  }
   1.112 +  if ( (y % 400 == 0) ){
   1.113 +    return 366;
   1.114 +  } else {
   1.115 +    return "ERROR: DaysInYear(" + y + ") case not covered";
   1.116 +  }
   1.117 +}
   1.118 +function TimeInYear( y ) {
   1.119 +  return ( DaysInYear(y) * msPerDay );
   1.120 +}
   1.121 +function DayNumber( t ) {
   1.122 +  return ( Math.floor( t / msPerDay ) );
   1.123 +}
   1.124 +function TimeWithinDay( t ) {
   1.125 +
   1.126 +  var r = t % msPerDay;
   1.127 +
   1.128 +  if (r < 0)
   1.129 +  {
   1.130 +    r += msPerDay;
   1.131 +  }
   1.132 +  return r;
   1.133 +
   1.134 +}
   1.135 +function YearNumber( t ) {
   1.136 +}
   1.137 +function TimeFromYear( y ) {
   1.138 +  return ( msPerDay * DayFromYear(y) );
   1.139 +}
   1.140 +function DayFromYear( y ) {
   1.141 +  return ( 365*(y-1970) +
   1.142 +           Math.floor((y-1969)/4) -
   1.143 +           Math.floor((y-1901)/100) +
   1.144 +           Math.floor((y-1601)/400) );
   1.145 +}
   1.146 +function InLeapYear( t ) {
   1.147 +  if ( DaysInYear(YearFromTime(t)) == 365 ) {
   1.148 +    return 0;
   1.149 +  }
   1.150 +  if ( DaysInYear(YearFromTime(t)) == 366 ) {
   1.151 +    return 1;
   1.152 +  } else {
   1.153 +    return "ERROR:  InLeapYear("+ t + ") case not covered";
   1.154 +  }
   1.155 +}
   1.156 +function YearFromTime( t ) {
   1.157 +  t = Number( t );
   1.158 +  var sign = ( t < 0 ) ? -1 : 1;
   1.159 +  var year = ( sign < 0 ) ? 1969 : 1970;
   1.160 +  for ( var timeToTimeZero = t; ;  ) {
   1.161 +    // subtract the current year's time from the time that's left.
   1.162 +    timeToTimeZero -= sign * TimeInYear(year)
   1.163 +
   1.164 +      // if there's less than the current year's worth of time left, then break.
   1.165 +      if ( sign < 0 ) {
   1.166 +        if ( sign * timeToTimeZero <= 0 ) {
   1.167 +          break;
   1.168 +        } else {
   1.169 +          year += sign;
   1.170 +        }
   1.171 +      } else {
   1.172 +        if ( sign * timeToTimeZero < 0 ) {
   1.173 +          break;
   1.174 +        } else {
   1.175 +          year += sign;
   1.176 +        }
   1.177 +      }
   1.178 +  }
   1.179 +  return ( year );
   1.180 +}
   1.181 +function MonthFromTime( t ) {
   1.182 +  // i know i could use switch but i'd rather not until it's part of ECMA
   1.183 +  var day = DayWithinYear( t );
   1.184 +  var leap = InLeapYear(t);
   1.185 +
   1.186 +  if ( (0 <= day) && (day < 31) ) {
   1.187 +    return 0;
   1.188 +  }
   1.189 +  if ( (31 <= day) && (day < (59+leap)) ) {
   1.190 +    return 1;
   1.191 +  }
   1.192 +  if ( ((59+leap) <= day) && (day < (90+leap)) ) {
   1.193 +    return 2;
   1.194 +  }
   1.195 +  if ( ((90+leap) <= day) && (day < (120+leap)) ) {
   1.196 +    return 3;
   1.197 +  }
   1.198 +  if ( ((120+leap) <= day) && (day < (151+leap)) ) {
   1.199 +    return 4;
   1.200 +  }
   1.201 +  if ( ((151+leap) <= day) && (day < (181+leap)) ) {
   1.202 +    return 5;
   1.203 +  }
   1.204 +  if ( ((181+leap) <= day) && (day < (212+leap)) ) {
   1.205 +    return 6;
   1.206 +  }
   1.207 +  if ( ((212+leap) <= day) && (day < (243+leap)) ) {
   1.208 +    return 7;
   1.209 +  }
   1.210 +  if ( ((243+leap) <= day) && (day < (273+leap)) ) {
   1.211 +    return 8;
   1.212 +  }
   1.213 +  if ( ((273+leap) <= day) && (day < (304+leap)) ) {
   1.214 +    return 9;
   1.215 +  }
   1.216 +  if ( ((304+leap) <= day) && (day < (334+leap)) ) {
   1.217 +    return 10;
   1.218 +  }
   1.219 +  if ( ((334+leap) <= day) && (day < (365+leap)) ) {
   1.220 +    return 11;
   1.221 +  } else {
   1.222 +    return "ERROR: MonthFromTime("+t+") not known";
   1.223 +  }
   1.224 +}
   1.225 +function DayWithinYear( t ) {
   1.226 +  return( Day(t) - DayFromYear(YearFromTime(t)));
   1.227 +}
   1.228 +function DateFromTime( t ) {
   1.229 +  var day = DayWithinYear(t);
   1.230 +  var month = MonthFromTime(t);
   1.231 +
   1.232 +  if ( month == 0 ) {
   1.233 +    return ( day + 1 );
   1.234 +  }
   1.235 +  if ( month == 1 ) {
   1.236 +    return ( day - 30 );
   1.237 +  }
   1.238 +  if ( month == 2 ) {
   1.239 +    return ( day - 58 - InLeapYear(t) );
   1.240 +  }
   1.241 +  if ( month == 3 ) {
   1.242 +    return ( day - 89 - InLeapYear(t));
   1.243 +  }
   1.244 +  if ( month == 4 ) {
   1.245 +    return ( day - 119 - InLeapYear(t));
   1.246 +  }
   1.247 +  if ( month == 5 ) {
   1.248 +    return ( day - 150- InLeapYear(t));
   1.249 +  }
   1.250 +  if ( month == 6 ) {
   1.251 +    return ( day - 180- InLeapYear(t));
   1.252 +  }
   1.253 +  if ( month == 7 ) {
   1.254 +    return ( day - 211- InLeapYear(t));
   1.255 +  }
   1.256 +  if ( month == 8 ) {
   1.257 +    return ( day - 242- InLeapYear(t));
   1.258 +  }
   1.259 +  if ( month == 9 ) {
   1.260 +    return ( day - 272- InLeapYear(t));
   1.261 +  }
   1.262 +  if ( month == 10 ) {
   1.263 +    return ( day - 303- InLeapYear(t));
   1.264 +  }
   1.265 +  if ( month == 11 ) {
   1.266 +    return ( day - 333- InLeapYear(t));
   1.267 +  }
   1.268 +
   1.269 +  return ("ERROR:  DateFromTime("+t+") not known" );
   1.270 +}
   1.271 +function WeekDay( t ) {
   1.272 +  var weekday = (Day(t)+4) % 7;
   1.273 +  return( weekday < 0 ? 7 + weekday : weekday );
   1.274 +}
   1.275 +
   1.276 +// missing daylight savings time adjustment
   1.277 +
   1.278 +function HourFromTime( t ) {
   1.279 +  var h = Math.floor( t / msPerHour ) % HoursPerDay;
   1.280 +  return ( (h<0) ? HoursPerDay + h : h  );
   1.281 +}
   1.282 +function MinFromTime( t ) {
   1.283 +  var min = Math.floor( t / msPerMinute ) % MinutesPerHour;
   1.284 +  return( ( min < 0 ) ? MinutesPerHour + min : min  );
   1.285 +}
   1.286 +function SecFromTime( t ) {
   1.287 +  var sec = Math.floor( t / msPerSecond ) % SecondsPerMinute;
   1.288 +  return ( (sec < 0 ) ? SecondsPerMinute + sec : sec );
   1.289 +}
   1.290 +function msFromTime( t ) {
   1.291 +  var ms = t % msPerSecond;
   1.292 +  return ( (ms < 0 ) ? msPerSecond + ms : ms );
   1.293 +}
   1.294 +function LocalTZA() {
   1.295 +  return ( TZ_DIFF * msPerHour );
   1.296 +}
   1.297 +function UTC( t ) {
   1.298 +  return ( t - LocalTZA() - DaylightSavingTA(t - LocalTZA()) );
   1.299 +}
   1.300 +
   1.301 +function DaylightSavingTA( t ) {
   1.302 +  t = t - LocalTZA();
   1.303 +
   1.304 +  var dst_start = GetDSTStart(t);
   1.305 +  var dst_end   = GetDSTEnd(t);
   1.306 +
   1.307 +  if ( t >= dst_start && t < dst_end )
   1.308 +    return msPerHour;
   1.309 +
   1.310 +  return 0;
   1.311 +}
   1.312 +
   1.313 +function GetFirstSundayInMonth( t, m ) {
   1.314 +  var year = YearFromTime(t);
   1.315 +  var leap = InLeapYear(t);
   1.316 +
   1.317 +// month m 0..11
   1.318 +// april == 3
   1.319 +// march == 2
   1.320 +
   1.321 +  // set time to first day of month m
   1.322 +  var time = TimeFromYear(year);
   1.323 +  for (var i = 0; i < m; ++i)
   1.324 +  {
   1.325 +    time += TimeInMonth(i, leap);
   1.326 +  }
   1.327 +
   1.328 +  for ( var first_sunday = time; WeekDay(first_sunday) > 0;
   1.329 +        first_sunday += msPerDay )
   1.330 +  {
   1.331 +    ;
   1.332 +  }
   1.333 +
   1.334 +  return first_sunday;
   1.335 +}
   1.336 +
   1.337 +function GetLastSundayInMonth( t, m ) {
   1.338 +  var year = YearFromTime(t);
   1.339 +  var leap = InLeapYear(t);
   1.340 +
   1.341 +// month m 0..11
   1.342 +// april == 3
   1.343 +// march == 2
   1.344 +
   1.345 +  // first day of following month
   1.346 +  var time = TimeFromYear(year);
   1.347 +  for (var i = 0; i <= m; ++i)
   1.348 +  {
   1.349 +    time += TimeInMonth(i, leap);
   1.350 +  }
   1.351 +  // prev day == last day of month
   1.352 +  time -= msPerDay;
   1.353 +
   1.354 +  for ( var last_sunday = time; WeekDay(last_sunday) > 0;
   1.355 +        last_sunday -= msPerDay )
   1.356 +  {
   1.357 +    ;
   1.358 +  }
   1.359 +  return last_sunday;
   1.360 +}
   1.361 +
   1.362 +/*
   1.363 +  15.9.1.9 Daylight Saving Time Adjustment
   1.364 +
   1.365 +  The implementation of ECMAScript should not try to determine whether
   1.366 +  the exact time was subject to daylight saving time, but just whether
   1.367 +  daylight saving time would have been in effect if the current
   1.368 +  daylight saving time algorithm had been used at the time. This avoids
   1.369 +  complications such as taking into account the years that the locale
   1.370 +  observed daylight saving time year round.
   1.371 +*/
   1.372 +
   1.373 +/*
   1.374 +  US DST algorithm
   1.375 +
   1.376 +  Before 2007, DST starts first Sunday in April at 2 AM and ends last
   1.377 +  Sunday in October at 2 AM
   1.378 +
   1.379 +  Starting in 2007, DST starts second Sunday in March at 2 AM and ends
   1.380 +  first Sunday in November at 2 AM
   1.381 +
   1.382 +  Note that different operating systems behave differently.
   1.383 +
   1.384 +  Fully patched Windows XP uses the 2007 algorithm for all dates while
   1.385 +  fully patched Fedora Core 6 and RHEL 4 Linux use the algorithm in
   1.386 +  effect at the time.
   1.387 +
   1.388 +  Since pre-2007 DST is a subset of 2007 DST rules, this only affects
   1.389 +  tests that occur in the period Mar-Apr and Oct-Nov where the two
   1.390 +  algorithms do not agree.
   1.391 +
   1.392 +*/
   1.393 +
   1.394 +function GetDSTStart( t )
   1.395 +{
   1.396 +  return (GetFirstSundayInMonth(t, 2) + 7*msPerDay + 2*msPerHour - LocalTZA());
   1.397 +}
   1.398 +
   1.399 +function GetDSTEnd( t )
   1.400 +{
   1.401 +  return (GetFirstSundayInMonth(t, 10) + 2*msPerHour - LocalTZA());
   1.402 +}
   1.403 +
   1.404 +function GetOldDSTStart( t )
   1.405 +{
   1.406 +  return (GetFirstSundayInMonth(t, 3) + 2*msPerHour - LocalTZA());
   1.407 +}
   1.408 +
   1.409 +function GetOldDSTEnd( t )
   1.410 +{
   1.411 +  return (GetLastSundayInMonth(t, 9) + 2*msPerHour - LocalTZA());
   1.412 +}
   1.413 +
   1.414 +function LocalTime( t ) {
   1.415 +  return ( t + LocalTZA() + DaylightSavingTA(t) );
   1.416 +}
   1.417 +function MakeTime( hour, min, sec, ms ) {
   1.418 +  if ( isNaN( hour ) || isNaN( min ) || isNaN( sec ) || isNaN( ms ) ) {
   1.419 +    return Number.NaN;
   1.420 +  }
   1.421 +
   1.422 +  hour = ToInteger(hour);
   1.423 +  min  = ToInteger( min);
   1.424 +  sec  = ToInteger( sec);
   1.425 +  ms  = ToInteger( ms );
   1.426 +
   1.427 +  return( (hour*msPerHour) + (min*msPerMinute) +
   1.428 +          (sec*msPerSecond) + ms );
   1.429 +}
   1.430 +function MakeDay( year, month, date ) {
   1.431 +  if ( isNaN(year) || isNaN(month) || isNaN(date) ) {
   1.432 +    return Number.NaN;
   1.433 +  }
   1.434 +  year = ToInteger(year);
   1.435 +  month = ToInteger(month);
   1.436 +  date = ToInteger(date );
   1.437 +
   1.438 +  var sign = ( year < 1970 ) ? -1 : 1;
   1.439 +  var t =    ( year < 1970 ) ? 1 :  0;
   1.440 +  var y =    ( year < 1970 ) ? 1969 : 1970;
   1.441 +
   1.442 +  var result5 = year + Math.floor( month/12 );
   1.443 +  var result6 = month % 12;
   1.444 +
   1.445 +  if ( year < 1970 ) {
   1.446 +    for ( y = 1969; y >= year; y += sign ) {
   1.447 +      t += sign * TimeInYear(y);
   1.448 +    }
   1.449 +  } else {
   1.450 +    for ( y = 1970 ; y < year; y += sign ) {
   1.451 +      t += sign * TimeInYear(y);
   1.452 +    }
   1.453 +  }
   1.454 +
   1.455 +  var leap = InLeapYear( t );
   1.456 +
   1.457 +  for ( var m = 0; m < month; m++ ) {
   1.458 +    t += TimeInMonth( m, leap );
   1.459 +  }
   1.460 +
   1.461 +  if ( YearFromTime(t) != result5 ) {
   1.462 +    return Number.NaN;
   1.463 +  }
   1.464 +  if ( MonthFromTime(t) != result6 ) {
   1.465 +    return Number.NaN;
   1.466 +  }
   1.467 +  if ( DateFromTime(t) != 1 ) {
   1.468 +    return Number.NaN;
   1.469 +  }
   1.470 +
   1.471 +  return ( (Day(t)) + date - 1 );
   1.472 +}
   1.473 +function TimeInMonth( month, leap ) {
   1.474 +  // september april june november
   1.475 +  // jan 0  feb 1  mar 2 apr 3 may 4  june 5  jul 6
   1.476 +  // aug 7  sep 8  oct 9 nov 10 dec 11
   1.477 +
   1.478 +  if ( month == 3 || month == 5 || month == 8 || month == 10 ) {
   1.479 +    return ( 30*msPerDay );
   1.480 +  }
   1.481 +
   1.482 +  // all the rest
   1.483 +  if ( month == 0 || month == 2 || month == 4 || month == 6 ||
   1.484 +       month == 7 || month == 9 || month == 11 ) {
   1.485 +    return ( 31*msPerDay );
   1.486 +  }
   1.487 +
   1.488 +  // save february
   1.489 +  return ( (leap == 0) ? 28*msPerDay : 29*msPerDay );
   1.490 +}
   1.491 +function MakeDate( day, time ) {
   1.492 +  if ( day == Number.POSITIVE_INFINITY ||
   1.493 +       day == Number.NEGATIVE_INFINITY ) {
   1.494 +    return Number.NaN;
   1.495 +  }
   1.496 +  if ( time == Number.POSITIVE_INFINITY ||
   1.497 +       time == Number.NEGATIVE_INFINITY ) {
   1.498 +    return Number.NaN;
   1.499 +  }
   1.500 +  return ( day * msPerDay ) + time;
   1.501 +}
   1.502 +function TimeClip( t ) {
   1.503 +  if ( isNaN( t ) ) {
   1.504 +    return ( Number.NaN );
   1.505 +  }
   1.506 +  if ( Math.abs( t ) > 8.64e15 ) {
   1.507 +    return ( Number.NaN );
   1.508 +  }
   1.509 +
   1.510 +  return ( ToInteger( t ) );
   1.511 +}
   1.512 +function ToInteger( t ) {
   1.513 +  t = Number( t );
   1.514 +
   1.515 +  if ( isNaN( t ) ){
   1.516 +    return ( Number.NaN );
   1.517 +  }
   1.518 +  if ( t == 0 || t == -0 ||
   1.519 +       t == Number.POSITIVE_INFINITY || t == Number.NEGATIVE_INFINITY ) {
   1.520 +    return 0;
   1.521 +  }
   1.522 +
   1.523 +  var sign = ( t < 0 ) ? -1 : 1;
   1.524 +
   1.525 +  return ( sign * Math.floor( Math.abs( t ) ) );
   1.526 +}
   1.527 +function Enumerate ( o ) {
   1.528 +  var p;
   1.529 +  for ( p in o ) {
   1.530 +    print( p +": " + o[p] );
   1.531 +  }
   1.532 +}
   1.533 +

mercurial