RPGLE Date and Time BIFs Reference

This page is a lookup for the RPGLE date and time built-in functions: what each one takes, what it returns, and the edge cases that cause run-time errors or surprising results. For a worked tutorial that also covers the CEE date APIs and embedded SQL date functions, read ILE RPG Date, Time and Timestamp Handling. The complete list of BIFs is in the RPGLE Built-in Functions Reference.

All examples are free-form RPGLE.

Date and time BIFs at a glance

BIFWhat it doesReturns
%dateBuild or convert to a dateA date
%timeBuild or convert to a timeA time
%timestampBuild or convert to a timestampA timestamp
%days, %months, %yearsA duration to add to or subtract from a dateA duration
%hours, %minutes, %seconds, %msecondsA duration to add to or subtract from a time or timestampA duration
%diffThe length of time between two valuesInteger
%subdtOne part of a date, time or timestampInteger

%DATE

Returns a date. With no parameters it returns the current date.

%date({value {: format}})
ParameterMeaning
valueA character, numeric, date or timestamp value to convert. Omit it for today’s date
formatThe format of value, such as *iso or *usa, for character or numeric data. If you omit it, *iso is assumed. Do not give it for a timestamp
dcl-s today date;
dcl-s fromText date;
dcl-s fromNumber date;

today      = %date();                          // the current date
fromText   = %date('10/05/2026' : *usa);       // 2026-10-05
fromNumber = %date(20261005 : *iso);           // 2026-10-05

Date formats

A format code tells %date how to read character or numeric data, and tells %char how to write a date.

FormatLayoutExample
*ISOyyyy-mm-dd2026-10-05
*USAmm/dd/yyyy10/05/2026
*EURdd.mm.yyyy05.10.2026
*JISyyyy-mm-dd2026-10-05
*YMDyy/mm/dd26/10/05
*MDYmm/dd/yy10/05/26
*DMYdd/mm/yy05/10/26
*JULyy/ddd26/278

The two-digit-year formats (*YMD, *MDY, *DMY, *JUL) cover a limited range of years. Prefer a four-digit-year format for new code.

%TIME and %TIMESTAMP

%time returns a time and %timestamp returns a timestamp. Both return the current value when called with no parameters.

%time({value {: format}})
%timestamp({value})
dcl-s now time;
dcl-s stamp timestamp;

now   = %time();                  // the current time
stamp = %timestamp();             // the current date and time

%DAYS, %MONTHS and %YEARS

These return a duration, which you add to or subtract from a date. They do not stand alone.

%days(number)
%months(number)
%years(number)
dcl-s start date inz(d'2026-10-05');
dcl-s due date;

due = start + %days(30);         // 2026-11-04
due = start + %months(3);        // 2027-01-05
due = start - %years(1);         // 2025-10-05

The time durations %hours, %minutes, %seconds and %mseconds work the same way with a time or timestamp.

%DIFF

Returns the number of units between two values, as an integer.

%diff(value1 : value2 : unit)

The result is value1 minus value2, so it is negative when value1 is the earlier value. Both values must be the same type, or a timestamp paired with a date or a time, in which case only the matching part of the timestamp is used. For timestamps, an optional fourth parameter sets the number of fractional seconds to return.

UnitMeaningValid with
*years or *yWhole yearsDate, timestamp
*months or *mWhole monthsDate, timestamp
*days or *dDaysDate, timestamp
*hours or *hHoursTime, timestamp
*minutes or *mnMinutesTime, timestamp
*seconds or *sSecondsTime, timestamp
*mseconds or *msMicrosecondsTime, timestamp
dcl-s startDate date inz(d'2026-10-05');
dcl-s endDate date inz(d'2026-12-25');
dcl-s span int(10);

span = %diff(endDate : startDate : *days);     // 81
span = %diff(startDate : endDate : *days);     // -81

%SUBDT

Returns one part of a date, time or timestamp as an integer.

%subdt(value : unit {: digits {: decimals}})
dcl-s d date inz(d'2026-10-05');
dcl-s yearPart int(10);
dcl-s monthPart int(10);

yearPart  = %subdt(d : *years);      // 2026
monthPart = %subdt(d : *months);     // 10

The units are the same as for %diff. The optional digits and decimals parameters set the size of the result, which matters mainly for *mseconds.

Worked example: days overdue

A common use of several BIFs together: find how many days an invoice is overdue, and a new due date if it is extended by one month.

dcl-s invoiceDue date inz(d'2026-09-15');
dcl-s today      date inz(d'2026-10-05');
dcl-s daysLate   int(10);
dcl-s extended   date;

daysLate = %diff(today : invoiceDue : *days);     // 20
if daysLate > 0;
  extended = invoiceDue + %months(1);             // 2026-10-15
endif;

%diff is positive here because today is the later value. Reverse the arguments and the result is -20, which is why the sign convention matters when you test daysLate > 0.

Choosing a duration BIF

  • Use %days when the interval is a fixed number of days, such as a 30-day payment term.
  • Use %months when the interval follows the calendar, such as “same day next month”.
  • Use %years for anniversaries. Remember the leap-day rule above.
  • Use %diff rather than subtracting dates by hand. Subtracting two dates directly is an error unless you use %diff or a duration.

Legacy opcodes

Fixed-format code used opcodes for the same jobs. They still compile; use the BIF in new code.

Fixed-format opcodeFree-form equivalent
ADDDUR+ with %days, %months, %years or a time duration
SUBDUR (duration)- with a duration, or %diff to find the difference
EXTRCT%subdt
TIME%time() or %timestamp()

Common mistakes

  • Converting character or numeric data with %date and no format, so the compiler cannot know how to read it.
  • Assuming + %months(1) always keeps the same day of the month.
  • Using %diff with a unit that does not fit the type.
  • Reading the sign of %diff backwards. The result is the first value minus the second.
  • Calling %date on input you have not validated. An invalid date stops the program with a run-time error.

FAQ

How do I get today’s date in RPGLE?

Assign %date() to a date field. For the current time use %time(), and for both use %timestamp().

How do I count the days between two dates?

Use %diff(laterDate : earlierDate : *days). The result is positive when the first date is later.

How do I add a month to a date?

Add %months(1) to the date. If the day does not exist in the new month, the result is the last day of that month.

Summary

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top