Gregorian date formats in DFSORT are calendar dates: year, month, and day. The way those three parts are arranged in the record—year first, year last, 2-digit vs 4-digit year—determines which format code you use (Y2T, Y2W, Y4T, Y4W) and how the date sorts and displays. The most useful format for sorting and filtering is YYYYMMDD (8 bytes, year first), because character order then matches chronological order. This page explains the main Gregorian layouts (YYYYMMDD, MMDDYYYY, DDMMYYYY), the DFSORT format codes that describe them, how to convert between them with TOGREG, and when to use display formats (e.g. with separators) in reports.
Mainframe data uses several common arrangements of year, month, and day. Each has a different sort behavior and a corresponding DFSORT format code.
| Layout | Example | Format code | Sort as CH |
|---|---|---|---|
| YYYYMMDD | 20241225 | Y4T (year first) | Yes—chronological order |
| MMDDYYYY | 12252024 | Y4W (year last) | No—month/day first breaks order |
| DDMMYYYY | 25122024 | Y4W (year last; day/month order) | No |
| YYMMDD | 251225 | Y2T (2-digit year first) | Only if year order correct; century window applies |
| MMDDYY | 122525 | Y2W (2-digit year last) | No |
Y4T (4-digit year, year first) is the format you get from TOGREG=Y4T and is the one to use when you need to sort or compare by date. Y4W (year last) describes input like MMDDYYYY or DDMMYYYY; you convert that to Y4T (YYYYMMDD) in INREC when you need correct sort order.
YYYYMMDD (or ccyymmdd) is 8 bytes: 4-digit year, 2-digit month, 2-digit day. Example: 20241225 for December 25, 2024. When you sort this field as character ascending, the order is chronological: 20230101 comes before 20231231, and 20221231 comes before 20230101. So SORT FIELDS=(pos,8,CH,A) on a YYYYMMDD field gives date order. INCLUDE and OMIT conditions (e.g. GE C'20230101') also work as expected. This is why converting other formats to YYYYMMDD in INREC is so common: once converted, sorting and filtering are straightforward.
In MMDDYYYY the month and day come first, then the 4-digit year (e.g. 12252024 for December 25, 2024). In DFSORT this is described by Y4W (4-digit year last). As character, this does not sort chronologically: 12311999 is greater than 01012000 as strings, even though December 31, 1999 is before January 1, 2000. So if your input is MMDDYYYY, convert to YYYYMMDD in INREC using 60,8,Y4W,TOGREG=Y4T (adjust position and length to match your data), place the result at a fixed position, and sort on that. The same idea applies to DDMMYYYY (day, month, year)—still year last, so Y4W; the difference is whether the first four bytes are MMDD or DDMM. Specify the format that matches your actual byte order.
The T in Y4T means year first ("top" or leading). The W in Y4W means year last (trailing). You do not choose T vs W by preference—you choose based on how the input bytes are laid out. If the first bytes of the date field are the year, use Y4T (or Y2T for 2-digit year). If the last bytes are the year, use Y4W (or Y2W). Using the wrong code causes the wrong value to be interpreted as year, month, or day and can produce incorrect or invalid dates.
| Code | Meaning |
|---|---|
| Y4T | 4-digit year first: ccyymmdd or ccyyddd (Julian). |
| Y4W | 4-digit year last: mmddccyy or dddccyy (Julian). |
| Y2T | 2-digit year first: yymmdd or yyddd. Century window applies. |
| Y2W | 2-digit year last: mmddyy or dddyy. Century window applies. |
Typical pattern: input has a Gregorian date in a non-sortable form (e.g. MMDDYYYY at 60,8). Convert in INREC and put YYYYMMDD at the start of the record:
12INREC BUILD=(1:60,8,Y4W,TOGREG=Y4T,9:1,59,69:61,20) SORT FIELDS=(1,8,CH,A)
Here 1:60,8,Y4W,TOGREG=Y4T reads 8 bytes at 60 as mmddccyy, converts to ccyymmdd, and places the 8-byte result at output position 1. The rest of the record is copied. SORT FIELDS=(1,8,CH,A) then sorts by date. Use the same approach for DDMMYYYY (still Y4W if the year is last; ensure the byte order matches your data).
For reports, you often want a human-readable date (e.g. 12/25/2024 or 2024-12-25) instead of 20241225. Options include: (1) Use a display format in OUTREC or in OUTFIL HEADER if your DFSORT version supports it (e.g. TOGREG with a format that adds separators, or DATE= in headers). (2) Build the display form manually in OUTREC using edited fields, constants, and substrings (e.g. extract month, day, year and place with slashes). (3) Keep the sort key as YYYYMMDD and only change the presentation in the output. Exact syntax for separator formats is product-dependent; check your manual.
When the source has a 2-digit year (yy), use Y2T or Y2W. DFSORT then applies a century window to interpret yy (e.g. 25 → 2025, 99 → 1999). Dates outside that window can get the wrong century; prefer 4-digit year (Y4T, Y4W) when the data has it. See Century windowing for details.
Imagine writing a date three ways: "2024 December 25," "December 25 2024," and "25 December 2024." The first one, when you sort a list of such lines, puts the oldest year first, then the month, then the day—so everything lines up in time order. The other two ways mix month and day first, so sorting by the written order does not give time order. Gregorian formats are just those different ways of writing the same date. DFSORT lets you convert from one way to another. We usually convert everything to "year first" (YYYYMMDD) so that when the computer sorts the records, the dates come in the right order.
1. Which Gregorian format sorts correctly as character (CH) ascending?
2. What does Y4W mean in DFSORT date format?
3. Your input has dates in MMDDYYYY at position 60 (8 bytes). You want to sort by date. What should you do?
4. What is the difference between Y4T and Y4W for Gregorian input?
5. Why might you want a display format (e.g. with slashes or hyphens) in OUTREC instead of plain YYYYMMDD?