1. Home
  2. /
  3. Docs
  4. /
  5. Articles Report Writer
  6. /
  7. Report Functions
  8. /
  9. Date Functions

Date Functions

Date functions are available throughout the Articles report script editor. They provide tools for calculating date differences, checking date conditions, encoding and decoding date components, and working with the current date and time.


Date

Returns the current date with no time component.

Date: TDateTime
// Stamp today's date on a report header
Result := 'Date: ' + DateToStr(Date);

// Compare a field date to today
if [Orders.DueDate] < Date then
  Result := 'Overdue'
else
  Result := 'Current';

// Use directly in an inline expression
// [DateToStr(Date)]

DaysBetweenSafe

Returns the number of days between two dates. Handles Null values in either date safely without raising an error.

DaysBetweenSafe(A, B: Variant): Integer
ParameterTypeDescription
AVariantThe start date
BVariantThe end date
// Days since an order was placed
Result := IntToStr(DaysBetweenSafe([Orders.OrderDate], Date)) + ' days ago';

// Days until a contract expires
var d := DaysBetweenSafe(Date, [Vendor.ContractExpiry]);
if d < 30 then
  Result := 'Expiring soon (' + IntToStr(d) + ' days)'
else
  Result := IntToStr(d) + ' days remaining';

// Safe when either date might be NULL
Result := IntToStr(DaysBetweenSafe([Employee.HireDate], [Employee.TermDate]));

DayOfWeek

Returns the day of the week for a given date as an integer. Sunday = 1, Monday = 2, through Saturday = 7.

DayOfWeek(ADate: TDateTime): Integer
ParameterTypeDescription
ADateTDateTimeThe date to evaluate
// Get the day name for a date
var days := 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday';
Result := StringMap(IntToStr(DayOfWeek([Orders.OrderDate])),
                   '1,2,3,4,5,6,7', days);

// Check if an order was placed on a weekend
if DayOfWeek([Orders.OrderDate]) in [1, 7] then
  Result := 'Weekend order'
else
  Result := 'Weekday order';

DaysInMonth

Returns the number of days in a specified month and year. Correctly handles leap years for February.

DaysInMonth(nYear, nMonth: Integer): Integer
ParameterTypeDescription
nYearIntegerThe year (e.g. 2024)
nMonthIntegerThe month number (1-12)
Result := IntToStr(DaysInMonth(2024, 2));
// Returns: '29'  (2024 is a leap year)

Result := IntToStr(DaysInMonth(2023, 2));
// Returns: '28'

// Get days in the current month
var y, m, d: Word;
DecodeDate(Date, y, m, d);
Result := IntToStr(DaysInMonth(y, m)) + ' days this month';

DecodeDate

Splits a date value into its year, month, and day components. Use this when you need to work with individual parts of a date.

procedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word)
ParameterTypeDescription
DateTDateTimeThe date to decode
YearWordReceives the year component
MonthWordReceives the month component (1-12)
DayWordReceives the day component (1-31)
var y, m, d: Word;
DecodeDate([Orders.OrderDate], y, m, d);
Result := IntToStr(m) + '/' + IntToStr(y);
// Returns: '3/2024'

// Get just the year from a date field
var yr, mo, dy: Word;
DecodeDate(Date, yr, mo, dy);
Result := 'Fiscal Year ' + IntToStr(yr);

// Build a period label from month and year
DecodeDate([Invoice.InvoiceDate], y, m, d);
Result := FormatDateTime('mmmm yyyy', EncodeDate(y, m, 1));
// Returns: 'March 2024'

DecodeTime

Splits a time value into its hour, minute, second, and millisecond components.

procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word)
ParameterTypeDescription
TimeTDateTimeThe time value to decode
HourWordReceives the hour (0-23)
MinWordReceives the minutes (0-59)
SecWordReceives the seconds (0-59)
MSecWordReceives the milliseconds (0-999)
var h, m, s, ms: Word;
DecodeTime(Now, h, m, s, ms);
Result := IntToStr(h) + ' hours, ' + IntToStr(m) + ' minutes';

// Check if a timestamp is in business hours
DecodeTime([Log.Timestamp], h, m, s, ms);
if (h >= 9) and (h < 17) then
  Result := 'Business hours'
else
  Result := 'After hours';

EncodeDate

Builds a date value from individual year, month, and day components. Use this when you need to construct a specific date in a script.

EncodeDate(Year, Month, Day: Word): TDateTime
ParameterTypeDescription
YearWordThe year (e.g. 2024)
MonthWordThe month (1-12)
DayWordThe day (1-31)
// Build the first day of the current month
var y, m, d: Word;
DecodeDate(Date, y, m, d);
var firstOfMonth := EncodeDate(y, m, 1);
Result := DateToStr(firstOfMonth);

// Build a specific date for comparison
var deadline := EncodeDate(2024, 12, 31);
if Date > deadline then
  Result := 'Past deadline'
else
  Result := 'On track';

EncodeTime

Builds a time value from individual hour, minute, second, and millisecond components.

EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime
ParameterTypeDescription
HourWordHour (0-23)
MinWordMinutes (0-59)
SecWordSeconds (0-59)
MSecWordMilliseconds (0-999)
// Build a specific time for comparison
var cutoff := EncodeTime(17, 0, 0, 0);  // 5:00 PM
var h, m, s, ms: Word;
DecodeTime(Now, h, m, s, ms);
if EncodeTime(h, m, s, ms) > cutoff then
  Result := 'After closing time';

IsFuture

Returns True if a date is in the future (after today).

IsFuture(ADate: TDateTime): Boolean
ParameterTypeDescription
ADateTDateTimeThe date to evaluate
if IsFuture([Vendor.ContractExpiry]) then
  Result := 'Contract active'
else
  Result := 'Contract expired';

// Use in inline expression
// [IIF(IsFuture([Orders.DueDate]), 'Pending', 'Overdue')]

IsLeapYear

Returns True if the specified year is a leap year.

IsLeapYear(Year: Word): Boolean
ParameterTypeDescription
YearWordThe year to check
if IsLeapYear(2024) then
  Result := 'Leap year';

// Check for the current year
var y, m, d: Word;
DecodeDate(Date, y, m, d);
if IsLeapYear(y) then
  Result := IntToStr(y) + ' is a leap year';

IsPast

Returns True if a date is in the past (before today).

IsPast(ADate: TDateTime): Boolean
ParameterTypeDescription
ADateTDateTimeThe date to evaluate
if IsPast([Orders.DueDate]) then
  Result := 'Overdue'
else
  Result := 'Due: ' + DateToStr([Orders.DueDate]);

// Flag expired warranties
if IsPast([Item.WarrantyExpiry]) then
  Result := 'WARRANTY EXPIRED';

IsToday

Returns True if a date value falls on today’s date.

IsToday(ADate: TDateTime): Boolean
ParameterTypeDescription
ADateTDateTimeThe date to evaluate
if IsToday([Orders.OrderDate]) then
  Result := 'New today'
else
  Result := DateToStr([Orders.OrderDate]);

// Highlight orders due today
if IsToday([Orders.DueDate]) then
  Result := 'DUE TODAY';

IsWeekend

Returns True if a date falls on a Saturday or Sunday.

IsWeekend(ADate: TDateTime): Boolean
ParameterTypeDescription
ADateTDateTimeThe date to evaluate
if IsWeekend([Orders.OrderDate]) then
  Result := 'Weekend order'
else
  Result := 'Weekday order';

// Flag transactions that occurred on weekends
if IsWeekend([Journal.TransDate]) then
  Result := '** Weekend Transaction **';

MonthsBetweenSafe

Returns the number of complete months between two dates. Handles Null values safely.

MonthsBetweenSafe(A, B: Variant): Integer
ParameterTypeDescription
AVariantThe start date
BVariantThe end date
// Months of service for an employee
Result := IntToStr(MonthsBetweenSafe([Employee.HireDate], Date)) + ' months';

// Months remaining on a contract
var m := MonthsBetweenSafe(Date, [Vendor.ContractExpiry]);
Result := IntToStr(m) + ' ' + Pluralize(m, 'month', 'months') + ' remaining';

Now

Returns the current date and time combined as a single value.

Now: TDateTime
// Stamp the current date and time on a report
Result := 'Printed: ' + FormatDateTime('mm/dd/yyyy hh:nn', Now);

// Log when a report was generated
Result := DateTimeToStr(Now);

// Calculate elapsed time since a stored timestamp
var elapsed := Now - StrToDateTime([Log.StartTime]);
Result := FormatDateTime('hh:nn:ss', elapsed);

Time

Returns the current time with no date component.

Time: TDateTime
// Show the current time in a report footer
Result := 'Generated at: ' + TimeToStr(Time);

// Check if within business hours
var h, m, s, ms: Word;
DecodeTime(Time, h, m, s, ms);
if (h >= 9) and (h < 17) then
  Result := 'Business hours'
else
  Result := 'After hours';

YearsBetweenSafe

Returns the number of complete years between two dates. Handles Null values safely. Commonly used for calculating age or tenure.

YearsBetweenSafe(A, B: Variant): Integer
ParameterTypeDescription
AVariantThe start date
BVariantThe end date
// Years of service for an employee
var yrs := YearsBetweenSafe([Employee.HireDate], Date);
Result := IntToStr(yrs) + ' ' + Pluralize(yrs, 'year', 'years') + ' of service';

// Age from date of birth (see also AgeFromDOB in Conversion Functions)
Result := IntToStr(YearsBetweenSafe([Employee.DOB], Date)) + ' years old';

// Years remaining on a long-term contract
Result := IntToStr(YearsBetweenSafe(Date, [Vendor.ContractExpiry])) + ' years left';