JScript - Working With Date Values

Applies to TestComplete 15.70, last modified on December 17, 2024

This topic explains how to work with date values in JScript and gives examples of date operations. It contains the following sections:

Basics

When writing scripts we often deal with dates. There are certain date value formats and TestComplete routines that help handle dates.

Since the TestComplete scripting engine only supports OLE-compatible data types, the date-time values are implemented as floating-point variant values in a special format. The integer part of this value represents the number of days that have passed since December 30, 1899. The number after the decimal separator represents the fraction of a 24-hour period that has elapsed. However, you do not have to understand what these floating-point values represent. TestComplete provides several routines that help you convert these values to their string representation (see below).

Below are some examples of date-time values and their meaning:

Value Meaning
0.25 December 30, 1899. 6:00 AM
36345.5 July 4, 1999. 12:00 PM
39094.65625 January 12, 2007. 3:45 PM

When you are only working with date values the fractional part can be omitted.

Objects and Functions for Working With Date Values

TestComplete has the aqDateTime object that contains methods that can be useful when operating with dates.

Method Description
AddDays Adds or subtracts the specified number of days to (from) the given date.
AddMonths Adds or subtracts the specified number of months to (from) the given date.
AddTime Adds or subtracts the specified number of days, hours, minutes and seconds to (from) the given date.
Compare Compares two specified date/time values.
GetDay Returns the ordinal number of a day in a month.
GetDayOfWeek Returns the day of the week for the specified date.
GetDayOfYear Returns the ordinal number of a day in a year.
GetMonth Returns the month number of the specified date.
GetYear Returns the year number of the specified date.
IsLeapYear Indicates whether the specified year is a leap year.
Now Returns the current date and time.
SetDateElements Returns the Date variable having the specified year, month and day.
SetDateTimeElements Returns the Date variable having the specified date and time portions.
SetSystemDateTime Assigns the specified date and time as the system date and time.
Today Returns the current date.

One more object, aqConvert, provides methods to convert strings between date values and their string equivalents:

Method Description
DateTimeToFormatStr Converts the given date value to a string using the specified format.
DateTimeToStr Converts the given date value to a string.
StrToDate Converts the specified string to a date value.
StrToDateTime Converts the specified string to a date/time value.

The aqDateTime and aqConvert objects are available for all supported scripting languages, so that you can use them to operate with date values regardless of the chosen language.

Getting Current Date

There are two routines that return current date: Today and Now. The difference between them is that the value returned by the Now routine includes both the date and time parts, whereas the Date routine returns only the date part. The script below demonstrates how to use them.

JScript

function GetDate()
{
  var TodayValue, NowValue, StringTodayValue, StringNowValue, VariantTodayValue, VariantNowValue

  // Obtain the current date
  TodayValue = aqDateTime.Today();

  // Obtain the current date and time
  NowValue = aqDateTime.Now();
  
  // Convert the returned date/time values to the string values
  StringTodayValue = aqConvert.DateTimeToStr(TodayValue);
  StringNowValue = aqConvert.DateTimeToStr(NowValue);

  // Post the converted values to the log
  Log.Message("The date obtained from the Today routine is " + StringTodayValue);
  Log.Message("The date obtained from the Now routine is " + StringNowValue);
  
  // Convert the floating-point values to the string values
  VariantTodayValue = aqConvert.FloatToStr(TodayValue);
  VariantNowValue = aqConvert.FloatToStr(NowValue);

  // Post the converted values to the log
  Log.Message("The variant representation of TodayValue is " + VariantTodayValue);
  Log.Message("The variant representation of NowValue is " + VariantNowValue)
}

Getting Tomorrow’s and Yesterday’s Dates

The sample below demonstrates how the aqDateTime object can be used to calculate tomorrow's date. The current date is obtained via the aqDateTime.Today method. Then the current date value is incremented via the aqDateTime.AddDays method. The DateTimeToStr method of the aqConvert object is used to convert the date value into a string that is posted to the TestComplete log.

JScript

function TomorrowDate()
{
  // Obtain the current date
  var CurrentDate = aqDateTime.Today();

  // Convert the date/time value to a string and post it to the log
  Today = aqConvert.DateTimeToStr(CurrentDate);
  Log.Message("Today is " + Today);

  // Calculate the tomorrow’s date, convert the returned date to a string and post this string to the log
  Tomorrow = aqDateTime.AddDays(CurrentDate, 1);
  ConvertedTomorrowDate = aqConvert.DateTimeToStr(Tomorrow);
  Log.Message("Tomorrow will be " + ConvertedTomorrowDate);
  return Tomorrow;
}

Similarily, you can calculate any date that differs from the current day by a certain amount of days: yesterday, next or previous week and so forth. For example, to get yesterday’s date, you have to pass -1 as the second parameter of the aqDateTime.AddDays method.

JScript

function YesterdayDate()
{
  // Obtain the current date
  var CurrentDate = aqDateTime.Today();

  // Convert the date/time value to a string and post it to the log
  Today = aqConvert.DateTimeToStr(CurrentDate);
  Log.Message("Today is " + Today);

  // Calculate the yesterday’s date, convert the returned date to a string and post this string to the log
  YesterdayDate = aqDateTime.AddDays(CurrentDate, -1);
  ConvertedYesterdayDate = aqConvert.DateTimeToStr(YesterdayDate);
  Log.Message("Yesterday was " + ConvertedYesterdayDate);
}

Calculating the Year and Month Duration

Generally there are 365 days in a calendar year. However the length of an astronomical year is about 365.242375 days, so in the course of time the fractional part would result in an extra day and the calendar year would lag from the astronomical. To avoid this the leap year that is 366 days long was invented.

The Gregorian calendar is the current standard calendar in most of the world and it adds a 29th day to February in all years evenly divisible by 4, except for centennial years (those ending in -00), which only receive the extra day if they are evenly divisible by 400. The aqDateTime object has a special method IsLeapYear that accepts the year number and returns true if the specified year is a leap year. We can use this method to get the exact number of days in the desired year:

JScript

function DaysInYear(YearNo)
{
  return 365 + aqDateTime.IsLeapYear(YearNo);
}

In the sample above, the Boolean value was converted into an integer since JScript allows implicit type conversion.

Using the IsLeapYear method we can get the number of days in the month. For all months, except February, the duration of a month is fixed and is either 30 or 31 days. The duration of February is 28 or 29 days depending on whether the current year is a leap year or not. The routine that gets the month duration would be the following:

JScript

function DaysInMonth(MonthNo, YearNo)
{
  switch (MonthNo)
  {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31;
    case 2: if (aqDateTime.IsLeapYear(YearNo)) return 29; return 28;
    case 4: case 6: case 9: case 11: return 30;
  }
}

Comparing Dates

To compare date/time values, use the aqDateTime.Compare method rather than comparison operators (like ==, >, <, != and others) provided by the scripting engine:

JScript

r = aqDateTime.Compare(DateTime1, DateTime2);
if (r > 0)
  // DateTime1 > DateTime2
else
  if (r < 0)
    // DateTime1 < DateTime2
  else
    // DateTime1 == DateTime2

This note does not concern the Date objects provided by the JScript engine. To compare Date objects, use the features provided by the engine.

Encoding and Decoding Date Values

Because the date values are represented as variants, special routines are required that convert the variant value to a calendar date format and back. These operations are performed by the SetDateElements, GetYear, GetMonth and GetDay methods of the aqDateTime object. These methods take into account whether the current year is a leap year and the number of days in a month so that the resulting value is guaranteed to be valid. The SetDateElements accepts the parts of date and returns the variant date value.

JScript

function EncodeDateDemo()
{
  // Create a Date variable having the specified year, month and day values
  var myDate = aqDateTime.SetDateElements(2005, 12, 25);

  // Convert the value of the myDate variable to a string using the specified format and post this string to the log
  EncodedDate = aqConvert.DateTimeToFormatStr(myDate,"%B/%#d/%Y");
  Log.Message("The encoded date is "+ EncodedDate);

  // Convert the value of the myDate variable to a variant value and post it to the log
  VariantDate = aqConvert.IntToStr(myDate);
  Log.Message("The variant representation of it is "+ VariantDate);
}

The GetYear, GetMonth and GetDay methods accept the variant date-time value and return the respective date parts of that value. Here is an example of how to use these routines:

JScript

function DecodeDateDemo()
{
  // Obtain the current date
  var CurrentDate = aqDateTime.Today();

  // Return the parts of the current date value and then post them to the log
  var Year = aqDateTime.GetYear(CurrentDate);
  var Month = aqDateTime.GetMonth(CurrentDate);
  var Day = aqDateTime.GetDay(CurrentDate);

  Log.Message(Day + " day(s) have passed since the beginning of the " + Month + " month of " + Year + " year.");
}

Modifying Date Values

Despite the fact that date-time values are represented as floating-point numbers, you cannot explicitly use ordinary arithmetic operators to change dates or times. However, the aqDateTime scripting object provides a number of methods that are especially designed to modify date-time values. These methods are: AddMonths, AddDays and AddTime. The AddTime method allows to modify date and time portions at once.

As you may notice from the Getting Tomorrow’s and Yesterday’s Dates section, these methods are used both for incrementing and decrementing of date-time values. When the positive number is passed as Month, Days or another parameter, then the resulting value is increased. If the parameter is negative, then the resulting value is decreased.

These methods take into account the number of days in the month, whether the year is a leap and other aspects of time calculations, that is why the resulting value is guaranteed to be valid.

The code below demonstrates how to use these methods:

JScript

function ModifyDates()
{
    var Date, AlteredDate;

    Date = aqDateTime.SetDateElements(2007, 1, 25);

    // Increase the date by 7 days
    // Note the month changing
    AlteredDate = aqDateTime.AddDays(Date, 7);
    Log.Message("Initial date: " + aqConvert.DateTimeToStr(Date));
    Log.Message("Altered date 1: " + aqConvert.DateTimeToStr(AlteredDate));

    // Increase the date by one month
    // Note that 28 days were added since the month is February
    AlteredDate = aqDateTime.AddMonths(AlteredDate, 1);
    Log.Message("Altered date 2: " + aqConvert.DateTimeToStr(AlteredDate));

    // Decrease the date by 1 day
    AlteredDate = aqDateTime.AddTime(AlteredDate, -1, 0, 0, 0);
    Log.Message("Altered date 3: " + aqConvert.DateTimeToStr(AlteredDate));
}

Dealing With Week Days

Besides recognizing the date, month and year, you may need to know which day of the week a certain date falls. The aqDateTime.GetDayOfWeek method performs this task. It accepts the variant date and returns the number of the week day that corresponds to it. The returned number ranges between 1 and 7, where 1 corresponds to Sunday, 2 - to Monday, and so forth. The sample code below obtains the current date, calculates the day of the week and posts the name of the day to the log.

JScript

function DayOfWeekDemo()
{
  var WeekDay, DayName;

  WeekDay = aqDateTime.GetDayOfWeek(aqDateTime.Today());
  switch (WeekDay)
  {
    case 1: DayName = "Sunday"; break;
    case 2: DayName = "Monday"; break;
    case 3: DayName = "Tuesday"; break;
    case 4: DayName = "Wednesday"; break;
    case 5: DayName = "Thursday"; break;
    case 6: DayName = "Friday"; break;
    case 7: DayName = "Saturday"; break;
  }
  Log.Message("Today is " + DayName);
}

Note: The GetDayOfWeek method uses the United States system of week notation where the week is considered to start on Sunday and end on Saturday. However, the ISO 8601 “Data elements and interchange formats - Information interchange - Representation of dates and times” standard recommends another system of a week notation. In this system the week starts on Monday and ends on Sunday. To convert the US Week day number to ISO 8601 you can use the following routine:

JScript

function ISODayOfWeek(InputDate)
{
  var ReturnDate = aqDateTime.GetDayOfWeek(InputDate) - 1;
  if (ReturnDate == 0) ReturnDate = 7;
  return ReturnDate;
}

The result of this function is also an integer number, but 1 corresponds to Monday, 2 to Tuesday and so on.

In addition to the day of the week, we can find out the week boundaries that the specified date belongs, that is, calculate the dates that the week starts and ends. This could be done using the following two routines. Here the number of a week day is subtracted from the specified date to get the beginning of a week, and to get the end of the week, six days are added to the calculated date.

JScript

function StartOfWeek (InputDate)
{
  // If the input parameter is omitted then current date is taken
  if (InputDate == undefined) InputDate = aqDateTime.Today();

  // Using US week day number
  return aqDateTime.AddDays(InputDate, - aqDateTime.GetDayOfWeek(InputDate) + 1);

  // Using ISO week day number
  // return aqDateTime.AddDays(InputDate, - ISODayOfWeek(InputDate) + 1);
}

function EndOfWeek (InputDate)
{
  // If the input parameter is omitted then current date is taken
  if (InputDate == undefined) InputDate = aqDateTime.Today();

  // Using US week day number
  return aqDateTime.AddDays(InputDate, - aqDateTime.GetDayOfWeek(InputDate) + 7);

  // Using ISO week day number
  // return aqDateTime.AddDays(InputDate, - ISODayOfWeek(InputDate) + 7);
}

Note: Since the routines use the aqDateTime.GetDayOfWeek method, which returns the US week day number, the dates returned by the routines are Sunday and Saturday, correspondingly. To apply the ISO 8601 week day notation, you should use the last code line, where the aqDateTime.GetDayOfWeek call is replaced with a call to ISODayOfWeek function. (The code of the ISODayOfWeek function is provided in the note above.) In this case the first routine would return the date that falls on Monday and the second one, the date that falls on Sunday.

Another frequent operation when dealing with dates is calculating the number of weeks that have passed since the beginning of the year. First we should clarify what week should be considered as the first week of a year. According to the ISO 8601 standard, the first week of a year is a week with the majority (four or more) of days in the starting year. In our case it is better to use another equivalent definition of the first week: the week with the date, January, 4th.

Here is the routine that calculates the week number in compliance with this rule. It accepts the date that belongs to the desired week, determines the end of this week and the end of the week that includes January 4, and that calculates the week number as the difference between those two values divided by 7.

JScript

function WeekNumber(InputDate)
{
  var YearNo = aqDateTime.GetYear(InputDate);
  var EndOfFirstWeek = EndOfWeek(aqDateTime.SetDateElements(YearNo,1,4));
  var EndOfCurrentWeek = EndOfWeek(InputDate);
  return 1 + (aqDateTime.GetDayOfYear(EndOfCurrentWeek) - aqDateTime.GetDayOfYear(EndOfFirstWeek)) / 7;
}

Sometimes it is useful to know what day of the week the desired month starts or ends. The routines below return the week day number that correspond to the beginning and end of the month. They only have one input parameter that specifies the date which belongs to the desired month. If the parameter is missing then the routines return the results for the current month. The routines are similar to calculating the beginning and end of a week, but instead of the week day number, the day of the month number is used.

JScript

function StartOfMonthDay (InputDate)
{
  // If the input parameter is omitted then current date is taken
  if (InputDate == undefined) InputDate = aqDateTime.Today();
  var StartDate = aqDateTime.AddDays(InputDate, - aqDateTime.GetDay(InputDate)+1);

  // Using US week day number
  return aqDateTime.GetDayOfWeek(StartDate);

  // Using ISO week day number
  // return ISODayOfWeek(StartDate);
}

function EndOfMonthDay (InputDate)
{
  // If the input parameter is omitted then current date is taken
  if (InputDate == undefined) InputDate = aqDateTime.Today();
  var DayNo = aqDateTime.GetDay(InputDate);
  var MonthNo = aqDateTime.GetMonth(InputDate);
  var YearNo = aqDateTime.GetYear(InputDate);
  var EndDate = aqDateTime.AddDays(InputDate, - DayNo + DaysInMonth(MonthNo, YearNo));

  // Using US week day number
  return aqDateTime.GetDayOfWeek(EndDate);

  // Using ISO week day number
  // return ISODayOfWeek(EndDate);
}

Converting to Date Object

JScript has the native Date object that was created to hold date-time values and has its own methods to manage dates. The complete description of the object is in the Date Object article of the MSDN library. Since C#Script and C++Script are based on JScript, the Date object is also available in these scripting languages. The sample code below demonstrates how to create this object.

JScript

function DateDemo()
{
  // Create Date object.
  var DateObj = new Date();
  Log.Message(DateObj.toDateString());
  var Day = DateObj.getDate();
  var Month = DateObj.getMonth();
  var Year = DateObj.getYear();

  // Note that the month number is zero-based
  Log.Message(Day + " day(s) have passed since the beginning of the " + (Month + 1) + " month of " + Year + " year.");
}

However the methods of the aqDateTime object can only operate with the variant date-time values. To convert variant values to instances of the Date object and vice versa you can use the following routines. The first one accepts the variant value as input parameter and returns the object instance and the second routine, on the contrary, accepts the object instance and returns variant.

JScript

function ToDateObject (InputDate)
{
  // Parse variant date onto components
  var Day = aqDateTime.GetDay(InputDate);
  var Month = aqDateTime.GetMonth(InputDate);
  var Year = aqDateTime.GetYear(InputDate);

  // Create Date object
  var DateObj = new Date();

  // Assign values to object
  DateObj.setDate(Day);
  DateObj.setMonth(Month - 1);
  DateObj.setFullYear(Year);

  return DateObj;
}

function ToVariantDate (InputDateObj)
{
  var VariantDate = aqDateTime.SetDateElements(InputDateObj.getFullYear(), InputDateObj.getMonth() + 1, InputDateObj.getDate());
  return VariantDate;
}

Note: The routines above only deal with the date portion. However the Date object can store time values as well. To learn how to convert a variant value holding both date and time parts to the Date object instance, see a similar section in the JScript - Working With Time Values topic.

See Also

Working With Dates
JScript - Working With Time Values
aqDateTime Object

Highlight search results