A Julian date in mainframe and DFSORT terms is a date stored as year plus day-of-year: YYYYDDD (or YYDDD with a 2-digit year). The DDD part is 001–366: 001 is January 1, 032 is February 1, and 365 (or 366 in a leap year) is December 31. Many legacy systems store dates in this form because it is compact (7 bytes for YYYYDDD), sorts correctly as character, and avoids month/day logic. In DFSORT you use TOJUL to convert a Gregorian (calendar) date to Julian and TOGREG to convert Julian to Gregorian. This page explains the Julian format, how to convert to and from it in INREC and OUTREC, when to use it, and how it fits with the rest of Date & Time Processing (Gregorian formats, date arithmetic, century windowing).
The Julian date format used in DFSORT (and many mainframe applications) is not the same as the historical Julian calendar. Here it simply means: year followed by day-of-year. The day-of-year is a number from 001 to 365 (or 366 in a leap year). So there is no separate month and day—just "which day of the year."
| Part | Meaning |
|---|---|
| YYYY (or YY) | 4-digit year (ccyy) or 2-digit year (yy). With 2-digit, century windowing applies. |
| DDD | Day of year: 001 = Jan 1, 032 = Feb 1, 059 = Feb 28, 060 = Feb 29 (leap), 366 = Dec 31 (leap only). |
Examples: 2024001 is January 1, 2024. 2024060 is February 29, 2024 (leap year). 2024366 is December 31, 2024. In a non-leap year like 2023, the last day is 2023365; 2023366 would be invalid.
Julian format has several practical advantages on the mainframe:
When your input is already in Julian form, you must tell DFSORT the format so it can parse and convert it. Use the same format codes as for Gregorian:
| Code | Meaning |
|---|---|
| Y2T | 2-digit year first: yyddd (5 bytes). Century window applies to yy. |
| Y4T | 4-digit year first: ccyyddd (7 bytes). Standard Julian in DFSORT. |
So if the input has a 7-byte Julian date at position 41 in ccyyddd form, you specify 41,7,Y4T as the source. If it were 5-byte yyddd, you would use the position, 5, and Y2T. Then you add the conversion operator: TOGREG=Y4T to convert to Gregorian (ccyymmdd) or TOJUL=Y4T to keep or produce Julian (ccyyddd).
When the input date is in Gregorian form (e.g. YYYYMMDD or MMDDYYYY), use TOJUL=Y4T (or TOJUL=Y2T for 2-digit year output) to produce Julian. The source format must match the input: Y4T for ccyymmdd, Y4W for mmddccyy, etc.
Example: input has an 8-byte YYYYMMDD at position 50. Convert to 7-byte YYYYDDD and place it at the start of the record for sorting:
12INREC BUILD=(1:50,8,Y4T,TOJUL=Y4T,8:1,49,58:51,30) SORT FIELDS=(1,7,CH,A)
Here 1:50,8,Y4T,TOJUL=Y4T means: from input positions 50–57 (8 bytes), interpret as Y4T (ccyymmdd), convert to Julian Y4T (ccyyddd), and place the 7-byte result at output position 1. Then the rest of the record is copied. Sorting on 1,7 as character ascending gives chronological order by the Julian date.
When the input is Julian (YYYYDDD) and you need a calendar date (e.g. for a report or to sort by YYYYMMDD), use the matching source format for Julian and TOGREG=Y4T. The source is 7 bytes for Y4T (ccyyddd).
12INREC BUILD=(1:41,7,Y4T,TOGREG=Y4T,9:1,40,49:42,35) SORT FIELDS=(1,8,CH,A)
1:41,7,Y4T,TOGREG=Y4T: input 41–47 is ccyyddd (Julian); convert to ccyymmdd (8 bytes) and place at output 1–8. Now SORT FIELDS=(1,8,CH,A) sorts by the Gregorian date. Use INREC when the sort or INCLUDE/OMIT must see the Gregorian value; use OUTREC when you only need it in the final output.
The same conversion syntax (source format plus TOJUL or TOGREG) works in both INREC and OUTREC. The difference is when it runs:
Julian TOJUL=Y4T produces 7 bytes (ccyyddd). Gregorian TOGREG=Y4T produces 8 bytes (ccyymmdd). When you build records in INREC or OUTREC, the next output position must account for this. For example, if you put a converted Julian at 1–7, the next field starts at 8; if you put a converted Gregorian at 1–8, the next starts at 9.
In a leap year, day 366 is December 31. In a non-leap year, the last day is 365. DFSORT follows the calendar rules for leap years (divisible by 4, with exceptions for century years). Invalid input (e.g. 366 for a non-leap year) may produce incorrect results or errors; validate source data if needed.
Imagine you have a big calendar with 365 (or 366) boxes for the year. Instead of saying "March 15," you say "day number 74" (or whatever number March 15 is). That number is the "day of the year." A Julian date is just: the year, then that day number. So "2024 074" means the 74th day of 2024. Computers like it because it's one number for the day instead of month and day, and when you sort those numbers, the dates come in the right order.
1. What does the DDD part of YYYYDDD (Julian date) represent?
2. How do you convert a Gregorian date (YYYYMMDD) to Julian (YYYYDDD) in DFSORT?
3. Why might Julian (YYYYDDD) be useful for sorting or comparing dates?
4. If your input has Julian date at position 41 (7 bytes, YYYYDDD), and you need to sort by calendar date, what should you do?
5. What is the length of the output when you convert to TOJUL=Y4T vs TOGREG=Y4T?