External date formats—MMDDYY, CCYYMMDD, Julian YYDDD—exist so humans and legacy files can read calendar parts in digit positions. Internal date representation collapses a calendar position into one integer: typically the count of days before or after a fixed base date such as December 31, 1900. That encoding makes adding thirty days or comparing two dates a numeric operation instead of month-end logic with leap years scattered through IF blocks. Easytrieve batch programs often start with external N fields from COBOL files, then convert to internal packed values inside DATECALC, DATECONV, or installation date exit routines for arithmetic. This page explains internal versus external storage, packed P day-count fields, conversion boundaries, and how subsystem documentation describes ADD_DAYS and FROM_EXTERNAL patterns compatible with Easytrieve date processing ecosystems.
| Aspect | External | Internal |
|---|---|---|
| Purpose | Human and file interchange | Calendar arithmetic |
| Typical type | N 6 or N 8 digit string | P or B integer day count |
| Example | 031585 MMDDYY | 30728 days from base (illustrative) |
| Add 30 days | Needs conversion first | Add 30 to integer |
| Report print | Direct with MASK | Convert out via DATECONV |
Confusing layers causes subtle bugs: comparing FILE MMDDYY hire date to internal packed run date without conversion looks like IF logic works on some records and fails on others because byte patterns encode different meanings at the same numeric magnitude.
CA-family date modeling often defines day zero as December 31, 1900. January 1, 1901 becomes day 1; earlier calendar dates become negative integers. A five-digit internal field supports roughly 273 years of range from that base in related documentation examples. Easytrieve core DEFINE does not expose a separate D type letter like some IDEAL dataviews, but date routines and companion utilities consume the same day-count concept when converting external strings to packed internal values for ADD_DAYS style operations.
Internal dates frequently store as packed decimal P with zero decimal positions—four or seven byte examples appear in subsystem integration docs. P 7 0 holds seven-digit day magnitudes efficiently. Binary four-byte internal dates also appear in ADD_DAYS function signatures where FROM_DATE, DAYS, and RESULT_DATE are four-byte packed internal forms. Match byte length and packed layout to the routine you call—declaring internal date as N 7 display when file carries P 4 packed misaligns every subsequent field.
1234567DEFINE EXT-HIRE W 8 N DEFINE INT-HIRE W 4 P 0 DEFINE INT-RUN W 4 P 0 DEFINE DAYS-SERV W 4 P 0 * After DATECONV external to internal: DAYS-SERV = INT-RUN - INT-HIRE
Pattern: read external FILE date, validate with %DATEVAL and format literal, convert to internal with DATECONV or installation FROM_EXTERNAL equivalent, perform arithmetic, convert back for REPORT LINE external MASK display. SET_FORMAT or installation defaults tell conversion routines how to interpret character external literals like YYYY/MM/DD before FROM_EXTERNAL populates internal packed fields.
12345%DATEVAL EXT-HIRE MMDDCCYY IF DATEVAL-FLAG EQ 'YES' %DATECONV EXT-HIRE MMDDCCYY INT-HIRE P-int-format %DATECALC INT-HIRE int-fmt PLUS 30 EXT-DUE ext-fmt END-IF
Exact internal format parameter names depend on installed routine variants—consult site macro library. Concept remains: never add thirty to MMDDYY digits directly—month lengths forbid it.
DATECALC adds or subtracts a day count from a formatted date field, writing another formatted field—not always exposing internal integers to application code. Internally the routine still applies calendar rules including month lengths and leap years. THRESHOLD governs century on two-digit external formats during calculation. Validate inputs with DATEVAL when feeds are untrusted—invalid February 30 should fail before arithmetic propagates garbage.
Julian YYDDD external is not the same encoding as day-count internal though both feel numeric. Julian keeps year visible in digits; internal hides year into scalar offset. Converting Julian to internal requires DATECONV with YYDDD format literal, not manual multiplication of day-of-year by constants—which breaks across century and leap rules.
SYSDATE and %GETDATE deliver external display form for titles. If job logic needs internal run date for aging calculations against internal stored customer open dates, add conversion step once after GETDATE: external run date to packed internal INT-RUN, then subtract internal invoice dates for days-past-due numeric comparisons without string parsing in every detail line.
CA-1 and related utilities document ADD_DAYS with four-byte packed internal FROM_DATE, DAYS, and RESULT_DATE. TO_EXTERNAL converts internal packed back to ten-byte character external with SET_FORMAT controlling separator pattern. Easytrieve programs participating in those ecosystems DEFINE compatible P 4 fields and call interfaces documented for the utility—not reimplement leap-year tables in PROC unless policy requires self-contained logic.
External date is writing March 15 on a calendar page. Internal date is counting how many days from a starting line you drew on a long strip of paper—day one, day two, thousands later. Adding thirty days on the strip means count thirty steps forward, which is easy. Adding thirty on the calendar page means crossing month ends and February rules—hard without a helper. Easytrieve helpers convert between the page view and the strip count.
1. Internal date storage often uses:
2. External date MMDDYY differs from internal because:
3. DATECALC adds days by:
4. Five-byte internal date value can represent roughly:
5. Before comparing internal and external dates you should: