The TEST opcode validates whether a character field contains a valid date, time, or timestamp value. It is a fixed-format C-spec operation:
C *format TEST(D) charField 50
C *format TEST(T) charField 50
C *format TEST(Z) charField 50
Factor 1 contains the expected format code (e.g. *MDY, *ISO, *HMS). Factor 2 is always blank. The Result field is the character field to validate. The (D), (T), or (Z) extender specifies which type to test for - date, time, or timestamp respectively.
Error reporting uses either a resulting indicator in the LO position (cols 73-74), which is turned ON when the field is invalid, or the (E) extender, which sets %ERROR / %STATUS(00112) on failure. One or the other must be specified; they cannot be combined.
C *MDY TEST(D) CharDate 50
C IF *IN50 = *ON
C ...handle invalid date...
C ENDIF
C *HMS TEST(TE) CharTime
C IF %ERROR
C ...handle invalid time...
C ENDIF
When testing an actual date, time, or timestamp field (declared with type D, T, or Z), the D/T/Z extender and Factor 1 format are omitted - these fields are always valid since the runtime enforces validity at assignment:
C TEST(E) MyDateField
Supported date format codes: *MDY, *DMY, *YMD, *ISO, *USA, *EUR, *JIS, *JUL, *CYMD, *CMDY, *CDMY (and their separator-less 0 variants, e.g. *MDY0). The two-digit-year formats (*MDY, *DMY, *YMD, *JUL) validate against the 1940 - 2039 year window (so 02/29/40:*MDY is valid - 2040 is a leap year - while 02/29/39 is not). The century formats (*CYMD, *CMDY, *CDMY) expect the century-digit external form - a single leading digit (0→1900s, 1→2000s) followed by the two-digit-year layout, e.g. 115/04/15:*CYMD is 2015-04-15 - and their leap-year check honors the resolved century (000/02/29:*CYMD is invalid because 1900 is not a leap year).
Supported time format codes: *HMS, *ISO, *USA, *EUR, *JIS (and their 0 variants).