The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript \ Tk

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace Microsoft.JScript
  16. {
  17.    
  18.     using System;
  19.     using System.Globalization;
  20.     using System.Reflection;
  21.     using System.Text;
  22.    
  23.     enum Ps
  24.     {
  25.         Initial,
  26.         Minutes,
  27.         Seconds,
  28.         AddOffset,
  29.         SubOffset,
  30.         Date,
  31.         Year
  32.     }
  33.     enum Tk
  34.     {
  35.         Dummy,
  36.         BcAd,
  37.         AmPm,
  38.         Zone,
  39.         Day,
  40.         Month
  41.     }
  42.    
  43.     public class DatePrototype : DateObject
  44.     {
  45.         static internal readonly DatePrototype ob = new DatePrototype(ObjectPrototype.ob);
  46.         static internal DateConstructor _constructor;
  47.        
  48.         internal DatePrototype(ObjectPrototype parent) : base(parent, 0)
  49.         {
  50.             this.noExpando = true;
  51.         }
  52.        
  53.         //////////////////////////////Utility funcs//////////////////////////////////////////////////////
  54.        
  55.         private const double HoursPerDay = 24;
  56.         private const double MinutesPerHour = 60;
  57.         private const double SecondsPerMinute = 60;
  58.         private const double msPerSecond = 1000;
  59.         private const double msPerMinute = msPerSecond * SecondsPerMinute;
  60.         private const double msPerHour = msPerMinute * MinutesPerHour;
  61.         private const double msPerDay = msPerHour * HoursPerDay;
  62.         internal const double msTo1970 = msPerDay * (365 * 1969 + 1968 / 4 - 1900 / 100 + 1600 / 400);
  63.         internal const double ticksPerMillisecond = 10000;
  64.         internal const double maxDate = (long)(8.64E+15);
  65.         internal const double minDate = (long)(-8.64E+15);
  66.        
  67.         private static readonly int[] daysToMonthEnd = new int[] {31, 59, 90, 120, 151, 181, 212, 243, 273, 304,
  68.         334, 365};
  69.         private static readonly int[] leapDaysToMonthEnd = new int[] {31, 60, 91, 121, 152, 182, 213, 244, 274, 305,
  70.         335, 366};
  71.        
  72.         private static double Day(double time)
  73.         {
  74.             return Math.Floor(time / msPerDay);
  75.         }
  76.        
  77.         private static double TimeWithinDay(double time)
  78.         {
  79.             double result = time % msPerDay;
  80.             if (result < 0)
  81.                 result += msPerDay;
  82.             return result;
  83.         }
  84.        
  85.         private static int DaysInYear(double year)
  86.         {
  87.             if (year % 4 != 0.0)
  88.                 return 365;
  89.             if (year % 100 != 0.0)
  90.                 return 366;
  91.             if (year % 400 != 0.0)
  92.                 return 365;
  93.             return 366;
  94.         }
  95.        
  96.         private static double DayFromYear(double year)
  97.         {
  98.             return 365 * (year - 1970) + Math.Floor((year - 1969) / 4) - Math.Floor((year - 1901) / 100) + Math.Floor((year - 1601) / 400);
  99.         }
  100.        
  101.         private static double TimeFromYear(double year)
  102.         {
  103.             return msPerDay * DayFromYear(year);
  104.         }
  105.        
  106.         private static double YearFromTime(double time)
  107.         {
  108.             double day = Math.Floor(time / msPerDay);
  109.             double year = 1970 + Math.Floor((400 * day + 398) / 146097);
  110.             //gives us the right year, or right year + 1
  111.             double dfy = DayFromYear(year);
  112.             if (day < dfy) {
  113.                 //The first day of year is beyond day, so we have right year + 1
  114.                 year -= 1;
  115.             }
  116.             return year;
  117.         }
  118.        
  119.         private static bool InLeapYear(double year)
  120.         {
  121.             if (year % 4 != 0.0)
  122.                 return false;
  123.             if (year % 100 != 0.0)
  124.                 return true;
  125.             if (year % 400 != 0.0)
  126.                 return false;
  127.             return true;
  128.         }
  129.        
  130.         private static int MonthFromTime(double time)
  131.         {
  132.             int month = 0;
  133.             int day = DayWithinYear(time) + 1;
  134.             if (InLeapYear(YearFromTime(time)))
  135.                 while (day > leapDaysToMonthEnd[month])
  136.                     month++;
  137.             else
  138.                 while (day > daysToMonthEnd[month])
  139.                     month++;
  140.             return month;
  141.         }
  142.        
  143.         private static int DayWithinYear(double time)
  144.         {
  145.             return (int)(Day(time) - DayFromYear(YearFromTime(time)));
  146.         }
  147.        
  148.         private static int DateFromTime(double time)
  149.         {
  150.             int month = 0;
  151.             int day = DayWithinYear(time) + 1;
  152.             if (day <= 31)
  153.                 return day;
  154.             if (InLeapYear(YearFromTime(time))) {
  155.                 while (day > leapDaysToMonthEnd[month])
  156.                     month++;
  157.                 return day - leapDaysToMonthEnd[month - 1];
  158.             }
  159.             else {
  160.                 while (day > daysToMonthEnd[month])
  161.                     month++;
  162.                 return day - daysToMonthEnd[month - 1];
  163.             }
  164.         }
  165.        
  166.         private static int WeekDay(double time)
  167.         {
  168.             double result = (Day(time) + 4) % 7;
  169.             if (result < 0)
  170.                 result += 7;
  171.             return (int)result;
  172.         }
  173.        
  174.         private static bool DaylightSavingsTime(double localTime)
  175.         {
  176.             if (!useDST)
  177.                 return false;
  178.             double t = (localTime + msTo1970) * ticksPerMillisecond;
  179.             if ((double)Int64.MinValue <= t && t <= (double)Int64.MaxValue)
  180.                 try {
  181.                     DateTime dt = new DateTime((long)t);
  182.                     return System.TimeZone.CurrentTimeZone.IsDaylightSavingTime(dt);
  183.                 }
  184.                 catch (System.ArgumentOutOfRangeException) {
  185.                 }
  186.            
  187.             int month = MonthFromTime(localTime);
  188.             if (month < 3 || month > 9)
  189.                 return false;
  190.             if (month > 3 && month < 9)
  191.                 return true;
  192.             int date = DateFromTime(localTime);
  193.             if (month == 3) {
  194.                 if (date > 7)
  195.                     return true;
  196.                 int weekDay = WeekDay(localTime);
  197.                 if (weekDay > 0)
  198.                     return date > weekDay;
  199.                 return HourFromTime(localTime) > 1;
  200.             }
  201.             else {
  202.                 if (date < 25)
  203.                     return true;
  204.                 int weekDay = WeekDay(localTime);
  205.                 if (weekDay > 0)
  206.                     return date - weekDay < 25;
  207.                 return HourFromTime(localTime) < 1;
  208.             }
  209.         }
  210.        
  211.         private static readonly double localStandardTZA;
  212.         private static readonly double localDaylightTZA;
  213.         private static readonly bool useDST;
  214.        
  215.         static DatePrototype()
  216.         {
  217.             DateTime jan1ThisYear = new DateTime(DateTime.Now.Year, 1, 1);
  218.             double jantimeoffset = (jan1ThisYear.Ticks - jan1ThisYear.ToUniversalTime().Ticks) / ticksPerMillisecond;
  219.             DateTime july1ThisYear = new DateTime(DateTime.Now.Year, 7, 1);
  220.             double julytimeoffset = (july1ThisYear.Ticks - july1ThisYear.ToUniversalTime().Ticks) / ticksPerMillisecond;
  221.             if (jantimeoffset < julytimeoffset) {
  222.                 localStandardTZA = jantimeoffset;
  223.                 localDaylightTZA = julytimeoffset;
  224.             }
  225.             else {
  226.                 localStandardTZA = julytimeoffset;
  227.                 localDaylightTZA = jantimeoffset;
  228.             }
  229.             useDST = localStandardTZA != localDaylightTZA;
  230.         }
  231.        
  232.         private static double LocalTime(double utcTime)
  233.         {
  234.             return utcTime + (DaylightSavingsTime(utcTime + localStandardTZA) ? localDaylightTZA : localStandardTZA);
  235.         }
  236.        
  237.         static internal double UTC(double localTime)
  238.         {
  239.             return localTime - (DaylightSavingsTime(localTime) ? localDaylightTZA : localStandardTZA);
  240.         }
  241.        
  242.         private static int HourFromTime(double time)
  243.         {
  244.             double result = Math.Floor(time / msPerHour) % HoursPerDay;
  245.             if (result < 0)
  246.                 result += HoursPerDay;
  247.             return (int)result;
  248.         }
  249.        
  250.         private static int MinFromTime(double time)
  251.         {
  252.             double result = Math.Floor(time / msPerMinute) % MinutesPerHour;
  253.             if (result < 0)
  254.                 result += MinutesPerHour;
  255.             return (int)result;
  256.         }
  257.        
  258.         private static int SecFromTime(double time)
  259.         {
  260.             double result = Math.Floor(time / msPerSecond) % SecondsPerMinute;
  261.             if (result < 0)
  262.                 result += SecondsPerMinute;
  263.             return (int)result;
  264.         }
  265.        
  266.         private static int msFromTime(double time)
  267.         {
  268.             double result = time % msPerSecond;
  269.             if (result < 0)
  270.                 result += msPerSecond;
  271.             return (int)result;
  272.         }
  273.        
  274.         static internal double MakeTime(double hour, double min, double sec, double ms)
  275.         {
  276.             if (Double.IsInfinity(hour) || Double.IsInfinity(min) || Double.IsInfinity(sec) || Double.IsInfinity(ms) || hour != hour || min != min || sec != sec || ms != ms)
  277.                 return Double.NaN;
  278.             hour = (double)(int)Runtime.DoubleToInt64(hour);
  279.             min = (double)(int)Runtime.DoubleToInt64(min);
  280.             sec = (double)(int)Runtime.DoubleToInt64(sec);
  281.             ms = (double)(int)Runtime.DoubleToInt64(ms);
  282.             return hour * msPerHour + min * msPerMinute + sec * msPerSecond + ms;
  283.         }
  284.        
  285.         static internal double MakeDay(double year, double month, double date)
  286.         {
  287.             if (Double.IsInfinity(year) || Double.IsInfinity(month) || Double.IsInfinity(date) || year != year || month != month || date != date)
  288.                 return Double.NaN;
  289.             year = (double)(int)Runtime.DoubleToInt64(year);
  290.             month = (double)(int)Runtime.DoubleToInt64(month);
  291.             date = (double)(int)Runtime.DoubleToInt64(date);
  292.             year += Math.Floor(month / 12);
  293.             month = month % 12;
  294.             if (month < 0)
  295.                 month += 12;
  296.             double daysToMonthStart = 0;
  297.             if (month > 0)
  298.                 if (InLeapYear((int)Runtime.DoubleToInt64(year)))
  299.                     daysToMonthStart = leapDaysToMonthEnd[(int)(month - 1)];
  300.                 else
  301.                     daysToMonthStart = daysToMonthEnd[(int)(month - 1)];
  302.             return DayFromYear(year) - 1 + daysToMonthStart + date;
  303.         }
  304.        
  305.         static internal double MakeDate(double day, double time)
  306.         {
  307.             if (Double.IsInfinity(day) || Double.IsInfinity(time))
  308.                 return Double.NaN;
  309.             return day * msPerDay + time;
  310.         }
  311.        
  312.         static internal double TimeClip(double time)
  313.         {
  314.             if (Double.IsInfinity(time))
  315.                 return Double.NaN;
  316.             if (minDate <= time && time <= maxDate)
  317.                 return (double)(long)time;
  318.             else
  319.                 return Double.NaN;
  320.         }
  321.        
  322.         static internal string DateToLocaleDateString(double time)
  323.         {
  324.             if (Double.IsNaN(time))
  325.                 return "NaN";
  326.             StringBuilder result = new StringBuilder();
  327.             int month = MonthFromTime(time) + 1;
  328.             if (month < 10)
  329.                 result.Append("0");
  330.             result.Append(month);
  331.             result.Append("/");
  332.             int date = DateFromTime(time);
  333.             if (date < 10)
  334.                 result.Append("0");
  335.             result.Append(date);
  336.             result.Append("/");
  337.             result.Append(YearString(time));
  338.             return result.ToString();
  339.         }
  340.        
  341.         static internal string DateToLocaleString(double time)
  342.         {
  343.             if (Double.IsNaN(time))
  344.                 return "NaN";
  345.             StringBuilder result = new StringBuilder();
  346.             int month = MonthFromTime(time) + 1;
  347.             if (month < 10)
  348.                 result.Append("0");
  349.             result.Append(month);
  350.             result.Append("/");
  351.             int date = DateFromTime(time);
  352.             if (date < 10)
  353.                 result.Append("0");
  354.             result.Append(date);
  355.             result.Append("/");
  356.             result.Append(YearString(time));
  357.             result.Append(" ");
  358.             AppendTime(time, result);
  359.             return result.ToString();
  360.         }
  361.        
  362.         static internal string DateToLocaleTimeString(double time)
  363.         {
  364.             if (Double.IsNaN(time))
  365.                 return "NaN";
  366.             StringBuilder result = new StringBuilder();
  367.             AppendTime(time, result);
  368.             return result.ToString();
  369.         }
  370.        
  371.         static void AppendTime(double time, StringBuilder sb)
  372.         {
  373.             int hour = HourFromTime(time);
  374.             if (hour < 10)
  375.                 sb.Append("0");
  376.             sb.Append(hour);
  377.             sb.Append(":");
  378.             int minute = MinFromTime(time);
  379.             if (minute < 10)
  380.                 sb.Append("0");
  381.             sb.Append(minute);
  382.             sb.Append(":");
  383.             int second = SecFromTime(time);
  384.             if (second < 10)
  385.                 sb.Append("0");
  386.             sb.Append(second);
  387.         }
  388.        
  389.         static string TimeZoneID(double utcTime)
  390.         {
  391.             int tz = (int)(localStandardTZA / msPerHour);
  392.             if (DaylightSavingsTime(utcTime + localStandardTZA))
  393.                 switch (tz) {
  394.                     case -5:
  395.                         return "EDT";
  396.                     case -6:
  397.                         return "CDT";
  398.                     case -7:
  399.                         return "MDT";
  400.                     case -8:
  401.                         return "PDT";
  402.                 }
  403.             else
  404.                 switch (tz) {
  405.                     case -5:
  406.                         return "EST";
  407.                     case -6:
  408.                         return "CST";
  409.                     case -7:
  410.                         return "MST";
  411.                     case -8:
  412.                         return "PST";
  413.                 }
  414.             return (tz >= 0 ? "UTC+" : "UTC") + tz.ToString(CultureInfo.InvariantCulture);
  415.         }
  416.        
  417.         static string YearString(double time)
  418.         {
  419.             double year = YearFromTime(time);
  420.             if (year > 0)
  421.                 return year.ToString(CultureInfo.InvariantCulture);
  422.             else {
  423.                 return (1 - year).ToString(CultureInfo.InvariantCulture) + " B.C.";
  424.             }
  425.         }
  426.        
  427.        
  428.         static readonly string[] WeekDayName = new string[] {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  429.         static readonly string[] MonthName = new string[] {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
  430.         "Nov", "Dec"};
  431.        
  432.         static internal string DateToDateString(double utcTime)
  433.         {
  434.             if (Double.IsNaN(utcTime))
  435.                 return "NaN";
  436.             StringBuilder result = new StringBuilder();
  437.             double localTime = LocalTime(utcTime);
  438.             result.Append(WeekDayName[WeekDay(localTime)]);
  439.             result.Append(" ");
  440.             int month = MonthFromTime(localTime);
  441.             result.Append(MonthName[month]);
  442.             result.Append(" ");
  443.             result.Append(DateFromTime(localTime));
  444.             result.Append(" ");
  445.             result.Append(YearString(localTime));
  446.             return result.ToString();
  447.         }
  448.        
  449.         static internal string DateToString(double utcTime)
  450.         {
  451.             if (Double.IsNaN(utcTime))
  452.                 return "NaN";
  453.             StringBuilder result = new StringBuilder();
  454.             double localTime = LocalTime(utcTime);
  455.             result.Append(WeekDayName[WeekDay(localTime)]);
  456.             result.Append(" ");
  457.             int month = MonthFromTime(localTime);
  458.             result.Append(MonthName[month]);
  459.             result.Append(" ");
  460.             result.Append(DateFromTime(localTime));
  461.             result.Append(" ");
  462.             AppendTime(localTime, result);
  463.             result.Append(" ");
  464.             result.Append(TimeZoneID(utcTime));
  465.             result.Append(" ");
  466.             result.Append(YearString(localTime));
  467.             return result.ToString();
  468.         }
  469.        
  470.         static internal string DateToTimeString(double utcTime)
  471.         {
  472.             if (Double.IsNaN(utcTime))
  473.                 return "NaN";
  474.             StringBuilder result = new StringBuilder();
  475.             double localTime = LocalTime(utcTime);
  476.             AppendTime(localTime, result);
  477.             result.Append(" ");
  478.             result.Append(TimeZoneID(utcTime));
  479.             return result.ToString();
  480.         }
  481.        
  482.         static internal string UTCDateToString(double utcTime)
  483.         {
  484.             if (Double.IsNaN(utcTime))
  485.                 return "NaN";
  486.             StringBuilder result = new StringBuilder();
  487.             result.Append(WeekDayName[WeekDay(utcTime)]);
  488.             result.Append(", ");
  489.             result.Append(DateFromTime(utcTime));
  490.             result.Append(" ");
  491.             result.Append(MonthName[MonthFromTime(utcTime)]);
  492.             result.Append(" ");
  493.             result.Append(YearString(utcTime));
  494.             result.Append(" ");
  495.             AppendTime(utcTime, result);
  496.             result.Append(" UTC");
  497.             return result.ToString();
  498.         }
  499.        
  500.         static bool NotSpecified(object value)
  501.         {
  502.             return value == null || value is Missing;
  503.         }
  504.        
  505.         static bool isASCII(char ch)
  506.         {
  507.             return ((int)ch) < 128;
  508.         }
  509.        
  510.         static bool isalpha(char ch)
  511.         {
  512.             return 'A' <= ch && ch <= 'Z' || 'a' <= ch && ch <= 'z';
  513.         }
  514.        
  515.         static bool isdigit(char ch)
  516.         {
  517.             return '0' <= ch && ch <= '9';
  518.         }
  519.        
  520.         static readonly string[] Strings = new string[] {"bc", "b.c", "ad", "a.d", "am", "a.m", "pm", "p.m", "est", "edt",
  521.         "cst", "cdt", "mst", "mdt", "pst", "pdt", "gmt", "utc", "sunday", "monday",
  522.         "tuesday", "wednesday", "thursday", "friday", "saturday", "january", "february", "march", "april", "may",
  523.         "june", "july", "august", "september", "october", "november", "december"};
  524.        
  525.         static readonly Tk[] Tokens = new Tk[] {Tk.BcAd, Tk.BcAd, Tk.BcAd, Tk.BcAd, Tk.AmPm, Tk.AmPm, Tk.AmPm, Tk.AmPm, Tk.Zone, Tk.Zone,
  526.         Tk.Zone, Tk.Zone, Tk.Zone, Tk.Zone, Tk.Zone, Tk.Zone, Tk.Zone, Tk.Zone, Tk.Day, Tk.Day,
  527.         Tk.Day, Tk.Day, Tk.Day, Tk.Day, Tk.Day, Tk.Month, Tk.Month, Tk.Month, Tk.Month, Tk.Month,
  528.         Tk.Month, Tk.Month, Tk.Month, Tk.Month, Tk.Month, Tk.Month, Tk.Month};
  529.        
  530.         static readonly int[] Values = new int[] {-1, -1, +1, +1, -1, -1, +1, +1, -5 * 60, -4 * 60,
  531.         -6 * 60, -5 * 60, -7 * 60, -6 * 60, -8 * 60, -7 * 60, 0, 0, 0, 1,
  532.         2, 3, 4, 5, 6, 0, 1, 2, 3, 4,
  533.         5, 6, 7, 8, 9, 10, 11};
  534.        
  535.         static internal double ParseDate(string str)
  536.         {
  537.             long Nil = 2147483648u;
  538.            
  539.             int AmPm = 0;
  540.             int BcAd = 0;
  541.             Ps ps = Ps.Initial;
  542.             long Year = Nil;
  543.             long Month = Nil;
  544.             long Date = Nil;
  545.             long Time = Nil;
  546.             long Zone = Nil;
  547.             long Offset = Nil;
  548.            
  549.             str = str.ToLowerInvariant();
  550.            
  551.             int i = 0;
  552.             int n = str.Length;
  553.             while (i < n) {
  554.                 char ch = str[i++];
  555.                 if (ch <= ' ')
  556.                     continue;
  557.                 switch (ch) {
  558.                     case '(':
  559.                         // skip stuff in parens
  560.                         for (int depth = 1; i < n;) {
  561.                             ch = str[i++];
  562.                             if (ch == '(')
  563.                                 depth++;
  564.                             else if (ch == ')' && --depth <= 0)
  565.                                 break;
  566.                         }
  567.                         continue;
  568.                     case ',':
  569.                         continue;
  570.                     case ':':
  571.                         continue;
  572.                     case '/':
  573.                         continue;
  574.                     case '+':
  575.                         if (Nil != Year)
  576.                             ps = Ps.AddOffset;
  577.                         continue;
  578.                     case '-':
  579.                         if (Nil != Year)
  580.                             ps = Ps.SubOffset;
  581.                         continue;
  582.                     default:
  583.                         break;
  584.                 }
  585.                
  586.                 if (isalpha(ch)) {
  587.                     //scan an alpha token
  588.                     int j = i - 1;
  589.                     //remember start of token
  590.                     while (i < n) {
  591.                         ch = str[i++];
  592.                         if (isalpha(ch) || '.' == ch)
  593.                             continue;
  594.                         break;
  595.                     }
  596.                    
  597.                     int cch = i - j - (i < n ? 1 : 0);
  598.                     if ('.' == str[i - (i < n ? 2 : 1)])
  599.                         //Exclude a trailing dot from the token
  600.                         cch--;
  601.                    
  602.                     // skip over any spaces
  603.                     while (ch == ' ' && i < n)
  604.                         ch = str[i++];
  605.                    
  606.                     // have an alphabetic token - look it up
  607.                    
  608.                     if (1 == cch) {
  609.                         // military version of time zone
  610.                         // z = GMT
  611.                         // j isn't used
  612.                         // a to m are -1 to -12
  613.                         // n to y are 1 to 12
  614.                         if (Nil != Zone)
  615.                             return Double.NaN;
  616.                         char chj = str[j];
  617.                         if (chj <= 'm') {
  618.                             if (chj == 'j' || chj < 'a')
  619.                                 return Double.NaN;
  620.                             Zone = -(long)(chj - 'a' + (chj < 'j' ? 1 : 0)) * 60;
  621.                         }
  622.                         else if (chj <= 'y')
  623.                             Zone = (long)(chj - 'm') * 60;
  624.                         else if (chj == 'z')
  625.                             Zone = 0;
  626.                         else
  627.                             return Double.NaN;
  628.                        
  629.                         // look for a time zone offset
  630.                         if ('+' == ch) {
  631.                             ps = Ps.AddOffset;
  632.                         }
  633.                         else if ('-' == ch) {
  634.                             ps = Ps.SubOffset;
  635.                         }
  636.                         else
  637.                             ps = Ps.Initial;
  638.                        
  639.                         continue;
  640.                     }
  641.                    
  642.                     for (int kk = Strings.Length - 1; kk >= 0; kk--) {
  643.                         string tkstr = Strings[kk];
  644.                         if (tkstr.Length < cch)
  645.                             continue;
  646.                         if (0 != String.CompareOrdinal(str, j, tkstr, 0, cch)) {
  647.                             if (kk == 0)
  648.                                 return Double.NaN;
  649.                             //The current token does not match anything. Date string cannot be parsed by this routine.
  650.                         }
  651.                         else {
  652.                             switch (Tokens[kk]) {
  653.                                 case Tk.BcAd:
  654.                                     if (0 != BcAd)
  655.                                         return Double.NaN;
  656.                                     BcAd = Values[kk];
  657.                                     break;
  658.                                 case Tk.AmPm:
  659.                                     if (0 != AmPm)
  660.                                         return Double.NaN;
  661.                                     AmPm = Values[kk];
  662.                                     break;
  663.                                 case Tk.Month:
  664.                                     if (Nil != Month)
  665.                                         return Double.NaN;
  666.                                     Month = Values[kk];
  667.                                     break;
  668.                                 case Tk.Zone:
  669.                                     if (Nil != Zone)
  670.                                         return Double.NaN;
  671.                                     Zone = Values[kk];
  672.                                    
  673.                                     // look for a time zone offset
  674.                                     if ('+' == ch) {
  675.                                         ps = Ps.AddOffset;
  676.                                         i++;
  677.                                     }
  678.                                     else if ('-' == ch) {
  679.                                         ps = Ps.SubOffset;
  680.                                         i++;
  681.                                     }
  682.                                     else
  683.                                         ps = Ps.Initial;
  684.                                     break;
  685.                             }
  686.                             break;
  687.                             //out of the loop matching the current token with known tokens
  688.                         }
  689.                     }
  690.                     if (i < n)
  691.                         i--;
  692.                     continue;
  693.                     //with overall loop, looking for next bit of date
  694.                 }
  695.                
  696.                 if (!isdigit(ch))
  697.                     return Double.NaN;
  698.                
  699.                 int T = 0;
  700.                 int k = i;
  701.                 do {
  702.                     T = T * 10 + ch - '0';
  703.                     if (i >= n)
  704.                         break;
  705.                     ch = str[i++];
  706.                 }
  707.                 while (isdigit(ch));
  708.                
  709.                 // to avoid overflow
  710.                 if (i - k > 6)
  711.                     return Double.NaN;
  712.                
  713.                 // skip over any spaces
  714.                 while (ch == ' ' && i < n)
  715.                     ch = str[i++];
  716.                
  717.                 switch (ps) {
  718.                     case Ps.AddOffset:
  719.                         if (Nil != Offset)
  720.                             return Double.NaN;
  721.                         Offset = T < 24 ? T * 60 : (T % 100) + (T / 100) * 60;
  722.                         //> 24 implies hhmm
  723.                         ps = Ps.Initial;
  724.                         if (i < n)
  725.                             i--;
  726.                         break;
  727.                     case Ps.SubOffset:
  728.                        
  729.                         if (Nil != Offset)
  730.                             return Double.NaN;
  731.                         Offset = T < 24 ? -T * 60 : -((T % 100) + (T / 100) * 60);
  732.                         //> 24 implies hhmm
  733.                         ps = Ps.Initial;
  734.                         if (i < n)
  735.                             i--;
  736.                         break;
  737.                     case Ps.Minutes:
  738.                        
  739.                         if (T >= 60)
  740.                             return Double.NaN;
  741.                         Time += T * 60;
  742.                         if (ch == ':') {
  743.                             ps = Ps.Seconds;
  744.                         }
  745.                         else {
  746.                             ps = Ps.Initial;
  747.                             if (i < n)
  748.                                 i--;
  749.                         }
  750.                         break;
  751.                     case Ps.Seconds:
  752.                        
  753.                         if (T >= 60)
  754.                             return Double.NaN;
  755.                         Time += T;
  756.                         ps = Ps.Initial;
  757.                         if (i < n)
  758.                             i--;
  759.                         break;
  760.                     case Ps.Date:
  761.                        
  762.                         if (Nil != Date)
  763.                             return Double.NaN;
  764.                         Date = T;
  765.                         if ('/' == ch || '-' == ch) {
  766.                             ps = Ps.Year;
  767.                         }
  768.                         else {
  769.                             ps = Ps.Initial;
  770.                             if (i < n)
  771.                                 i--;
  772.                         }
  773.                         break;
  774.                     case Ps.Year:
  775.                        
  776.                         if (Nil != Year)
  777.                             return Double.NaN;
  778.                         Year = T;
  779.                         ps = Ps.Initial;
  780.                         if (i < n)
  781.                             i--;
  782.                         break;
  783.                     default:
  784.                        
  785.                         //Assert(ps == Ps.Initial);
  786.                         if (T >= 70) {
  787.                             // assume it's a year
  788.                             if (Nil != Year)
  789.                                 return Double.NaN;
  790.                             Year = T;
  791.                             if (i < n)
  792.                                 i--;
  793.                             break;
  794.                         }
  795.                        
  796.                         switch (ch) {
  797.                             case ':':
  798.                                 // hour
  799.                                 if (Nil != Time)
  800.                                     return Double.NaN;
  801.                                 if (T >= 24)
  802.                                     return Double.NaN;
  803.                                 Time = T * 3600;
  804.                                 ps = Ps.Minutes;
  805.                                 break;
  806.                             case '/':
  807.                                
  808.                                 goto case '-';
  809.                                 break;
  810.                             case '-':
  811.                                
  812.                                 // month
  813.                                 if (Nil != Month)
  814.                                     return Double.NaN;
  815.                                 Month = T - 1;
  816.                                 ps = Ps.Date;
  817.                                 break;
  818.                             default:
  819.                                
  820.                                 // date
  821.                                 if (Nil != Date)
  822.                                     return Double.NaN;
  823.                                 Date = T;
  824.                                 if (i < n)
  825.                                     i--;
  826.                                 break;
  827.                         }
  828.                         break;
  829.                 }
  830.             }
  831.            
  832.             if (Nil == Year || Nil == Month || Nil == Date)
  833.                 return Double.NaN;
  834.            
  835.             if (0 != BcAd) {
  836.                 if (BcAd < 0)
  837.                     // BC. Note that 1 BC is year 0 and 2 BC is year -1.
  838.                     Year = -Year + 1;
  839.             }
  840.             else if (Year < 100)
  841.                 Year += 1900;
  842.            
  843.             if (0 != AmPm) {
  844.                 if (Nil == Time)
  845.                     return Double.NaN;
  846.                 if (Time >= 12 * 3600 && Time < 13 * 3600) {
  847.                     // In the 12:00 hour. AM means subtract 12 hours and PM means
  848.                     // do nothing.
  849.                     if (AmPm < 0)
  850.                         Time -= 12 * 3600;
  851.                 }
  852.                 else {
  853.                     // Not in the 12:00 hour. AM means do nothing and PM means
  854.                     // add 12 hours.
  855.                     if (AmPm > 0) {
  856.                         if (Time >= 12 * 3600)
  857.                             return Double.NaN;
  858.                         Time += 12 * 3600;
  859.                     }
  860.                 }
  861.             }
  862.             else if (Nil == Time)
  863.                 Time = 0;
  864.            
  865.             bool Utc = false;
  866.             if (Nil != Zone) {
  867.                 Time -= Zone * 60;
  868.                 Utc = true;
  869.             }
  870.             if (Nil != Offset)
  871.                 Time -= Offset * 60;
  872.            
  873.             // Rebuild time.
  874.             double result = MakeDate(MakeDay(Year, Month, Date), Time * 1000);
  875.             if (!Utc)
  876.                 result = UTC(result);
  877.             return result;
  878.         }
  879.        
  880.         ////////////////////////////////public funcs visible from scripts//////////////////////////////////
  881.        
  882.         public static DateConstructor constructor {
  883.             get { return DatePrototype._constructor; }
  884.         }
  885.        
  886.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getDate)]
  887.         public static double getDate(object thisob)
  888.         {
  889.             if (!(thisob is DateObject))
  890.                 throw new JScriptException(JSError.DateExpected);
  891.             double t = ((DateObject)thisob).value;
  892.             if (t != t)
  893.                 return t;
  894.             return DateFromTime(LocalTime(t));
  895.         }
  896.        
  897.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getDay)]
  898.         public static double getDay(object thisob)
  899.         {
  900.             if (!(thisob is DateObject))
  901.                 throw new JScriptException(JSError.DateExpected);
  902.             double t = ((DateObject)thisob).value;
  903.             if (t != t)
  904.                 return t;
  905.             return WeekDay(LocalTime(t));
  906.         }
  907.        
  908.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getFullYear)]
  909.         public static double getFullYear(object thisob)
  910.         {
  911.             if (!(thisob is DateObject))
  912.                 throw new JScriptException(JSError.DateExpected);
  913.             double t = ((DateObject)thisob).value;
  914.             if (t != t)
  915.                 return t;
  916.             return YearFromTime(LocalTime(t));
  917.         }
  918.        
  919.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getHours)]
  920.         public static double getHours(object thisob)
  921.         {
  922.             if (!(thisob is DateObject))
  923.                 throw new JScriptException(JSError.DateExpected);
  924.             double t = ((DateObject)thisob).value;
  925.             if (t != t)
  926.                 return t;
  927.             return HourFromTime(LocalTime(t));
  928.         }
  929.        
  930.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getMilliseconds)]
  931.         public static double getMilliseconds(object thisob)
  932.         {
  933.             if (!(thisob is DateObject))
  934.                 throw new JScriptException(JSError.DateExpected);
  935.             double t = ((DateObject)thisob).value;
  936.             if (t != t)
  937.                 return t;
  938.             return msFromTime(LocalTime(t));
  939.         }
  940.        
  941.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getMinutes)]
  942.         public static double getMinutes(object thisob)
  943.         {
  944.             if (!(thisob is DateObject))
  945.                 throw new JScriptException(JSError.DateExpected);
  946.             double t = ((DateObject)thisob).value;
  947.             if (t != t)
  948.                 return t;
  949.             return MinFromTime(LocalTime(t));
  950.         }
  951.        
  952.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getMonth)]
  953.         public static double getMonth(object thisob)
  954.         {
  955.             if (!(thisob is DateObject))
  956.                 throw new JScriptException(JSError.DateExpected);
  957.             double t = ((DateObject)thisob).value;
  958.             if (t != t)
  959.                 return t;
  960.             return MonthFromTime(LocalTime(t));
  961.         }
  962.        
  963.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getSeconds)]
  964.         public static double getSeconds(object thisob)
  965.         {
  966.             if (!(thisob is DateObject))
  967.                 throw new JScriptException(JSError.DateExpected);
  968.             double t = ((DateObject)thisob).value;
  969.             if (t != t)
  970.                 return t;
  971.             return SecFromTime(LocalTime(t));
  972.         }
  973.        
  974.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getTime)]
  975.         public static double getTime(object thisob)
  976.         {
  977.             if (!(thisob is DateObject))
  978.                 throw new JScriptException(JSError.DateExpected);
  979.             return ((DateObject)thisob).value;
  980.         }
  981.        
  982.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getTimezoneOffset)]
  983.         public static double getTimezoneOffset(object thisob)
  984.         {
  985.             if (!(thisob is DateObject))
  986.                 throw new JScriptException(JSError.DateExpected);
  987.             double t = ((DateObject)thisob).value;
  988.             if (t != t)
  989.                 return t;
  990.             return (t - LocalTime(t)) / msPerMinute;
  991.         }
  992.        
  993.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getUTCDate)]
  994.         public static double getUTCDate(object thisob)
  995.         {
  996.             if (!(thisob is DateObject))
  997.                 throw new JScriptException(JSError.DateExpected);
  998.             double t = ((DateObject)thisob).value;
  999.             if (t != t)
  1000.                 return t;
  1001.             return DateFromTime(t);
  1002.         }
  1003.        
  1004.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getUTCDay)]
  1005.         public static double getUTCDay(object thisob)
  1006.         {
  1007.             if (!(thisob is DateObject))
  1008.                 throw new JScriptException(JSError.DateExpected);
  1009.             double t = ((DateObject)thisob).value;
  1010.             if (t != t)
  1011.                 return t;
  1012.             return WeekDay(t);
  1013.         }
  1014.        
  1015.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getUTCFullYear)]
  1016.         public static double getUTCFullYear(object thisob)
  1017.         {
  1018.             if (!(thisob is DateObject))
  1019.                 throw new JScriptException(JSError.DateExpected);
  1020.             double t = ((DateObject)thisob).value;
  1021.             if (t != t)
  1022.                 return t;
  1023.             return YearFromTime(t);
  1024.         }
  1025.        
  1026.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getUTCHours)]
  1027.         public static double getUTCHours(object thisob)
  1028.         {
  1029.             if (!(thisob is DateObject))
  1030.                 throw new JScriptException(JSError.DateExpected);
  1031.             double t = ((DateObject)thisob).value;
  1032.             if (t != t)
  1033.                 return t;
  1034.             return HourFromTime(t);
  1035.         }
  1036.        
  1037.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getUTCMilliseconds)]
  1038.         public static double getUTCMilliseconds(object thisob)
  1039.         {
  1040.             if (!(thisob is DateObject))
  1041.                 throw new JScriptException(JSError.DateExpected);
  1042.             double t = ((DateObject)thisob).value;
  1043.             if (t != t)
  1044.                 return t;
  1045.             return msFromTime(t);
  1046.         }
  1047.        
  1048.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getUTCMinutes)]
  1049.         public static double getUTCMinutes(object thisob)
  1050.         {
  1051.             if (!(thisob is DateObject))
  1052.                 throw new JScriptException(JSError.DateExpected);
  1053.             double t = ((DateObject)thisob).value;
  1054.             if (t != t)
  1055.                 return t;
  1056.             return MinFromTime(t);
  1057.         }
  1058.        
  1059.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getUTCMonth)]
  1060.         public static double getUTCMonth(object thisob)
  1061.         {
  1062.             if (!(thisob is DateObject))
  1063.                 throw new JScriptException(JSError.DateExpected);
  1064.             double t = ((DateObject)thisob).value;
  1065.             if (t != t)
  1066.                 return t;
  1067.             return MonthFromTime(t);
  1068.         }
  1069.        
  1070.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getUTCSeconds)]
  1071.         public static double getUTCSeconds(object thisob)
  1072.         {
  1073.             if (!(thisob is DateObject))
  1074.                 throw new JScriptException(JSError.DateExpected);
  1075.             double t = ((DateObject)thisob).value;
  1076.             if (t != t)
  1077.                 return t;
  1078.             return SecFromTime(t);
  1079.         }
  1080.        
  1081.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getVarDate)]
  1082.         public static object getVarDate(object thisob)
  1083.         {
  1084.             if (!(thisob is DateObject))
  1085.                 throw new JScriptException(JSError.DateExpected);
  1086.             double t = ((DateObject)thisob).value;
  1087.             if (t != t)
  1088.                 return null;
  1089.             long it;
  1090.             checked {
  1091.                 try {
  1092.                     it = (long)(LocalTime(t) + msTo1970) * (long)ticksPerMillisecond;
  1093.                 }
  1094.                 catch (System.OverflowException) {
  1095.                     return null;
  1096.                 }
  1097.             }
  1098.             if (it < DateTime.MinValue.Ticks || it > DateTime.MaxValue.Ticks)
  1099.                 return null;
  1100.             DateTime dt;
  1101.             try {
  1102.                 dt = new DateTime(it);
  1103.             }
  1104.             catch (System.ArgumentOutOfRangeException) {
  1105.                 return null;
  1106.             }
  1107.             return dt;
  1108.         }
  1109.        
  1110.         [NotRecommended("getYear")]
  1111.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_getYear)]
  1112.         public static double getYear(object thisob)
  1113.         {
  1114.             if (!(thisob is DateObject))
  1115.                 throw new JScriptException(JSError.DateExpected);
  1116.             double t = ((DateObject)thisob).value;
  1117.             if (t != t)
  1118.                 return t;
  1119.             double year = YearFromTime(LocalTime(t));
  1120.             if (1900 <= year && year <= 1999)
  1121.                 return year - 1900;
  1122.             else
  1123.                 return year;
  1124.         }
  1125.        
  1126.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setDate)]
  1127.         public static double setDate(object thisob, double ddate)
  1128.         {
  1129.             if (!(thisob is DateObject))
  1130.                 throw new JScriptException(JSError.DateExpected);
  1131.             double t = LocalTime(((DateObject)thisob).value);
  1132.             double dday = MakeDay(YearFromTime(t), MonthFromTime(t), ddate);
  1133.             t = TimeClip(UTC(MakeDate(dday, TimeWithinDay(t))));
  1134.             ((DateObject)thisob).value = t;
  1135.             return t;
  1136.         }
  1137.        
  1138.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setFullYear)]
  1139.         public static double setFullYear(object thisob, double dyear, object month, object date)
  1140.         {
  1141.             if (!(thisob is DateObject))
  1142.                 throw new JScriptException(JSError.DateExpected);
  1143.             double t = LocalTime(((DateObject)thisob).value);
  1144.             double dmonth = NotSpecified(month) ? MonthFromTime(t) : Convert.ToNumber(month);
  1145.             double ddate = NotSpecified(date) ? DateFromTime(t) : Convert.ToNumber(date);
  1146.             double day = MakeDay(dyear, dmonth, ddate);
  1147.             t = TimeClip(UTC(MakeDate(day, TimeWithinDay(t))));
  1148.             ((DateObject)thisob).value = t;
  1149.             return t;
  1150.         }
  1151.        
  1152.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setHours)]
  1153.         public static double setHours(object thisob, double dhour, object min, object sec, object msec)
  1154.         {
  1155.             if (!(thisob is DateObject))
  1156.                 throw new JScriptException(JSError.DateExpected);
  1157.             double t = LocalTime(((DateObject)thisob).value);
  1158.             double dmin = NotSpecified(min) ? MinFromTime(t) : Convert.ToNumber(min);
  1159.             double dsec = NotSpecified(sec) ? SecFromTime(t) : Convert.ToNumber(sec);
  1160.             double dmsec = NotSpecified(msec) ? msFromTime(t) : Convert.ToNumber(msec);
  1161.             t = TimeClip(UTC(MakeDate(Day(t), MakeTime(dhour, dmin, dsec, dmsec))));
  1162.             ((DateObject)thisob).value = t;
  1163.             return t;
  1164.         }
  1165.        
  1166.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setMinutes)]
  1167.         public static double setMinutes(object thisob, double dmin, object sec, object msec)
  1168.         {
  1169.             if (!(thisob is DateObject))
  1170.                 throw new JScriptException(JSError.DateExpected);
  1171.             double t = LocalTime(((DateObject)thisob).value);
  1172.             double dsec = NotSpecified(sec) ? SecFromTime(t) : Convert.ToNumber(sec);
  1173.             double dmsec = NotSpecified(msec) ? msFromTime(t) : Convert.ToNumber(msec);
  1174.             t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), dmin, dsec, dmsec))));
  1175.             ((DateObject)thisob).value = t;
  1176.             return t;
  1177.         }
  1178.        
  1179.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setMilliseconds)]
  1180.         public static double setMilliseconds(object thisob, double dmsec)
  1181.         {
  1182.             if (!(thisob is DateObject))
  1183.                 throw new JScriptException(JSError.DateExpected);
  1184.             double t = LocalTime(((DateObject)thisob).value);
  1185.             t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), dmsec))));
  1186.             ((DateObject)thisob).value = t;
  1187.             return t;
  1188.         }
  1189.        
  1190.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setMonth)]
  1191.         public static double setMonth(object thisob, double dmonth, object date)
  1192.         {
  1193.             if (!(thisob is DateObject))
  1194.                 throw new JScriptException(JSError.DateExpected);
  1195.             double t = LocalTime(((DateObject)thisob).value);
  1196.             double ddate = NotSpecified(date) ? DateFromTime(t) : Convert.ToNumber(date);
  1197.             double day = MakeDay(YearFromTime(t), dmonth, ddate);
  1198.             t = TimeClip(UTC(MakeDate(day, TimeWithinDay(t))));
  1199.             ((DateObject)thisob).value = t;
  1200.             return t;
  1201.         }
  1202.        
  1203.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setSeconds)]
  1204.         public static double setSeconds(object thisob, double dsec, object msec)
  1205.         {
  1206.             if (!(thisob is DateObject))
  1207.                 throw new JScriptException(JSError.DateExpected);
  1208.             double t = LocalTime(((DateObject)thisob).value);
  1209.             double dmsec = NotSpecified(msec) ? msFromTime(t) : Convert.ToNumber(msec);
  1210.             t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), dsec, dmsec))));
  1211.             ((DateObject)thisob).value = t;
  1212.             return t;
  1213.         }
  1214.        
  1215.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setTime)]
  1216.         public static double setTime(object thisob, double time)
  1217.         {
  1218.             if (!(thisob is DateObject))
  1219.                 throw new JScriptException(JSError.DateExpected);
  1220.             time = TimeClip(time);
  1221.             ((DateObject)thisob).value = time;
  1222.             return time;
  1223.         }
  1224.        
  1225.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setUTCDate)]
  1226.         public static double setUTCDate(object thisob, double ddate)
  1227.         {
  1228.             if (!(thisob is DateObject))
  1229.                 throw new JScriptException(JSError.DateExpected);
  1230.             double t = ((DateObject)thisob).value;
  1231.             double day = MakeDay(YearFromTime(t), MonthFromTime(t), ddate);
  1232.             t = TimeClip(MakeDate(day, TimeWithinDay(t)));
  1233.             ((DateObject)thisob).value = t;
  1234.             return t;
  1235.         }
  1236.        
  1237.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setUTCFullYear)]
  1238.         public static double setUTCFullYear(object thisob, double dyear, object month, object date)
  1239.         {
  1240.             if (!(thisob is DateObject))
  1241.                 throw new JScriptException(JSError.DateExpected);
  1242.             double t = ((DateObject)thisob).value;
  1243.             double dmonth = NotSpecified(month) ? MonthFromTime(t) : Convert.ToNumber(month);
  1244.             double ddate = NotSpecified(date) ? DateFromTime(t) : Convert.ToNumber(date);
  1245.             double day = MakeDay(dyear, dmonth, ddate);
  1246.             t = TimeClip(MakeDate(day, TimeWithinDay(t)));
  1247.             ((DateObject)thisob).value = t;
  1248.             return t;
  1249.         }
  1250.        
  1251.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setUTCHours)]
  1252.         public static double setUTCHours(object thisob, double dhour, object min, object sec, object msec)
  1253.         {
  1254.             if (!(thisob is DateObject))
  1255.                 throw new JScriptException(JSError.DateExpected);
  1256.             double t = ((DateObject)thisob).value;
  1257.             double dmin = NotSpecified(min) ? MinFromTime(t) : Convert.ToNumber(min);
  1258.             double dsec = NotSpecified(sec) ? SecFromTime(t) : Convert.ToNumber(sec);
  1259.             double dmsec = NotSpecified(msec) ? msFromTime(t) : Convert.ToNumber(msec);
  1260.             t = TimeClip(MakeDate(Day(t), MakeTime(dhour, dmin, dsec, dmsec)));
  1261.             ((DateObject)thisob).value = t;
  1262.             return t;
  1263.         }
  1264.        
  1265.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setUTCMinutes)]
  1266.         public static double setUTCMinutes(object thisob, double dmin, object sec, object msec)
  1267.         {
  1268.             if (!(thisob is DateObject))
  1269.                 throw new JScriptException(JSError.DateExpected);
  1270.             double t = ((DateObject)thisob).value;
  1271.             double dsec = NotSpecified(sec) ? SecFromTime(t) : Convert.ToNumber(sec);
  1272.             double dmsec = NotSpecified(msec) ? msFromTime(t) : Convert.ToNumber(msec);
  1273.             t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), dmin, dsec, dmsec)));
  1274.             ((DateObject)thisob).value = t;
  1275.             return t;
  1276.         }
  1277.        
  1278.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setUTCMilliseconds)]
  1279.         public static double setUTCMilliseconds(object thisob, double dmsec)
  1280.         {
  1281.             if (!(thisob is DateObject))
  1282.                 throw new JScriptException(JSError.DateExpected);
  1283.             double t = ((DateObject)thisob).value;
  1284.             t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), dmsec)));
  1285.             ((DateObject)thisob).value = t;
  1286.             return t;
  1287.         }
  1288.        
  1289.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setUTCMonth)]
  1290.         public static double setUTCMonth(object thisob, double dmonth, object date)
  1291.         {
  1292.             if (!(thisob is DateObject))
  1293.                 throw new JScriptException(JSError.DateExpected);
  1294.             double t = ((DateObject)thisob).value;
  1295.             double ddate = NotSpecified(date) ? DateFromTime(t) : Convert.ToNumber(date);
  1296.             double day = MakeDay(YearFromTime(t), dmonth, ddate);
  1297.             t = TimeClip(MakeDate(day, TimeWithinDay(t)));
  1298.             ((DateObject)thisob).value = t;
  1299.             return t;
  1300.         }
  1301.        
  1302.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setUTCSeconds)]
  1303.         public static double setUTCSeconds(object thisob, double dsec, object msec)
  1304.         {
  1305.             if (!(thisob is DateObject))
  1306.                 throw new JScriptException(JSError.DateExpected);
  1307.             double t = ((DateObject)thisob).value;
  1308.             double dmsec = NotSpecified(msec) ? msFromTime(t) : Convert.ToNumber(msec);
  1309.             t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), dsec, dmsec)));
  1310.             ((DateObject)thisob).value = t;
  1311.             return t;
  1312.         }
  1313.        
  1314.         [NotRecommended("setYear")]
  1315.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_setYear)]
  1316.         public static double setYear(object thisob, double dyear)
  1317.         {
  1318.             if (!(thisob is DateObject))
  1319.                 throw new JScriptException(JSError.DateExpected);
  1320.             double t = LocalTime(((DateObject)thisob).value);
  1321.             if (Double.IsNaN(dyear)) {
  1322.                 ((DateObject)thisob).value = dyear;
  1323.                 return dyear;
  1324.             }
  1325.             dyear = Convert.ToInteger(dyear);
  1326.             if (0 <= dyear && dyear <= 99)
  1327.                 dyear += 1900;
  1328.             double day = MakeDay(dyear, MonthFromTime(t), DateFromTime(t));
  1329.             t = TimeClip(UTC(MakeDate(day, TimeWithinDay(t))));
  1330.             ((DateObject)thisob).value = t;
  1331.             return t;
  1332.         }
  1333.        
  1334.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_toDateString)]
  1335.         public static string toDateString(object thisob)
  1336.         {
  1337.             if (!(thisob is DateObject))
  1338.                 throw new JScriptException(JSError.DateExpected);
  1339.             double t = ((DateObject)thisob).value;
  1340.             return DateToDateString(t);
  1341.         }
  1342.        
  1343.         [NotRecommended("toGMTString")]
  1344.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_toGMTString)]
  1345.         public static string toGMTString(object thisob)
  1346.         {
  1347.             if (!(thisob is DateObject))
  1348.                 throw new JScriptException(JSError.DateExpected);
  1349.             double t = ((DateObject)thisob).value;
  1350.             return UTCDateToString(t);
  1351.         }
  1352.        
  1353.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_toLocaleDateString)]
  1354.         public static string toLocaleDateString(object thisob)
  1355.         {
  1356.             object dt = getVarDate(thisob);
  1357.             return dt == null ? DateToDateString(((DateObject)thisob).value) : ((DateTime)dt).ToLongDateString();
  1358.         }
  1359.        
  1360.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_toLocaleString)]
  1361.         public static string toLocaleString(object thisob)
  1362.         {
  1363.             object dt = getVarDate(thisob);
  1364.             return dt == null ? DateToString(((DateObject)thisob).value) : ((DateTime)dt).ToLongDateString() + " " + ((DateTime)dt).ToLongTimeString();
  1365.         }
  1366.        
  1367.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_toLocaleTimeString)]
  1368.         public static string toLocaleTimeString(object thisob)
  1369.         {
  1370.             object dt = getVarDate(thisob);
  1371.             return dt == null ? DateToTimeString(((DateObject)thisob).value) : ((DateTime)dt).ToLongTimeString();
  1372.         }
  1373.        
  1374.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_toString)]
  1375.         public static string toString(object thisob)
  1376.         {
  1377.             if (!(thisob is DateObject))
  1378.                 throw new JScriptException(JSError.DateExpected);
  1379.             double t = ((DateObject)thisob).value;
  1380.             return DateToString(t);
  1381.         }
  1382.        
  1383.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_toTimeString)]
  1384.         public static string toTimeString(object thisob)
  1385.         {
  1386.             if (!(thisob is DateObject))
  1387.                 throw new JScriptException(JSError.DateExpected);
  1388.             double t = ((DateObject)thisob).value;
  1389.             return DateToTimeString(t);
  1390.         }
  1391.        
  1392.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_toUTCString)]
  1393.         public static string toUTCString(object thisob)
  1394.         {
  1395.             if (!(thisob is DateObject))
  1396.                 throw new JScriptException(JSError.DateExpected);
  1397.             double t = ((DateObject)thisob).value;
  1398.             return UTCDateToString(t);
  1399.         }
  1400.        
  1401.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Date_valueOf)]
  1402.         public static double valueOf(object thisob)
  1403.         {
  1404.             if (!(thisob is DateObject))
  1405.                 throw new JScriptException(JSError.DateExpected);
  1406.             return ((DateObject)thisob).value;
  1407.         }
  1408.        
  1409.     }
  1410. }

Developer Fusion