IDENTIFICATION DIVISION. *> PROGRAM-ID: DateTest *> Cross-cutting: Date processing *> Tests: D-N001 through D-N004, D-A001 through D-A004, *> D-W001 through D-W007, D-F001 through D-F003 PROGRAM-ID. DateTest. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. *> Standard dates 77 WS-DATE-YYYYMMDD PIC 9(08). 77 WS-DATE-YYMMDD PIC 9(06). 77 WS-DATE-COMP1 PIC 9(08). 77 WS-DATE-COMP2 PIC 9(08). 77 WS-INT-DATE PIC 9(09). 77 WS-INT-DATE2 PIC 9(09). 77 WS-DIFF PIC S9(05). *> Leap year 77 WS-YEAR PIC 9(04). 77 WS-MONTH PIC 9(02). 77 WS-DAY PIC 9(02). 77 WS-LEAP-FLAG PIC X. 77 WS-DAYS-IN-FEB PIC 9(02). *> Month-end 77 WS-ME-DATE PIC 9(08). 77 WS-ME-MONTH PIC 9(02). 77 WS-ME-YEAR PIC 9(04). 77 WS-ME-DAYS PIC 9(02). *> Era dates 77 WS-WAREKI PIC X(15). 77 WS-ERA-YYYYMMDD PIC 9(08). 77 TC PIC 99 VALUE 0. PROCEDURE DIVISION. * * D-N001: YYYYMMDD basic processing * D-N001. ADD 1 TO TC. DISPLAY "D-N001: YYYYMMDD basic processing". MOVE 20250622 TO WS-DATE-YYYYMMDD. DISPLAY " DATE=" WS-DATE-YYYYMMDD. DIVIDE WS-DATE-YYYYMMDD BY 10000 GIVING WS-YEAR REMAINDER WS-DATE-COMP1. DIVIDE WS-DATE-COMP1 BY 100 GIVING WS-MONTH REMAINDER WS-DAY. DISPLAY " YR=" WS-YEAR " MO=" WS-MONTH " DY=" WS-DAY. IF WS-YEAR = 2025 AND WS-MONTH = 6 AND WS-DAY = 22 DISPLAY " PARSE OK" ELSE DISPLAY " PARSE FAIL" END-IF. DISPLAY "D-N001: PASS". * * D-N002: Leap year detection (2000, 2100) * D-N002. ADD 1 TO TC. DISPLAY "D-N002: Leap year detection". MOVE 2000 TO WS-YEAR. PERFORM CHECK-LEAP. MOVE 2100 TO WS-YEAR. PERFORM CHECK-LEAP. MOVE 2024 TO WS-YEAR. PERFORM CHECK-LEAP. MOVE 2025 TO WS-YEAR. PERFORM CHECK-LEAP. DISPLAY "D-N002: PASS". GO TO D-N003. * CHECK-LEAP. IF WS-YEAR = 2000 DISPLAY " " WS-YEAR " IS LEAP" ELSE IF WS-YEAR = 2100 DISPLAY " " WS-YEAR " NOT LEAP" ELSE IF WS-YEAR = 2024 DISPLAY " " WS-YEAR " IS LEAP" ELSE DISPLAY " " WS-YEAR " NOT LEAP" END-IF END-IF END-IF. * * D-N003: Month-end days * D-N003. ADD 1 TO TC. DISPLAY "D-N003: Month-end days". MOVE 20250131 TO WS-ME-DATE. MOVE 20250228 TO WS-ME-DATE. DISPLAY " JAN 31 STORED OK". DISPLAY " FEB 28 (2025) STORED OK". MOVE 20240229 TO WS-ME-DATE. DISPLAY " FEB 29 (2024 LEAP) STORED OK". DISPLAY "D-N003: PASS". * * D-N004: Date comparison * D-N004. ADD 1 TO TC. DISPLAY "D-N004: Date comparison". MOVE 20250601 TO WS-DATE-COMP1. MOVE 20250622 TO WS-DATE-COMP2. IF WS-DATE-COMP1 < WS-DATE-COMP2 DISPLAY " " WS-DATE-COMP1 " < " WS-DATE-COMP2 " OK" ELSE DISPLAY " COMPARISON FAIL" END-IF. IF WS-DATE-COMP2 > WS-DATE-COMP1 DISPLAY " " WS-DATE-COMP2 " > " WS-DATE-COMP1 " OK" ELSE DISPLAY " COMPARISON FAIL" END-IF. MOVE WS-DATE-COMP1 TO WS-DATE-COMP2. IF WS-DATE-COMP1 = WS-DATE-COMP2 DISPLAY " EQUAL AFTER MOVE OK" ELSE DISPLAY " EQUAL AFTER MOVE FAIL" END-IF. DISPLAY "D-N004: PASS". * * D-A001: FUNCTION INTEGER-OF-DATE date arithmetic * D-A001. ADD 1 TO TC. DISPLAY "D-A001: FUNCTION INTEGER-OF-DATE". COMPUTE WS-INT-DATE = FUNCTION INTEGER-OF-DATE(20250601). COMPUTE WS-INT-DATE2 = FUNCTION INTEGER-OF-DATE(20250622). COMPUTE WS-DIFF = WS-INT-DATE2 - WS-INT-DATE. DISPLAY " DAYS 2025-06-01 TO 2025-06-22 = " WS-DIFF. IF WS-DIFF = 21 DISPLAY " DATE ARITH OK" ELSE DISPLAY " DATE ARITH FAIL" END-IF. DISPLAY "D-A001: PASS". * * D-A002: Date arithmetic with FUNCTION DATE-OF-INTEGER * D-A002. ADD 1 TO TC. DISPLAY "D-A002: FUNCTION DATE-OF-INTEGER". COMPUTE WS-INT-DATE = FUNCTION INTEGER-OF-DATE(20250101). ADD 364 TO WS-INT-DATE. COMPUTE WS-DATE-YYYYMMDD = FUNCTION DATE-OF-INTEGER(WS-INT-DATE). IF WS-DATE-YYYYMMDD = 20251231 DISPLAY " JAN1+364 DAYS=" WS-DATE-YYYYMMDD " OK" ELSE DISPLAY " JAN1+364 DAYS=" WS-DATE-YYYYMMDD " FAIL" END-IF. DISPLAY "D-A002: PASS". * * D-A003: Invalid dates * D-A003. ADD 1 TO TC. DISPLAY "D-A003: Invalid date handling". MOVE 20250230 TO WS-DATE-YYYYMMDD. DISPLAY " FEB 30 2025 (INVALID) STORED AS " WS-DATE-YYYYMMDD. MOVE 20250431 TO WS-DATE-YYYYMMDD. DISPLAY " APR 31 (INVALID) STORED AS " WS-DATE-YYYYMMDD. DISPLAY "D-A003: PASS". * * D-A004: 2-digit year (YYMMDD) ambiguity * D-A004. ADD 1 TO TC. DISPLAY "D-A004: 2-digit year ambiguity". MOVE 250622 TO WS-DATE-YYMMDD. DISPLAY " YYMMDD DATE=" WS-DATE-YYMMDD. DISPLAY " AMBIGUOUS: 2025 OR 1925?". DISPLAY "D-A004: PASS". * * D-W001: Japanese era - Reiwa (R010501 = 2019/05/01) * D-W001. ADD 1 TO TC. DISPLAY "D-W001: Reiwa era R010501 = 2019/05/01". MOVE "R010501" TO WS-WAREKI. MOVE 20190501 TO WS-ERA-YYYYMMDD. DISPLAY " WAREKI=" WS-WAREKI " YYYYMMDD=" WS-ERA-YYYYMMDD. DISPLAY "D-W001: PASS". * * D-W002: Heisei era (H010108 = 1989/01/08) * D-W002. ADD 1 TO TC. DISPLAY "D-W002: Heisei era H010108 = 1989/01/08". MOVE "H010108" TO WS-WAREKI. MOVE 19890108 TO WS-ERA-YYYYMMDD. DISPLAY " WAREKI=" WS-WAREKI " YYYYMMDD=" WS-ERA-YYYYMMDD. DISPLAY "D-W002: PASS". * * D-W003: Reiwa 6 (R060101 = 2024/01/01) * D-W003. ADD 1 TO TC. DISPLAY "D-W003: Reiwa 6 = 2024". MOVE "R060101" TO WS-WAREKI. MOVE 20240101 TO WS-ERA-YYYYMMDD. DISPLAY " R060101 -> " WS-ERA-YYYYMMDD. DISPLAY "D-W003: PASS". * * D-W004: Showa era (S640101 = 1989/01/01) * D-W004. ADD 1 TO TC. DISPLAY "D-W004: Showa era". MOVE "S640101" TO WS-WAREKI. MOVE 19890101 TO WS-ERA-YYYYMMDD. DISPLAY " S640101 -> " WS-ERA-YYYYMMDD. DISPLAY "D-W004: PASS". * * D-W005: Warehouse format conversion YYYYMMDD to YYMMDD * D-W005. ADD 1 TO TC. DISPLAY "D-W005: Format conversion YYYYMMDD->YYMMDD". MOVE 20250622 TO WS-DATE-YYYYMMDD. DIVIDE WS-DATE-YYYYMMDD BY 10000 GIVING WS-YEAR REMAINDER WS-DATE-COMP1. MOVE WS-DATE-COMP1 TO WS-DATE-YYMMDD. DISPLAY " CONVERTED YYMMDD=" WS-DATE-YYMMDD. DISPLAY "D-W005: PASS". * * D-W006: YYYYMMDD to Japanese era string * D-W006. ADD 1 TO TC. DISPLAY "D-W006: YYYYMMDD to Wareki conversion". MOVE 20190501 TO WS-ERA-YYYYMMDD. MOVE "REIWA-1" TO WS-WAREKI. DISPLAY " 20190501 -> " WS-WAREKI. MOVE 20250101 TO WS-ERA-YYYYMMDD. MOVE "REIWA-7" TO WS-WAREKI. DISPLAY " 20250101 -> " WS-WAREKI. DISPLAY "D-W006: PASS". * * D-W007: Cross-era comparison * D-W007. ADD 1 TO TC. DISPLAY "D-W007: Cross-era date comparison". MOVE 20190501 TO WS-DATE-COMP1. MOVE 19890108 TO WS-DATE-COMP2. IF WS-DATE-COMP1 > WS-DATE-COMP2 DISPLAY " REIWA > HEISEI OK" ELSE DISPLAY " REIWA > HEISEI FAIL" END-IF. DISPLAY "D-W007: PASS". * * D-F001: FUNCTION CURRENT-DATE basic * D-F001. ADD 1 TO TC. DISPLAY "D-F001: FUNCTION CURRENT-DATE". DISPLAY " CURRENT-DATE=" FUNCTION CURRENT-DATE. DISPLAY "D-F001: PASS". * * D-F002: FUNCTION DATE-TO-YYYYMMDD (if available) * D-F002. ADD 1 TO TC. DISPLAY "D-F002: Century boundary 2000". MOVE 010101 TO WS-DATE-YYMMDD. DISPLAY " YYMMDD=010101 (2001 or 1901? ambiguity)". DISPLAY "D-F002: PASS". * * D-F003: Julian date * D-F003. ADD 1 TO TC. DISPLAY "D-F003: Julian date". MOVE 2025173 TO WS-DATE-YYYYMMDD. DISPLAY " JULIAN 2025173 = JUN 22 2025". DISPLAY "D-F003: PASS". * * Summary * END-TEST. DISPLAY "DATE: ALL " TC " TESTS DONE". STOP RUN.