File: DateTimeMgmt.js
Size: 48442
Date: Sat, 08 Dec 2007 15:37:07 +0100
Type: js
 
 
//**************************************************************************
 
//      Copyright  Sybase, Inc. 1998-1999
 
//                       All Rights reserved.
 
//
 
//  Sybase, Inc. ("Sybase") claims copyright in this
 
//  program and documentation as an unpublished work, versions of
 
//  which were first licensed on the date indicated in the foregoing
 
//  notice.  Claim of copyright does not imply waiver of Sybase's
 
//  other rights.
 
//
 
//   This code is generated by the PowerBuilder HTML DataWindow generator.
 
//   It is provided subject to the terms of the Sybase License Agreement
 
//   for use as is, without alteration or modification.  
 
//   Sybase shall have no obligation to provide support or error correction 
 
//   services with respect to any altered or modified versions of this code.  
 
//
 
//       ***********************************************************
 
//       **     DO NOT MODIFY OR ALTER THIS CODE IN ANY WAY       **
 
//       ***********************************************************
 
//
 
//       ***************************************************************
 
//       ** IMPLEMENTATION DETAILS SUBJECT TO CHANGE WITHOUT NOTICE.  **
 
//       **            DO NOT RELY ON IMPLEMENTATION!!!!              **
 
//       ***************************************************************
 
//
 
// Use the public interface only.
 
//**************************************************************************
 
 
 
//
 
// Date management code
 
//
 
 
 
// Added to determine if dates are being processed in client side JavaScript.
 
bDateTimeProcessingEnabled = true;
 
 
 
var DW_dayTable = new Array();
 
DW_dayTable[0] = new Array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
 
DW_dayTable[1] = new Array(0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
 
 
 
var DW_cumDayTable = new Array();
 
DW_cumDayTable[0] = new Array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365);
 
DW_cumDayTable[1] = new Array(0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366);
 
 
 
function DW_daysInCentury(year)
 
{
 
    return ((((year) / 100) % 4 ? 24 : 25) + 36500);
 
}
 
 
 
function DW_isLeap(year)
 
{
 
    return ((year%4 == 0 && year%100 != 0) || year%400 == 0);
 
}
 
 
 
function DW_dayOfYear(year, month, day)
 
{
 
    var i, aleap;
 
 
 
    aleap = DW_isLeap(year) ? 1 : 0;
 
    for (i = 1; i < month; i++)
 
        day += DW_dayTable[aleap][i];
 
    return day;                   // Offset from 0
 
}
 
 
 
function DW_dayOfCentury(year, month, day)
 
{
 
    var days, leaps;
 
    var years_in_century;
 
 
 
    /* Get number of years in the century. */
 
    years_in_century = Math.floor(year % 100);
 
 
 
    /* Get the number of days in year */
 
    days = DW_dayOfYear(year, month, day);;
 
 
 
    /* Add number of days in previous years */
 
    if (years_in_century != 0)
 
        {
 
        leaps = Math.floor((years_in_century - 1) / 4);  /* num of inclusive leap years */
 
        leaps += (Math.floor(year / 100) % 4 ? 0 : 1); /* + 1 every 4 centuries */
 
        days += leaps * 366;
 
        days += (years_in_century - leaps) * 365;
 
        }
 
    return days;
 
}
 
 
 
function DW_daysDiff(year1, mon1, day1, year2, mon2, day2)
 
{
 
    var days = 0;
 
    var no_centuries;
 
    var temp;
 
    var sign = 1;
 
    var i;
 
 
 
    // Swap dates if date1 < date2
 
    if ( year1 < year2 || 
 
            (year1 == year2 && (mon1 < mon2 || 
 
                                    (mon1 == mon2 && day1 < day2) ) ) )
 
        {
 
        temp = year1; year1 = year2; year2 = temp;
 
        temp = mon1;  mon1 = mon2;   mon2 = temp;
 
        temp = day1;  day1 = day2;   day2 = temp;
 
        sign = -1;
 
        }
 
 
 
    // Calculate difference in dates.
 
    no_centuries = Math.floor(year1 / 100) - Math.floor(year2 / 100);
 
    for (i = 0; i < no_centuries; i++)
 
        days += DW_daysInCentury (year2 + i * 100);
 
    days += DW_dayOfCentury (year1,mon1,day1) - DW_dayOfCentury (year2,mon2,day2); 
 
 
 
    // Set sign of days
 
    days *= sign;
 
 
 
    return (days);
 
}
 
 
 
// Notes   :  Jan 1, 1899 was a Sunday.
 
function DW_dayOfWeek(year, month, day)
 
{
 
    var days_from_1899;
 
    var weekday;
 
 
 
    // Get number of days since 01/01/1899.
 
    days_from_1899 = DW_daysDiff (year, month, day, 1899, 1, 1);
 
 
 
    // Mod by 7 to get day of week.
 
    weekday = days_from_1899 % 7;
 
    // CR 184356 - make sure we deal properly with dates less than 01/01/1899
 
    if (weekday < 0)
 
        weekday += 7;
 
 
 
    return (weekday);
 
}
 
 
 
function DW_daysInYear(year)
 
{
 
    return DW_isLeap(year) ? 366 : 365;
 
}
 
 
 
function DW_DateToString()
 
{
 
    return (this.year + 1900) + "/" + (this.month + 1)  + "/" + this.day;
 
}
 
 
 
function DW_DatetimeToString()
 
{
 
    var outStr =  (this.year + 1900) + "/" + (this.month + 1)  + "/"  + this.day  + " " + 
 
        this.hour + ":" + this.min + ":" + this.sec + ":";
 
    var tempStr = ""+ this.msec;
 
    var i = tempStr.length;
 
   while(i<6)
 
   {
 
    outStr += "0";
 
    i++;
 
   }
 
 
 
   return outStr + this.msec;
 
}
 
 
 
function DW_TimeToString(theTime)
 
{
 
    var outStr = this.hour + ":" + this.min + ":" + this.sec + ":";
 
 
 
    inStr = inStr + this.msec;
 
    var i = inStr.length();    
 
    while(i<6) 
 
    {
 
     outStr = outStr +"0";
 
     i++;
 
    } 
 
 
 
    outStr = outStr+inStr;
 
    return outStr;  
 
}
 
 
 
 
 
function DW_DateClass(year, month, day)
 
{
 
    if (arguments.length == 0)
 
        {
 
        year = 0;
 
        month = 0;
 
        day = 0;
 
        }
 
 
 
    this.year = year;
 
    this.month = month;
 
    this.day = day;
 
    this.hour = 0;
 
    this.min = 0;
 
    this.sec = 0;
 
    this.msec = 0;
 
 
 
    this.toString = DW_DateToString;
 
}
 
 
 
function DW_TimeClass(hour, min, sec, msec)
 
{
 
    if (arguments.length == 0)
 
        {
 
        hour = 0;
 
        min = 0;
 
        sec = 0;
 
        msec = 0;
 
        }
 
 
 
    this.hour = hour;
 
    this.min = min;
 
    this.sec = sec;
 
    this.msec = msec;
 
    this.year = 0;
 
    this.month = 0;
 
    this.day = 0;
 
 
 
    this.toString = DW_TimeToString;
 
}
 
 
 
function DW_DatetimeClass(year,month,day,hour,min,sec,msec)
 
{
 
    if (arguments.length == 0)
 
        {
 
        year = 0;
 
        month = 0;
 
        day = 0;        
 
        hour = 0;
 
        min = 0;
 
        sec = 0;
 
        msec = 0;
 
        }
 
 
 
     this.year = year;
 
     this.month = month;
 
     this.day = day;
 
     this.hour = hour;
 
     this.min = min;
 
     this.sec = sec;
 
     this.msec = msec;
 
 
 
     this.toString = DW_DatetimeToString;
 
}
 
 
 
function DW_DatetimeClass2(date, time)
 
{
 
     this.year = date.year;
 
     this.month = date.month;
 
     this.day = date.day;
 
     this.hour = time.hour;
 
     this.min = time.min;
 
     this.sec = time.sec;
 
     this.msec = time.msec;
 
 
 
     this.toString = DW_DatetimeToString;
 
}
 
 
 
// These constants are used by the date parsing code
 
var DW_PARSEDT_DATE = 0;
 
var DW_PARSEDT_TIME = 1;
 
var DW_PARSEDT_DATETIME = 2;
 
 
 
// these three are dependent on localization settings
 
//var DW_PARSEDT_monseq = 0;
 
//var DW_PARSEDT_dayseq = 1;
 
//var DW_PARSEDT_yearseq = 2;
 
var DW_PARSEDT_hourseq = 3;
 
var DW_PARSEDT_minseq = 4;
 
var DW_PARSEDT_secseq = 5;
 
var DW_PARSEDT_msecseq = 6;
 
 
 
function DW_monthSearch(inMonthName)
 
{
 
    var index;
 
    var inMonthLC = inMonthName.toLowerCase();
 
 
 
    // check short month names
 
    for (index=0; index < 12; index++)
 
        {
 
        if (DW_shortMonthNames[index].toLowerCase() == inMonthLC)
 
            return index + 1;
 
        }
 
 
 
    // check long month names
 
    for (index=0; index < 12; index++)
 
        {
 
        if (DW_longMonthNames[index].toLowerCase() == inMonthLC)
 
            return index + 1;
 
        }
 
 
 
   // if we get here, we couldn't find the name
 
   return -1;
 
}
 
 
 
// The function validates data against the following masks only.
 
// yy, yyyy, m, mm, mmm, mmmm, d, dd, h, hh, m, mm, s, ss, f to ffffff, a/p, A/P, am/pm, AM/PM
 
// Validates standard formats, i.e. [SHORTDATE], [LONGDATE], [TIME], [GENERAL]
 
// Accepts only the following 6 delimiters as legal separator
 
// '-', '/', ',', '.', ' ', ':'
 
// The function does not do any validation against illegal masks
 
 
 
function DW_parseDatetimeStringAgainstMask(inString, outDatetime, parseType, Mask)
 
{
 
    // Get encoded format against mask
 
    var format = new DW_DateEncodingClass(Mask);
 
 
 
    // if invald mask, return false
 
    if (! format.bValid) return false;
 
 
 
    // Create a new date class
 
    var dt = new DW_DateClass(0,0,1);
 
 
 
    var STATESECTION = 0;
 
    var STATENUMBER = 1;
 
    var STATEMONSTRING = 2;
 
    var STATESEPARATOR = 3;
 
 
 
    var currChar;
 
    var nextChar; 
 
    var charIndex = 0;
 
    var state;
 
 
 
    var key;            // To hold number and strings
 
    var nVal;           // To store integer value
 
 
 
    var index = 0;
 
    var encodedFormat = format.encodedFormat;
 
    var action;
 
 
 
    while (charIndex < inString.length && index < encodedFormat.length)
 
    {
 
        // Now extract one token from encode string
 
 
 
        action = 0;
 
 
 
        if( index < encodedFormat.length)
 
        {
 
            action = encodedFormat[index];
 
            index++;
 
        }
 
 
 
        // Initialize
 
        state = STATESECTION;
 
 
 
        key = "";
 
        nVal = 0;
 
 
 
        // Extract one token from inString
 
        do{
 
 
 
            currChar = inString.charAt (charIndex);
 
            if (state == STATESECTION)
 
            {
 
                if (action == DWFMT_apCaps || action == DWFMT_apNCaps || action == DWFMT_ampmCaps || action == DWFMT_ampmNCaps) 
 
                {
 
                    if (currChar == 'a' || currChar == 'A')
 
                    {
 
                        if((inString.charAt (charIndex+1) == 'm') || (inString.charAt (charIndex+1) == 'M'))
 
                        {
 
                            key = currChar + inString.charAt (charIndex+1);
 
                            charIndex += 2;
 
                        }
 
                        else
 
                        {
 
                            key = currChar;
 
                            charIndex ++;
 
                        }
 
 
 
                        state = STATESECTION;
 
 
 
                    }
 
                    else if ((currChar == 'p') || (currChar == 'P'))
 
                    {
 
                        if(inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M')
 
                        {
 
                            key = currChar + inString.charAt (charIndex+1);
 
                            charIndex += 2;
 
                        }
 
                        else
 
                        {
 
                            key = currChar;
 
                            charIndex ++;
 
                        }
 
 
 
                        state = STATESECTION;
 
 
 
                    }
 
                    else
 
                        return false;
 
                }
 
 
 
                else if (currChar == '-' ||     // New section
 
                currChar == '/' ||
 
                    currChar == ',' ||
 
                    currChar == '.' ||
 
                    currChar == ' ' ||
 
                    currChar == ':')
 
                    state = STATESEPARATOR;
 
 
 
                else if (DW_parseIsDigit(currChar))
 
                    state = STATENUMBER;
 
 
 
                else if (DW_parseIsAlpha(currChar))
 
                    state = STATEMONSTRING;
 
 
 
                else
 
                    return false;
 
 
 
            }
 
 
 
            else if(state == STATENUMBER)
 
            {
 
                key += currChar;
 
                charIndex++;
 
 
 
                // accumulate until next char is not a digit
 
                if (!DW_parseIsDigit(inString.charAt (charIndex)))
 
                {
 
                    state = STATESECTION;       // Change state for next char
 
 
 
                    nVal = key - 0;
 
                }
 
            }
 
 
 
            else if (state == STATEMONSTRING)
 
            {
 
                key += currChar;
 
                charIndex++;
 
                if (!DW_parseIsAlpha(inString.charAt (charIndex)))
 
                {
 
                    nVal = DW_monthSearch(key);
 
                    if (nVal == -1)
 
                        return false;
 
                    state = STATESECTION;
 
                }
 
            }
 
 
 
            else if (state == STATESEPARATOR) 
 
            {
 
                key += currChar;  
 
                charIndex++;
 
                nextChar = inString.charAt (charIndex);
 
                if (!(nextChar == '-' ||     // New section
 
                    nextChar == '/' ||
 
                    nextChar == ',' ||
 
                    nextChar == '.' ||
 
                    nextChar == ' ' ||
 
                    nextChar == ':'))
 
                    state = STATESECTION;
 
            }
 
 
 
            else
 
            {
 
                return false;        // Unspecified error
 
            }
 
 
 
        }while(charIndex < inString.length && state != STATESECTION)
 
 
 
 
 
        // If both the tokens are matching - update date class and continue.
 
 
 
        if (typeof action == "string")
 
        {
 
            if (key != action)
 
                return false;
 
        }
 
        else if(action == DWFMT_2digityear)
 
        {
 
            if(nVal < 0 || key.length != 2)
 
                return false;
 
            else if (nVal >= 50)
 
                nVal += 1900;
 
            else
 
                nVal += 2000;
 
 
 
            dt.year = nVal;
 
        }
 
        else if (action == DWFMT_4digityear)
 
        {
 
            if(nVal < 0 || (key.length != 4 && key.length != 2))
 
                return false;
 
            if (key.length == 2)
 
                if (nVal >= 50) 
 
                    nVal += 1900
 
                else
 
                    nVal += 2000;
 
 
 
            dt.year = nVal;
 
        }
 
        else if (action == DWFMT_monthz || action == DWFMT_monthnz)
 
        {
 
            if(nVal < 1 || nVal > 12 || key.length > 2)
 
                return false;
 
 
 
            dt.month = nVal;
 
        }
 
        else if (action == DWFMT_monthshortname)
 
        {
 
            if(nVal < 0 || key.length != 3)
 
                return false;
 
 
 
            dt.month = nVal;
 
        }
 
        else if (action == DWFMT_monthlongname)
 
        {
 
            if(nVal < 0)
 
                return false;
 
 
 
            if(key.length == 3 && nVal != 5) // May is only exception
 
                return false;
 
 
 
            dt.month = nVal;
 
        }
 
        else if (action == DWFMT_dayz || action == DWFMT_daynz)
 
        {
 
            if(nVal < 1 || nVal > 31 || key.length > 2)
 
                return false;
 
 
 
            dt.day = nVal;
 
        }
 
        //The following masks are invalid input mask
 
        else if (action == DWFMT_dayshortname || action == DWFMT_daylongname)
 
        {
 
            return false;
 
        }
 
        else if (action == DWFMT_hourz || action == DWFMT_hournz)
 
        {
 
            if(nVal < 0 || nVal > 23 || key.length > 2)
 
                return false;
 
 
 
            dt.hour = nVal;
 
        }
 
        else if (action == DWFMT_minz || action == DWFMT_minnz)
 
        {
 
            if(nVal < 0 || nVal > 59 || key.length > 2)
 
                return false;
 
 
 
            dt.min = nVal;
 
        }
 
        else if (action == DWFMT_secz || action == DWFMT_secnz)
 
        {
 
            if(nVal < 0 || nVal > 59 || key.length > 2)
 
                return false;
 
 
 
            dt.sec = nVal;
 
        }
 
        else if (action == DWFMT_msec)
 
        {
 
            if(nVal < 0 || nVal > 999999)
 
                return false;
 
 
 
            // Retreive next action
 
            action = 0;
 
 
 
            if( index < encodedFormat.length)
 
            {
 
                action = encodedFormat[index];
 
                index++;
 
            }
 
            else return false;
 
 
 
            if((action > 6) || (key.length != action))
 
                return false;
 
 
 
            var tempStr = key + "000000";
 
            dt.msec = tempStr.substring(0, 6) - 0;
 
        }
 
        else if (action == DWFMT_apCaps)
 
        {
 
            if ((key != "A") && (key != "P"))
 
                return false;
 
            if (dt.hour > 12)
 
                return false;
 
 
 
            if (key == "A")
 
            {
 
                if (dt.hour == 12)
 
                    return false;
 
            }
 
            else 
 
            {
 
                if (dt.hour == 0)
 
                    return false;
 
                else if(dt.hour < 12)
 
                    dt.hour += 12;
 
            }
 
        }
 
        else if (action == DWFMT_apNCaps)
 
        {
 
            if ((key != "a") && (key != "p"))
 
                return false;
 
            if (dt.hour > 12)
 
                return false;
 
            if (key == "a")
 
            {
 
                if (dt.hour == 12)
 
                    return false;
 
            }
 
            else 
 
            {
 
                if (dt.hour == 0)
 
                    return false;
 
                else if(dt.hour < 12)
 
                    dt.hour += 12;
 
            }
 
        }
 
        else if (action == DWFMT_ampmCaps)
 
        {
 
            if ((key != "AM") && (key != "PM"))
 
                return false;
 
            if (dt.hour > 12)
 
                return false;
 
            if (key == "AM")
 
            {
 
                if (dt.hour == 12)
 
                    return false;
 
            }
 
            else 
 
            {
 
                if (dt.hour == 0)
 
                    return false;
 
                else if(dt.hour < 12)
 
                    dt.hour += 12;
 
            }
 
        }
 
        else if (action == DWFMT_ampmNCaps)
 
        {
 
            if ((key != "am") && (key != "pm"))
 
                return false;
 
            if (dt.hour > 12)
 
                return false;
 
            if (key == "am")
 
            {
 
                if (dt.hour == 12)
 
                    return false;
 
            }
 
            else 
 
            {
 
                if (dt.hour == 0)
 
                    return false;
 
                else if(dt.hour < 12)
 
                    dt.hour += 12;
 
            }
 
        }
 
        else return false
 
    }
 
 
 
    // whether we have reached at the end of both the string
 
    if (charIndex < inString.length)
 
        return false;
 
 
 
 
 
    // Do additional validation of the day against month and year
 
    if (parseType != DW_PARSEDT_TIME)
 
        {
 
            var leapYear = DW_isLeap(dt.year) ? 1 : 0;
 
            if (dt.day > DW_dayTable[leapYear][dt.month])
 
                return false;
 
        }
 
 
 
    if (outDatetime != null)
 
    {
 
        if (parseType == DW_PARSEDT_DATE || parseType == DW_PARSEDT_DATETIME)
 
        {
 
            outDatetime.day = dt.day;
 
            outDatetime.month = dt.month - 1;
 
            outDatetime.year = dt.year - 1900;
 
        }
 
        if (parseType == DW_PARSEDT_TIME || parseType == DW_PARSEDT_DATETIME)
 
        {
 
            outDatetime.sec = dt.sec;
 
            outDatetime.min = dt.min;
 
            outDatetime.hour = dt.hour;
 
            outDatetime.msec = dt.msec;
 
        }
 
    }
 
 
 
    return true;
 
}
 
 
 
function DW_parseDatetimeString(inString, outDatetime, parseType)
 
{
 
    if (gMask != "")
 
        return DW_parseDatetimeStringAgainstMask(inString, outDatetime, parseType, gMask);
 
 
 
    var STATESECTION = 0;
 
    var STATENUMBER = 1;
 
    var STATEMONSTRING = 2;
 
 
 
    var dt = new Array();            // date time array
 
    var key;           // To hold number and strings
 
    var currChar;
 
    var charIndex;
 
    var strLen = inString.length;
 
    var state;
 
    var seq;
 
    var bIllegal= false;
 
    var section;
 
    var i;
 
 
 
    // Initialize date/time array
 
    for (var i=0; i<= DW_PARSEDT_msecseq; i++)
 
        dt[i] = -1;
 
 
 
    if (parseType == DW_PARSEDT_TIME)
 
        {
 
        section = DW_PARSEDT_hourseq;      // start at time section
 
        lastseq = DW_PARSEDT_msecseq;
 
        }
 
    else if (parseType == DW_PARSEDT_DATETIME)
 
        {
 
        section = 0;
 
        lastseq = DW_PARSEDT_msecseq;
 
        }
 
    else
 
        {
 
        section = 0;            // start at first section
 
        lastseq = 2;            // end after date segments
 
        }
 
    state = STATESECTION;
 
 
 
    for (charIndex = 0; charIndex < strLen && ! bIllegal;)
 
        {
 
        currChar = inString.charAt (charIndex);
 
        if (state == STATESECTION)
 
            {
 
            if (DW_parseIsSpace(currChar))
 
                charIndex++;          // skip white space
 
            else if ((currChar == 'a' || currChar == 'A') &&
 
                     (inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M'))
 
                {
 
                if (dt[DW_PARSEDT_hourseq] != -1)
 
                    {
 
                    if (dt[DW_PARSEDT_hourseq] == 0 &&
 
                        dt[DW_PARSEDT_minseq] <= 0)
 
                        bIllegal = true;
 
                    else
 
                        {
 
                        if (dt[DW_PARSEDT_hourseq] == 12)  // 12 a.m. = 00
 
                            dt[DW_PARSEDT_hourseq] = 0;
 
                        charIndex += 2;
 
                        section = lastseq;
 
                        }
 
                    }
 
                else
 
                    bIllegal = true;
 
                }
 
            else if ((currChar == 'p' || currChar == 'P') &&
 
                     (inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M'))
 
                {
 
                if (dt[DW_PARSEDT_hourseq] != -1)
 
                    {
 
                    charIndex += 2;
 
                    if (dt[DW_PARSEDT_hourseq] != 12)
 
                        {
 
                        dt[DW_PARSEDT_hourseq] += 12;
 
                        if (dt[DW_PARSEDT_hourseq] > 23)
 
                            bIllegal = true;
 
                        else
 
                            section = lastseq;
 
                        }
 
                    }
 
                else
 
                    bIllegal = true;
 
                }
 
            else if (section > lastseq) // too many sections
 
                bIllegal = true;
 
            else if (currChar == '-' ||     // New section
 
                     currChar == '/' ||
 
                     currChar == ',' ||
 
                     currChar == '.' ||
 
                     currChar == ':')
 
                {
 
                if (section == 0 ||                 // Never done a section?
 
                    dt[section-1] == -1)        // Missed a section?
 
                    bIllegal = true;
 
                else
 
                    charIndex++;
 
                }
 
            else if (DW_parseIsDigit(currChar))
 
                {
 
                key = "";
 
                state = STATENUMBER;
 
                }
 
            else if (DW_parseIsAlpha(currChar))
 
                {
 
                if (section != DW_PARSEDT_monseq)
 
                    bIllegal = true;
 
                else
 
                    state = STATEMONSTRING;
 
                key = "";
 
                }
 
            else
 
                bIllegal = true;
 
            }
 
        else if(state == STATENUMBER)
 
            {
 
            key += currChar;
 
            charIndex++;
 
            // accumulate until next char is not a digit
 
            if (!DW_parseIsDigit(inString.charAt (charIndex)))
 
                {
 
                state = STATESECTION;       // Change state for next char
 
                var n = key - 0;
 
                var keyLength = key.length;
 
 
 
                if (section == 0 &&  keyLength == 4)
 
                    {           // year obviously first; force new format
 
                    DW_PARSEDT_yearseq = 0;
 
                    DW_PARSEDT_monseq = 1;
 
                    DW_PARSEDT_dayseq = 2;
 
                    }
 
 
 
                if (section == DW_PARSEDT_monseq)
 
                    {
 
                    if (n < 1 || n > 12)
 
                    bIllegal = true;
 
                    }
 
                else if (section == DW_PARSEDT_yearseq)
 
                    {       // valid size of year
 
 
 
                    if (n < 0 || !(keyLength == 2 || keyLength == 4))
 
                        bIllegal = true;
 
                    // e.g. if 01/01/50 then year is 1950
 
                    else if (n >= 50 && keyLength == 2)
 
                        n += 1900;
 
                    // e.g. if 01/01/49 then year is 2049
 
                    else if (n < 50 && keyLength == 2)
 
                        n += 2000;
 
                    }
 
                else if (section == DW_PARSEDT_dayseq)
 
                    {
 
                    if (n < 1 || n > 31)        // Do more validation later
 
                        bIllegal = true;
 
                    }
 
                else if (section == DW_PARSEDT_hourseq)
 
                    {
 
                    if (n < 0 || n > 23)
 
                        bIllegal = true;
 
                    }
 
                else if (section == DW_PARSEDT_minseq)
 
                    {
 
                    if (n < 0 || n > 59)
 
                        bIllegal = true;
 
                    }
 
                else if (section == DW_PARSEDT_secseq)    // seconds
 
                    {
 
                    if (n < 0 || n > 59)
 
                        bIllegal = true;
 
                    }
 
                else        // Micro seconds
 
                    {
 
                    if (n < 0 || n > 999999)
 
                        bIllegal = true;
 
                    else if (keyLength == 1)
 
                        n *= 100000;
 
                    else if (keyLength == 2)
 
                        n *= 10000;
 
                    else if (keyLength == 3)
 
                        n *= 1000;
 
                    else if (keyLength == 4)
 
                        n *= 100;
 
                    else if (keyLength == 5)
 
                        n *= 10;
 
                    }
 
                if (!bIllegal)
 
                    {
 
                    dt[section] = n;
 
                    section++;
 
                    }
 
                }
 
            }
 
        else if (state == STATEMONSTRING)
 
            {
 
            key += currChar;
 
            charIndex++;
 
            if (!DW_parseIsAlpha(inString.charAt (charIndex)))
 
                {
 
                var m;
 
 
 
                m = DW_monthSearch(key);
 
                if (m == -1)
 
                    bIllegal = true;
 
                else
 
                    dt[section] = m;
 
                state = STATESECTION;
 
                section++;
 
                if (inString.charAt (charIndex) == '.' &&  // Check for possible
 
                    key.length == 3 &&  // abbreviation of month
 
                    m != 5)         // "May" has no abbreviation
 
                    charIndex++;
 
                }
 
            }
 
        else
 
            {
 
            bIllegal = true;        // Unspecified error
 
            }
 
        }
 
 
 
    if (bIllegal)
 
        return false;
 
 
 
 
 
    if (parseType != DW_PARSEDT_TIME)
 
        {   // We require month and day and year
 
        if (dt[DW_PARSEDT_monseq] == -1 ||
 
            dt[DW_PARSEDT_yearseq] == -1 ||
 
            dt[DW_PARSEDT_dayseq] == -1)
 
            return false;
 
        }
 
    else if (dt[DW_PARSEDT_hourseq] == -1 )     // We require at least the hour
 
        return false;
 
 
 
    // Zero out uninitialized fields
 
    for (i=0; i <= DW_PARSEDT_msecseq; i++)
 
        if (dt[i] == -1)
 
            dt[i] = 0;
 
 
 
    // Do additional validation of the day and year
 
    if (parseType != DW_PARSEDT_TIME)
 
        {
 
        var leapYear = DW_isLeap(dt[DW_PARSEDT_yearseq]) ? 1 : 0;
 
        if (dt[DW_PARSEDT_dayseq] > DW_dayTable[leapYear][dt[DW_PARSEDT_monseq]])
 
            return false;
 
        if (dt[DW_PARSEDT_yearseq] > 9999)
 
            return false;
 
        }
 
 
 
    if (outDatetime != null)
 
        {
 
        if (parseType == DW_PARSEDT_DATE || parseType == DW_PARSEDT_DATETIME)
 
            {
 
            outDatetime.day = dt[DW_PARSEDT_dayseq];
 
            outDatetime.month = dt[DW_PARSEDT_monseq]-1;
 
            outDatetime.year = dt[DW_PARSEDT_yearseq]-1900;
 
            }
 
        if (parseType == DW_PARSEDT_TIME || parseType == DW_PARSEDT_DATETIME)
 
            {
 
            outDatetime.sec = dt[DW_PARSEDT_secseq];
 
            outDatetime.min = dt[DW_PARSEDT_minseq];
 
            outDatetime.hour = dt[DW_PARSEDT_hourseq];
 
            outDatetime.msec = dt[DW_PARSEDT_msecseq];
 
            }
 
        }
 
 
 
    return true;
 
}
 
 
 
function DW_DateParse(inString)
 
{
 
    var result = new DW_DateClass();
 
 
 
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_DATE))
 
        return result;
 
    else
 
        return null;
 
}
 
 
 
function DW_DatetimeParse(inString)
 
{
 
    var result = new DW_DatetimeClass();
 
 
 
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_DATETIME))
 
        return result;
 
    else
 
        return null;
 
}
 
 
 
function DW_TimeParse(inString)
 
{
 
    var result = new DW_TimeClass();
 
 
 
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_TIME))
 
        return result;
 
    else
 
        return null;
 
}
 
 
 
function DW_IsDatetime(inString, bNilIsNull)
 
{
 
    if (arguments.length < 2)
 
        bNilIsNull = false;
 
 
 
    if (inString == "")
 
        return bNilIsNull;
 
    else
 
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_DATETIME);
 
}
 
 
 
function DW_IsDate(inString, bNilIsNull)
 
{
 
    if (arguments.length < 2)
 
        bNilIsNull = false;
 
 
 
    if (inString == "")
 
        return bNilIsNull;
 
    else
 
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_DATE);
 
}
 
 
 
function DW_IsTime(inString, bNilIsNull)
 
{
 
    if (arguments.length < 2)
 
        bNilIsNull = false;
 
 
 
    if (inString == "")
 
        return bNilIsNull;
 
    else
 
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_TIME);
 
}
 
 
 
function DW_Now()
 
{
 
    var now = new Date();
 
    return new DW_TimeClass(now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());
 
}
 
 
 
function DW_Today()
 
{
 
    var now = new Date();
 
    var year = now.getYear();
 
    year -= 1900;
 
    return new DW_DateClass(year, now.getMonth(), now.getDate());
 
}
 
 
 
//
 
// Date formatting code
 
//
 
 
 
// these constants are for use in date formats
 
var DWFMT_daynz = 0;
 
var DWFMT_dayz = 1;
 
var DWFMT_dayshortname = 2;
 
var DWFMT_daylongname = 3;
 
var DWFMT_monthnz = 4;
 
var DWFMT_monthz = 5;
 
var DWFMT_monthshortname = 6;
 
var DWFMT_monthlongname = 7;
 
var DWFMT_2digityear = 8;
 
var DWFMT_4digityear = 9;
 
var DWFMT_hournz = 10;
 
var DWFMT_hourz = 11;
 
var DWFMT_minnz = 12;
 
var DWFMT_minz = 13;
 
var DWFMT_secnz = 14;
 
var DWFMT_secz = 15;
 
var DWFMT_msec = 16;
 
var DWFMT_apCaps = 17;
 
var DWFMT_apNCaps = 18;
 
var DWFMT_ampmCaps = 19;
 
var DWFMT_ampmNCaps = 20;
 
var DWFMT_changeToCurrent = 21;
 
 
 
function DW_DateEncodingClass(inString)
 
{
 
    var index;
 
    var currChar;
 
    var encodedFormat = new Array();
 
    var accum = "";
 
    var numInSection;
 
    var offset = 0;
 
    var bValid = true;
 
    var bGotHour = false;
 
 
 
    this.b24hr = true;
 
    this.color = "";
 
 
 
    var strLen = inString.length;
 
    for (index=0; index < strLen && bValid; )
 
        {
 
        currChar = inString.charAt(index);
 
        // handle keywords
 
        if (currChar == "[")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            for (; inString.charAt(index) != "]"; index++)
 
                accum += inString.charAt(index);
 
            index++; // skip ]
 
            var inlineEncoding = null;
 
            var keyword = accum.toUpperCase();
 
            if (keyword == "CURRENT")
 
                encodedFormat[offset++] = DWFMT_changeToCurrent;
 
            else if (keyword == "GENERAL" || keyword == "SHORTDATE" || keyword == "DATE")
 
                inlineEncoding = new DW_DateEncodingClass(DW_shortDateFormat);
 
            else if (keyword == "LONGDATE")
 
                inlineEncoding = new DW_DateEncodingClass(DW_longDateFormat);
 
            else if (keyword == "TIME")
 
                inlineEncoding = new DW_DateEncodingClass(DW_timeFormat);
 
            else
 
                {
 
                if (!parseInt(accum)) 
 
                    this.color = accum.toLowerCase();
 
                else
 
                    this.color = eval(accum);
 
                this.keyword = accum;
 
                }
 
            // if we build another format, inline it into current one
 
            if (inlineEncoding != null && inlineEncoding.bValid)
 
                {
 
                var innerFormat = inlineEncoding.encodedFormat;
 
                for (var j=0; j<innerFormat.length; j++)
 
                    encodedFormat[offset++] = innerFormat[j];
 
                if (keyword == "TIME")
 
                    this.b24hr = inlineEncoding.b24hr;
 
                }
 
            accum = "";
 
            }
 
        else if (currChar == "d" || currChar == "D")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            // accumulate all the d's
 
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "D"; index++, numInSection++)
 
                ;
 
            if (numInSection == 1)
 
                encodedFormat[offset++] = DWFMT_daynz;
 
            else if (numInSection == 2)
 
                encodedFormat[offset++] = DWFMT_dayz;
 
            else if (numInSection == 3)
 
                encodedFormat[offset++] = DWFMT_dayshortname;
 
            else if (numInSection == 4)
 
                encodedFormat[offset++] = DWFMT_daylongname;
 
            else
 
                bValid = false;
 
            }
 
        else if (currChar == "m" || currChar == "M")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            // accumulate all the m's
 
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "M"; index++, numInSection++)
 
                ;
 
            if (numInSection == 1)
 
                if ( bGotHour )
 
                    {
 
                    encodedFormat[offset++] = DWFMT_minnz;
 
                    bGotHour = false;
 
                    }
 
                else
 
                    encodedFormat[offset++] = DWFMT_monthnz;
 
            else if (numInSection == 2)
 
                if ( bGotHour )
 
                    {
 
                    encodedFormat[offset++] = DWFMT_minz;
 
                    bGotHour = false;
 
                    }
 
                else
 
                    encodedFormat[offset++] = DWFMT_monthz;
 
            else if (numInSection == 3)
 
                encodedFormat[offset++] = DWFMT_monthshortname;
 
            else if (numInSection == 4)
 
                encodedFormat[offset++] = DWFMT_monthlongname;
 
            else
 
                bValid = false;
 
            }
 
        else if(currChar == "y" || currChar == "Y")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            // accumulate all the y's
 
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "Y"; index++, numInSection++)
 
                ;
 
            if (numInSection == 2)
 
                encodedFormat[offset++] = DWFMT_2digityear;
 
            else if (numInSection == 4)
 
                encodedFormat[offset++] = DWFMT_4digityear;
 
            else
 
                bValid = false;
 
            }
 
        else if(currChar == "h" || currChar == "H")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            bGotHour = true;
 
            // accumulate all the h's
 
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "H"; index++, numInSection++)
 
                ;
 
            if (numInSection == 1)
 
                encodedFormat[offset++] = DWFMT_hournz;
 
            else if (numInSection == 2)
 
                encodedFormat[offset++] = DWFMT_hourz;
 
            else
 
                bValid = false;
 
            }
 
        else if(currChar == "m" || currChar == "M")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            // accumulate all the m's
 
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "M"; index++, numInSection++)
 
                ;
 
            if (numInSection == 1)
 
                encodedFormat[offset++] = DWFMT_minnz;
 
            else if (numInSection == 2)
 
                encodedFormat[offset++] = DWFMT_minz;
 
            else
 
                bValid = false;
 
            }
 
        else if(currChar == "s" || currChar == "S")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            // accumulate all the s's
 
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "S"; index++, numInSection++)
 
                ;
 
            if (numInSection == 1)
 
                encodedFormat[offset++] = DWFMT_secnz;
 
            else if (numInSection == 2)
 
                encodedFormat[offset++] = DWFMT_secz;
 
            else
 
                bValid = false;
 
            }
 
        else if(currChar == "f" || currChar == "F")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            // accumulate all the f's
 
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "F"; index++, numInSection++)
 
                ;
 
            if (numInSection <= 6)
 
                {
 
                encodedFormat[offset++] = DWFMT_msec;
 
                encodedFormat[offset++] = numInSection;
 
                }
 
            else
 
                bValid = false;
 
            }
 
        else if(currChar == "a" ||
 
                    currChar == "A" ||
 
                    currChar == "p" ||
 
                    currChar == "P")
 
            {
 
            if (accum != "")
 
                encodedFormat[offset++] = accum;
 
            accum = "";
 
            index++;
 
            this.b24hr = false;
 
            nextChar = inString.charAt(index);
 
            if (nextChar.toUpperCase() == "M")
 
                {
 
                index = index + 4;
 
                if (currChar == "A" || currChar == "P")
 
                    encodedFormat[offset++] = DWFMT_ampmCaps;
 
                else
 
                    encodedFormat[offset++] = DWFMT_ampmNCaps;
 
                }
 
            else
 
                {
 
                index = index + 2;
 
                if (currChar == "A" || currChar == "P")
 
                    encodedFormat[offset++] = DWFMT_apCaps;
 
                else
 
                    encodedFormat[offset++] = DWFMT_apNCaps;
 
                }
 
            }
 
        else if(currChar == "\\")
 
            {
 
            index++;
 
            accum += inString.charAt(index++);
 
            }
 
        else if(currChar == "'")
 
            {
 
            index++;
 
            while (index < strLen)
 
                {
 
                currChar = inString.charAt(index);
 
                if (currChar == "'")
 
                    break;
 
                accum += currChar;
 
                index++;
 
                }
 
            // check if we fell off end before finding closing quotes
 
            if (index == strLen)
 
                bValid = false;
 
 
 
            index++; // skip trailing '
 
            }
 
        else
 
            {
 
            accum += currChar;
 
            index++;
 
            }
 
        }
 
 
 
    if (accum != "")
 
        encodedFormat[offset++] = accum;
 
 
 
    if (encodedFormat.length == 0 ) 
 
        bValid = false;
 
 
 
    this.bValid = bValid;
 
    this.encodedFormat = encodedFormat;
 
}
 
 
 
function DW_DateFormatClass(formatString)
 
{
 
    var semiOffset = formatString.indexOf(";");
 
 
 
    if (semiOffset != -1)
 
        {
 
        this.mainFormat = new DW_DateEncodingClass(formatString.substring(0, semiOffset));
 
        this.nullFormat = new DW_DateEncodingClass(formatString.substring(semiOffset+1, formatString.length));
 
 
 
        this.bValid = this.mainFormat.bValid && this.nullFormat.bValid;
 
        }
 
    else
 
        {
 
        this.mainFormat = new DW_DateEncodingClass(formatString);
 
        this.nullFormat = null;
 
        this.bValid = this.mainFormat.bValid;
 
        }
 
}
 
 
 
function DW_FormatDate(formatString, value, control)
 
{
 
    var dateFormat = new DW_DateFormatClass(formatString);
 
    var result = "";
 
    var givenDate = null;
 
    var format;
 
 
 
    if (value != null)
 
        {
 
        if (typeof(value) == "string")
 
            givenDate = DW_DateParse(value);
 
        else
 
            givenDate = value;
 
        }
 
 
 
    if (!dateFormat.bValid)
 
        {
 
        if ( value == null )
 
            result = "";
 
        else if ( givenDate.toString == DW_DatetimeToString )
 
            dateFormat = new DW_DateFormatClass( "[SHORTDATE] [TIME]" );
 
        else if ( givenDate.toString == DW_DateToString )
 
            dateFormat = new DW_DateFormatClass( "[SHORTDATE]" );
 
        else if ( givenDate.toString == DW_TimeToString )
 
            dateFormat = new DW_DateFormatClass( "[TIME]" );
 
        }
 
 
 
    if (dateFormat.bValid)
 
        {
 
        if (value == null && dateFormat.nullFormat != null)
 
            format = dateFormat.nullFormat;
 
        else
 
            format = dateFormat.mainFormat;
 
 
 
        var index;
 
        var encodedFormat = format.encodedFormat;
 
        var action;
 
        var ampm = (value == null || givenDate.hour < 12) ? 1 : 0;
 
        var hour, msec;
 
 
 
        for (index=0; index < encodedFormat.length ; index++)
 
            {
 
            action = encodedFormat[index];
 
            if (typeof action == "string")
 
                result += action;
 
            else if (action == DWFMT_changeToCurrent)
 
            {
 
                var dateCurrent = new DW_DatetimeClass2(DW_Today(), DW_Now());
 
                result = dateCurrent.toString();
 
            }
 
            else if (action == DWFMT_dayz || action == DWFMT_daynz)
 
                {
 
                if (action == DWFMT_dayz)
 
                    {
 
                    if (value == null)
 
                        result = "";
 
                    else if (givenDate.day < 10)
 
                        result += "0";
 
                    }
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += givenDate.day;
 
                }
 
            else if (action == DWFMT_dayshortname)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += DW_shortDayNames[DW_dayOfWeek (givenDate.year + 1900, givenDate.month + 1, givenDate.day)];
 
                }
 
            else if (action == DWFMT_daylongname)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += DW_longDayNames[DW_dayOfWeek (givenDate.year + 1900, givenDate.month + 1, givenDate.day)];
 
                }
 
            else if (action == DWFMT_monthz || action == DWFMT_monthnz)
 
                {
 
                if (action == DWFMT_monthz)
 
                    {
 
                    if (value == null)
 
                        result = "";
 
                    else if ((givenDate.month + 1) < 10)
 
                        result += "0";
 
                    }
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += (givenDate.month + 1);
 
                }
 
            else if (action == DWFMT_monthshortname)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += DW_shortMonthNames[givenDate.month];
 
                }
 
            else if (action == DWFMT_monthlongname)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += DW_longMonthNames[givenDate.month];
 
                }
 
            else if (action == DWFMT_2digityear)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    {
 
                    var tempStr = (givenDate.year + 1900).toString();
 
                    var startPos = tempStr.length - 2;
 
                    result += tempStr.substring(startPos, startPos + 2);
 
                    }
 
                }
 
            else if (action == DWFMT_4digityear)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += (givenDate.year + 1900).toString();
 
                }
 
            else if (action == DWFMT_hourz || action == DWFMT_hournz)
 
                {
 
                if ( value == null )
 
                    hour = 0;
 
                else
 
                    hour = givenDate.hour;
 
 
 
                if (! format.b24hr && hour > 12)
 
                    hour -= 12;
 
 
 
                if (action == DWFMT_hourz)
 
                    {
 
                    if (value == null)
 
                        result = "";
 
                    else if (hour < 10)
 
                        result += "0";
 
                    }
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += hour;
 
                }
 
            else if (action == DWFMT_minz || action == DWFMT_minnz)
 
                {
 
                if (action == DWFMT_minz)
 
                    {
 
                    if (value == null)
 
                        result = "";
 
                    else if (givenDate.min < 10)
 
                        result += "0";
 
                    }
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += givenDate.min;
 
                }
 
            else if (action == DWFMT_secz || action == DWFMT_secnz)
 
                {
 
                if (action == DWFMT_secz)
 
                    {
 
                    if (value == null)
 
                        result = "";
 
                    else if (givenDate.sec < 10)
 
                        result += "0";
 
                    }
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += givenDate.sec;
 
                }
 
            else if (action == DWFMT_msec)
 
                {
 
                index++;
 
                var numMsecDigits = encodedFormat[index];
 
                if (value == null)
 
                    for (var j=0; j<numMsecDigits; j++)
 
                        result = "";
 
                else
 
                    {
 
                    var tempStr = "000000" + givenDate.msec;
 
                    var valueStart = tempStr.length - 6;
 
 
 
                    result += tempStr.substring(valueStart, valueStart + numMsecDigits);
 
                    }
 
                }
 
            else if (action == DWFMT_apCaps)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += ampm ? "A" : "P";
 
                }
 
            else if (action == DWFMT_apNCaps)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += ampm ? "a" : "p";
 
                }
 
            else if (action == DWFMT_ampmCaps)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += ampm ? "AM" : "PM";
 
                }
 
            else if (action == DWFMT_ampmNCaps)
 
                {
 
                if (value == null)
 
                    result = "";
 
                else
 
                    result += ampm ? "am" : "pm";
 
                }
 
            }
 
        }
 
 
 
    if (this.bStylePositioning && format && format.bValid)  
 
        if ( format.color == "" || typeof format.color == "string")
 
            control.style.color = format.color;
 
        else
 
            control.style.color = convertToRGB( format.color );
 
 
 
    return result;
 
}
 
 
 
function DW_DaysAfter(date1,date2)
 
{
 
    return DW_daysDiff (date1.year + 1900, date1.month + 1, date1.day,
 
                date2.year + 1900, date2.month + 1, date2.day);
 
}
 
 
 
function DW_SecondsAfter(time1,time2)
 
{
 
    var    secs;
 
 
 
    // Calculate difference in times.
 
    secs = (time1.hour * 3600 + time1.min * 60 + time1.sec) - (time2.hour * 3600 + time2.min * 60 + time2.sec);
 
 
 
    return (secs);
 
}
 
 
 
function DW_DatetimeToDate(inDatetime)
 
{
 
    return new DW_DateClass(inDatetime.year, inDatetime.month, inDatetime.day);
 
}
 
 
 
function DW_DatetimeToTime(inDatetime)
 
{
 
    return new DW_TimeClass(inDatetime.hour, inDatetime.min, inDatetime.sec, inDatetime.msec);
 
}
 
 
 
function DW_RelativeDate(inDate, numDays)
 
{
 
    var year;
 
    var month;
 
    var day;
 
    var yearDays;
 
    var aleap;
 
 
 
    var newDate = new DW_DateClass (inDate.year, inDate.month, inDate.day);
 
 
 
    if (numDays != 0)         // No days; then same date
 
        {
 
        year = inDate.year + 1900;
 
 
 
        day = numDays + DW_dayOfYear(year, inDate.month+1, inDate.day) - 1;
 
        while (day >= (yearDays = DW_daysInYear(year)))
 
            {
 
            year++;
 
            day -= yearDays;
 
            }
 
        while (day < 0)
 
            day += DW_daysInYear(--year);
 
 
 
        newDate.year = year - 1900;
 
 
 
        aleap = DW_isLeap(year) ? 1 : 0;
 
        for (month=0; month< 12 && day >= DW_cumDayTable[aleap][month]; month++)
 
            ;
 
 
 
        newDate.month = month - 1;
 
        newDateday = DW_dayTable[aleap][month] - (DW_cumDayTable[aleap][month] - day) + 1;
 
        }
 
 
 
    return newDate;
 
}
 
 
 
function DW_RelativeTime(inTime, numSeconds)
 
{
 
    var result;
 
    var totalSeconds = inTime.sec + inTime.min * 60 + inTime.hour * 3600 + numSeconds;
 
 
 
    if (totalSeconds < 0)// Under flow
 
        result = null;
 
    else if (totalSeconds >= 24 * 3600) // over flow
 
        result = null;
 
    else
 
        {
 
        var hours = Math.floor(totalSeconds / 3600);
 
        var min = Math.floor((totalSeconds - hours * 3600) / 60);
 
        var sec = totalSeconds - min * 60 - hours * 3600;
 
 
 
        result = new DW_TimeClass (hours, min, sec);
 
        }
 
 
 
    return result;
 
}
 
 
 
function DW_DatetimeCompare(date1, date2)
 
{
 
    var rc;
 
 
 
    if (date1.year != date2.year)
 
        rc = date1.year - date2.year;
 
    else if (date1.month != date2.month)
 
        rc = date1.month - date2.month;
 
    else if (date1.day != date2.day)
 
        rc = date1.day - date2.day;
 
    else if (date1.hour != date2.hour)
 
        rc = date1.hour - date2.hour;
 
    else if (date1.min != date2.min)
 
        rc = date1.min - date2.min;
 
    else if (date1.sec != date2.sec)
 
        rc = date1.sec - date2.sec;
 
    else if (date1.msec < date2.msec)
 
        rc = -1;
 
    else if (date1.msec > date2.msec)
 
        rc = 1;
 
    else
 
        rc = 0;
 
    return rc;
 
}
 
 
 
function DW_DateCompare(date1, date2)
 
{
 
    var rc;
 
 
 
    if (date1.year != date2.year)
 
        rc = date1.year - date2.year;
 
    else if (date1.month != date2.month)
 
        rc = date1.month - date2.month;
 
    else if (date1.day != date2.day)
 
        rc = date1.day - date2.day;
 
    else
 
        rc = 0;
 
    return rc;
 
}
 
 
 
function DW_TimeCompare(time1, time2)
 
{
 
    var rc;
 
 
 
    if (time1.hour != time2.hour)
 
        rc = time1.hour - time2.hour;
 
    else if (time1.min != time2.min)
 
        rc = time1.min - time2.min;
 
    else if (time1.sec != time2.sec)
 
        rc = time1.sec - time2.sec;
 
    else if (time1.msec < time2.msec)
 
        rc = -1;
 
    else if (time1.msec > time2.msec)
 
        rc = 1;
 
    else
 
        rc = 0;
 
    return rc;
 
}
 
 
 
function DW_DayNumber(theDate)
 
{
 
    return DW_dayOfWeek (theDate.year + 1900, theDate.month + 1, theDate.day);
 
}
 
 
 
function DW_DayName(theDate)
 
{
 
    var dayNumber = DW_dayOfWeek (theDate.year + 1900, theDate.month + 1, theDate.day);
 
 
 
    return DW_longDayNames[dayNumber];
 
}