MainframeMaster

COBOL Tutorial

COBOL CENTURY-DATE Function

The CENTURY-DATE intrinsic function in COBOL converts dates by adding century information to two-digit year formats, addressing Y2K compliance requirements and ensuring proper date handling across century boundaries. This function is essential for legacy system modernization, date migration projects, historical data processing, and maintaining accurate chronological calculations in applications that handle dates spanning multiple centuries while preserving existing date logic and business rules in enterprise-scale mainframe environments where data integrity and temporal accuracy are paramount.

Understanding CENTURY-DATE Function

CENTURY-DATE converts a date from YYMMDD format to YYYYMMDD format using specified century windowing rules. This function helps resolve Y2K ambiguity by determining whether a two-digit year belongs to the 1900s or 2000s based on configurable pivot years and windowing logic, making it indispensable for date arithmetic, historical data analysis, and maintaining chronological accuracy in business applications.

Core Features:

  • Gregorian date century conversion with customizable windowing rules
  • Y2K compliance and century boundary handling for legacy systems
  • Configurable pivot years for different data domains and business contexts
  • Seamless integration with existing date processing logic and calculations
  • Support for historical data migration and temporal data consistency
  • Compatibility with standard COBOL date arithmetic and comparison operations
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
*> Basic CENTURY-DATE function usage DATA DIVISION. WORKING-STORAGE SECTION. 01 DATE-CONVERSION-EXAMPLES. 05 INPUT-DATE-YY PIC 9(6) VALUE 991231. *> YYMMDD format 05 OUTPUT-DATE-YYYY PIC 9(8). *> YYYYMMDD result 05 PIVOT-YEAR PIC 99 VALUE 30. *> Century pivot 05 CURRENT-DATE-8 PIC 9(8). 01 DATE-VALIDATION. 05 VALID-DATE-FLAG PIC X VALUE 'Y'. 88 DATE-IS-VALID VALUE 'Y'. 88 DATE-INVALID VALUE 'N'. 05 LEAP-YEAR-FLAG PIC X VALUE 'N'. 88 IS-LEAP-YEAR VALUE 'Y'. 01 DATE-COMPONENTS. 05 CONVERTED-YEAR PIC 9(4). 05 CONVERTED-MONTH PIC 9(2). 05 CONVERTED-DAY PIC 9(2). PROCEDURE DIVISION. BASIC-CENTURY-DATE-CONVERSION. *> Basic conversion with default pivot COMPUTE OUTPUT-DATE-YYYY = FUNCTION CENTURY-DATE(INPUT-DATE-YY) DISPLAY "Original Date (YYMMDD): " INPUT-DATE-YY DISPLAY "Century Date (YYYYMMDD): " OUTPUT-DATE-YYYY *> Conversion with specific pivot year COMPUTE OUTPUT-DATE-YYYY = FUNCTION CENTURY-DATE(INPUT-DATE-YY, PIVOT-YEAR) DISPLAY "With Pivot " PIVOT-YEAR ": " OUTPUT-DATE-YYYY *> Extract components for further processing PERFORM EXTRACT-DATE-COMPONENTS PERFORM VALIDATE-CONVERTED-DATE. EXTRACT-DATE-COMPONENTS. COMPUTE CONVERTED-YEAR = OUTPUT-DATE-YYYY / 10000 COMPUTE CONVERTED-MONTH = FUNCTION MOD(OUTPUT-DATE-YYYY, 10000) / 100 COMPUTE CONVERTED-DAY = FUNCTION MOD(OUTPUT-DATE-YYYY, 100) DISPLAY "Year: " CONVERTED-YEAR DISPLAY "Month: " CONVERTED-MONTH DISPLAY "Day: " CONVERTED-DAY. VALIDATE-CONVERTED-DATE. *> Basic date validation MOVE 'Y' TO VALID-DATE-FLAG IF CONVERTED-MONTH < 1 OR CONVERTED-MONTH > 12 MOVE 'N' TO VALID-DATE-FLAG DISPLAY "Invalid month: " CONVERTED-MONTH END-IF IF CONVERTED-DAY < 1 OR CONVERTED-DAY > 31 MOVE 'N' TO VALID-DATE-FLAG DISPLAY "Invalid day: " CONVERTED-DAY END-IF IF DATE-IS-VALID DISPLAY "Date validation: PASSED" ELSE DISPLAY "Date validation: FAILED" END-IF.

Advanced Century Windowing Strategies

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
*> Advanced century windowing for different business contexts DATA DIVISION. WORKING-STORAGE SECTION. 01 BUSINESS-DOMAIN-WINDOWS. 05 BIRTH-DATE-PIVOT PIC 99 VALUE 25. *> 1925-2024 for people 05 CONTRACT-PIVOT PIC 99 VALUE 70. *> 1970-2069 for contracts 05 FINANCIAL-PIVOT PIC 99 VALUE 90. *> 1990-2089 for transactions 05 HISTORICAL-PIVOT PIC 99 VALUE 00. *> 1900-1999 for archives 01 DATE-PROCESSING-CONTEXT. 05 CONTEXT-TYPE PIC X(15). 05 SELECTED-PIVOT PIC 99. 05 CONTEXT-RULES PIC X(50). 01 WINDOWING-TEST-CASES. 05 TEST-DATES OCCURS 15 TIMES. 10 TD-INPUT PIC 9(6). 10 TD-CONTEXT PIC X(15). 10 TD-EXPECTED PIC 9(8). 10 TD-ACTUAL PIC 9(8). 10 TD-RESULT PIC X(4). 88 TEST-PASSED VALUE "PASS". 88 TEST-FAILED VALUE "FAIL". 01 SLIDING-WINDOW-CONTROL. 05 CURRENT-YEAR-4 PIC 9(4). 05 SLIDING-PIVOT PIC 99. 05 WINDOW-SIZE PIC 99 VALUE 50. *> 50-year window 05 FUTURE-BIAS PIC 99 VALUE 20. *> 20 years into future PROCEDURE DIVISION. ADVANCED-WINDOWING-STRATEGIES. PERFORM INITIALIZE-TEST-CASES PERFORM BUSINESS-CONTEXT-WINDOWING PERFORM SLIDING-WINDOW-PROCESSING PERFORM WINDOWING-VALIDATION-TESTING. BUSINESS-CONTEXT-WINDOWING. DISPLAY "=== Business Context Windowing ===" *> Employee birth date processing MOVE "BIRTH_DATE" TO CONTEXT-TYPE MOVE BIRTH-DATE-PIVOT TO SELECTED-PIVOT MOVE "People born 1925-2024" TO CONTEXT-RULES MOVE 750815 TO WS-INPUT-DATE *> Aug 15, 1975 or 2075? COMPUTE WS-CONVERTED-DATE = FUNCTION CENTURY-DATE(WS-INPUT-DATE, SELECTED-PIVOT) DISPLAY "Context: " CONTEXT-TYPE DISPLAY "Input: " WS-INPUT-DATE DISPLAY "Converted: " WS-CONVERTED-DATE DISPLAY "Rule: " CONTEXT-RULES *> Contract date processing MOVE "CONTRACT" TO CONTEXT-TYPE MOVE CONTRACT-PIVOT TO SELECTED-PIVOT MOVE "Contracts 1970-2069" TO CONTEXT-RULES MOVE 850401 TO WS-INPUT-DATE *> Apr 1, 1985 or 2085? COMPUTE WS-CONVERTED-DATE = FUNCTION CENTURY-DATE(WS-INPUT-DATE, SELECTED-PIVOT) DISPLAY "Context: " CONTEXT-TYPE DISPLAY "Input: " WS-INPUT-DATE DISPLAY "Converted: " WS-CONVERTED-DATE *> Financial transaction processing MOVE "FINANCIAL" TO CONTEXT-TYPE MOVE FINANCIAL-PIVOT TO SELECTED-PIVOT MOVE "Transactions 1990-2089" TO CONTEXT-RULES MOVE 051225 TO WS-INPUT-DATE *> Dec 25, 2005 or 1905? COMPUTE WS-CONVERTED-DATE = FUNCTION CENTURY-DATE(WS-INPUT-DATE, SELECTED-PIVOT) DISPLAY "Context: " CONTEXT-TYPE DISPLAY "Input: " WS-INPUT-DATE DISPLAY "Converted: " WS-CONVERTED-DATE. SLIDING-WINDOW-PROCESSING. DISPLAY "=== Sliding Window Processing ===" *> Calculate sliding pivot based on current year MOVE FUNCTION CURRENT-DATE(1:4) TO CURRENT-YEAR-4 COMPUTE SLIDING-PIVOT = FUNCTION MOD(CURRENT-YEAR-4 - FUTURE-BIAS, 100) DISPLAY "Current Year: " CURRENT-YEAR-4 DISPLAY "Future Bias: " FUTURE-BIAS " years" DISPLAY "Calculated Sliding Pivot: " SLIDING-PIVOT *> Apply sliding window to various dates PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 5 EVALUATE WS-I WHEN 1 MOVE 200101 TO WS-TEST-DATE *> Jan 1, 20XX WHEN 2 MOVE 501231 TO WS-TEST-DATE *> Dec 31, 19XX/20XX WHEN 3 MOVE 751120 TO WS-TEST-DATE *> Nov 20, 19XX/20XX WHEN 4 MOVE 990229 TO WS-TEST-DATE *> Feb 29, 19XX/20XX WHEN 5 MOVE 100516 TO WS-TEST-DATE *> May 16, 19XX/20XX END-EVALUATE COMPUTE WS-SLIDING-RESULT = FUNCTION CENTURY-DATE(WS-TEST-DATE, SLIDING-PIVOT) DISPLAY "Input: " WS-TEST-DATE " -> Sliding Result: " WS-SLIDING-RESULT END-PERFORM. INITIALIZE-TEST-CASES. *> Set up comprehensive test cases MOVE 991231 TO TD-INPUT(1) MOVE "BIRTH_DATE" TO TD-CONTEXT(1) MOVE 19991231 TO TD-EXPECTED(1) MOVE 000101 TO TD-INPUT(2) MOVE "CONTRACT" TO TD-CONTEXT(2) MOVE 20000101 TO TD-EXPECTED(2) MOVE 500630 TO TD-INPUT(3) MOVE "FINANCIAL" TO TD-CONTEXT(3) MOVE 20500630 TO TD-EXPECTED(3) MOVE 750815 TO TD-INPUT(4) MOVE "BIRTH_DATE" TO TD-CONTEXT(4) MOVE 19750815 TO TD-EXPECTED(4) MOVE 851201 TO TD-INPUT(5) MOVE "CONTRACT" TO TD-CONTEXT(5) MOVE 19851201 TO TD-EXPECTED(5). WINDOWING-VALIDATION-TESTING. DISPLAY "=== Windowing Validation Testing ===" PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 5 EVALUATE TD-CONTEXT(WS-I) WHEN "BIRTH_DATE" MOVE BIRTH-DATE-PIVOT TO SELECTED-PIVOT WHEN "CONTRACT" MOVE CONTRACT-PIVOT TO SELECTED-PIVOT WHEN "FINANCIAL" MOVE FINANCIAL-PIVOT TO SELECTED-PIVOT END-EVALUATE COMPUTE TD-ACTUAL(WS-I) = FUNCTION CENTURY-DATE(TD-INPUT(WS-I), SELECTED-PIVOT) IF TD-ACTUAL(WS-I) = TD-EXPECTED(WS-I) MOVE "PASS" TO TD-RESULT(WS-I) ELSE MOVE "FAIL" TO TD-RESULT(WS-I) END-IF DISPLAY "Test " WS-I ": " TD-CONTEXT(WS-I) " Input=" TD-INPUT(WS-I) " Expected=" TD-EXPECTED(WS-I) " Actual=" TD-ACTUAL(WS-I) " Result=" TD-RESULT(WS-I) END-PERFORM.

Legacy System Migration and Data Conversion

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
*> Legacy system migration using CENTURY-DATE DATA DIVISION. WORKING-STORAGE SECTION. 01 MIGRATION-CONTROL. 05 TOTAL-RECORDS PIC 9(8) VALUE ZERO. 05 CONVERTED-RECORDS PIC 9(8) VALUE ZERO. 05 ERROR-RECORDS PIC 9(6) VALUE ZERO. 05 MIGRATION-STATUS PIC X(20) VALUE "IN_PROGRESS". 01 LEGACY-RECORD-LAYOUT. 05 LEGACY-CUSTOMER-ID PIC 9(8). 05 LEGACY-BIRTH-DATE PIC 9(6). *> YYMMDD 05 LEGACY-HIRE-DATE PIC 9(6). *> YYMMDD 05 LEGACY-CONTRACT-DATE PIC 9(6). *> YYMMDD 05 LEGACY-STATUS PIC X(2). 01 MODERNIZED-RECORD-LAYOUT. 05 MOD-CUSTOMER-ID PIC 9(8). 05 MOD-BIRTH-DATE PIC 9(8). *> YYYYMMDD 05 MOD-HIRE-DATE PIC 9(8). *> YYYYMMDD 05 MOD-CONTRACT-DATE PIC 9(8). *> YYYYMMDD 05 MOD-STATUS PIC X(2). 05 MOD-CONVERSION-DATE PIC 9(8). *> Conversion timestamp 01 DATE-VALIDATION-RULES. 05 MIN-BIRTH-YEAR PIC 9(4) VALUE 1900. 05 MAX-BIRTH-YEAR PIC 9(4) VALUE 2010. 05 MIN-HIRE-YEAR PIC 9(4) VALUE 1950. 05 MAX-HIRE-YEAR PIC 9(4) VALUE 2030. 05 MIN-CONTRACT-YEAR PIC 9(4) VALUE 1970. 05 MAX-CONTRACT-YEAR PIC 9(4) VALUE 2040. 01 CONVERSION-LOG. 05 LOG-RECORD-ID PIC 9(8). 05 LOG-FIELD-NAME PIC X(20). 05 LOG-OLD-VALUE PIC 9(6). 05 LOG-NEW-VALUE PIC 9(8). 05 LOG-ERROR-CODE PIC X(4). 05 LOG-TIMESTAMP PIC X(26). PROCEDURE DIVISION. LEGACY-SYSTEM-MIGRATION. PERFORM INITIALIZE-MIGRATION PERFORM PROCESS-LEGACY-RECORDS PERFORM GENERATE-MIGRATION-REPORT. INITIALIZE-MIGRATION. MOVE ZERO TO TOTAL-RECORDS CONVERTED-RECORDS ERROR-RECORDS MOVE "STARTING" TO MIGRATION-STATUS DISPLAY "=== Legacy System Migration Started ===" DISPLAY "Date Conversion: YYMMDD -> YYYYMMDD" DISPLAY "Migration Date: " FUNCTION CURRENT-DATE. PROCESS-LEGACY-RECORDS. PERFORM UNTIL END-OF-LEGACY-FILE ADD 1 TO TOTAL-RECORDS *> Read legacy record READ LEGACY-FILE INTO LEGACY-RECORD-LAYOUT AT END SET END-OF-LEGACY-FILE TO TRUE NOT AT END PERFORM CONVERT-LEGACY-RECORD END-READ *> Progress reporting every 1000 records IF FUNCTION MOD(TOTAL-RECORDS, 1000) = ZERO DISPLAY "Processed " TOTAL-RECORDS " records" END-IF END-PERFORM. CONVERT-LEGACY-RECORD. MOVE LEGACY-CUSTOMER-ID TO MOD-CUSTOMER-ID MOVE LEGACY-STATUS TO MOD-STATUS MOVE FUNCTION CURRENT-DATE(1:8) TO MOD-CONVERSION-DATE *> Convert birth date PERFORM CONVERT-BIRTH-DATE *> Convert hire date PERFORM CONVERT-HIRE-DATE *> Convert contract date PERFORM CONVERT-CONTRACT-DATE *> Validate converted record PERFORM VALIDATE-CONVERTED-RECORD IF CONVERSION-SUCCESSFUL PERFORM WRITE-MODERNIZED-RECORD ADD 1 TO CONVERTED-RECORDS ELSE PERFORM LOG-CONVERSION-ERROR ADD 1 TO ERROR-RECORDS END-IF. CONVERT-BIRTH-DATE. IF LEGACY-BIRTH-DATE NOT = ZERO COMPUTE MOD-BIRTH-DATE = FUNCTION CENTURY-DATE(LEGACY-BIRTH-DATE, 25) *> Validate birth date range COMPUTE WS-BIRTH-YEAR = MOD-BIRTH-DATE / 10000 IF WS-BIRTH-YEAR < MIN-BIRTH-YEAR OR WS-BIRTH-YEAR > MAX-BIRTH-YEAR PERFORM LOG-DATE-ERROR MOVE "BIRTH_DATE" TO LOG-FIELD-NAME MOVE LEGACY-BIRTH-DATE TO LOG-OLD-VALUE MOVE MOD-BIRTH-DATE TO LOG-NEW-VALUE MOVE "RANG" TO LOG-ERROR-CODE END-IF ELSE MOVE ZERO TO MOD-BIRTH-DATE END-IF. CONVERT-HIRE-DATE. IF LEGACY-HIRE-DATE NOT = ZERO COMPUTE MOD-HIRE-DATE = FUNCTION CENTURY-DATE(LEGACY-HIRE-DATE, 50) *> Validate hire date range COMPUTE WS-HIRE-YEAR = MOD-HIRE-DATE / 10000 IF WS-HIRE-YEAR < MIN-HIRE-YEAR OR WS-HIRE-YEAR > MAX-HIRE-YEAR PERFORM LOG-DATE-ERROR MOVE "HIRE_DATE" TO LOG-FIELD-NAME MOVE LEGACY-HIRE-DATE TO LOG-OLD-VALUE MOVE MOD-HIRE-DATE TO LOG-NEW-VALUE MOVE "RANG" TO LOG-ERROR-CODE END-IF ELSE MOVE ZERO TO MOD-HIRE-DATE END-IF. CONVERT-CONTRACT-DATE. IF LEGACY-CONTRACT-DATE NOT = ZERO COMPUTE MOD-CONTRACT-DATE = FUNCTION CENTURY-DATE(LEGACY-CONTRACT-DATE, 70) *> Validate contract date range COMPUTE WS-CONTRACT-YEAR = MOD-CONTRACT-DATE / 10000 IF WS-CONTRACT-YEAR < MIN-CONTRACT-YEAR OR WS-CONTRACT-YEAR > MAX-CONTRACT-YEAR PERFORM LOG-DATE-ERROR MOVE "CONTRACT_DATE" TO LOG-FIELD-NAME MOVE LEGACY-CONTRACT-DATE TO LOG-OLD-VALUE MOVE MOD-CONTRACT-DATE TO LOG-NEW-VALUE MOVE "RANG" TO LOG-ERROR-CODE END-IF ELSE MOVE ZERO TO MOD-CONTRACT-DATE END-IF. VALIDATE-CONVERTED-RECORD. MOVE 'Y' TO CONVERSION-SUCCESSFUL *> Business rule validation IF MOD-BIRTH-DATE > ZERO AND MOD-HIRE-DATE > ZERO IF MOD-HIRE-DATE <= MOD-BIRTH-DATE MOVE 'N' TO CONVERSION-SUCCESSFUL PERFORM LOG-BUSINESS-RULE-ERROR END-IF END-IF *> Contract date should be after hire date IF MOD-CONTRACT-DATE > ZERO AND MOD-HIRE-DATE > ZERO IF MOD-CONTRACT-DATE < MOD-HIRE-DATE MOVE 'N' TO CONVERSION-SUCCESSFUL PERFORM LOG-BUSINESS-RULE-ERROR END-IF END-IF. GENERATE-MIGRATION-REPORT. MOVE "COMPLETED" TO MIGRATION-STATUS DISPLAY "=== Migration Report ===" DISPLAY "Total Records Processed: " TOTAL-RECORDS DISPLAY "Successfully Converted: " CONVERTED-RECORDS DISPLAY "Error Records: " ERROR-RECORDS IF TOTAL-RECORDS > ZERO COMPUTE WS-SUCCESS-RATE = (CONVERTED-RECORDS / TOTAL-RECORDS) * 100 DISPLAY "Success Rate: " WS-SUCCESS-RATE "%" END-IF DISPLAY "Migration Status: " MIGRATION-STATUS DISPLAY "Completion Time: " FUNCTION CURRENT-DATE.

Performance Optimization and Best Practices

CENTURY-DATE Optimization Guidelines:

  • Use consistent pivot years across your application ecosystem for predictable behavior
  • Cache CENTURY-DATE results when processing large batches with the same pivot year
  • Validate input dates before conversion to prevent invalid results and runtime errors
  • Document your windowing strategy comprehensively for maintenance and compliance audits
  • Implement comprehensive testing for century boundary conditions and edge cases
  • Consider using explicit four-digit years in new development to avoid ambiguity
  • Use domain-specific pivot years based on data characteristics and business rules
  • Monitor conversion accuracy through automated validation and business rule checking
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
*> Performance optimized CENTURY-DATE processing DATA DIVISION. WORKING-STORAGE SECTION. 01 PERFORMANCE-METRICS. 05 CONVERSION-COUNT PIC 9(8) VALUE ZERO. 05 CACHE-HITS PIC 9(8) VALUE ZERO. 05 CACHE-MISSES PIC 9(8) VALUE ZERO. 05 VALIDATION-ERRORS PIC 9(6) VALUE ZERO. 05 PROCESSING-TIME PIC 9(6)V99 VALUE ZERO. 01 CONVERSION-CACHE. 05 CACHE-SIZE PIC 9(4) VALUE 1000. 05 CACHE-ENTRIES OCCURS 1000 TIMES. 10 CE-INPUT PIC 9(6). 10 CE-PIVOT PIC 99. 10 CE-RESULT PIC 9(8). 10 CE-VALID PIC X VALUE 'N'. 10 CE-LAST-USED PIC 9(8). 01 BATCH-PROCESSING. 05 BATCH-SIZE PIC 9(6) VALUE 10000. 05 RECORDS-PROCESSED PIC 9(8) VALUE ZERO. 05 BATCH-NUMBER PIC 9(4) VALUE ZERO. PROCEDURE DIVISION. OPTIMIZED-CENTURY-DATE-PROCESSING. PERFORM INITIALIZE-PERFORMANCE-TRACKING PERFORM BATCH-CONVERT-DATES PERFORM DISPLAY-PERFORMANCE-METRICS. INITIALIZE-PERFORMANCE-TRACKING. MOVE ZERO TO CONVERSION-COUNT CACHE-HITS CACHE-MISSES VALIDATION-ERRORS MOVE FUNCTION CURRENT-DATE(9:8) TO WS-START-TIME *> Initialize cache PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > CACHE-SIZE MOVE 'N' TO CE-VALID(WS-I) MOVE ZERO TO CE-INPUT(WS-I) CE-RESULT(WS-I) CE-LAST-USED(WS-I) END-PERFORM. BATCH-CONVERT-DATES. PERFORM VARYING WS-RECORD-NUM FROM 1 BY 1 UNTIL WS-RECORD-NUM > BATCH-SIZE *> Read input date PERFORM READ-INPUT-DATE *> Validate before conversion PERFORM VALIDATE-INPUT-DATE IF INPUT-DATE-VALID PERFORM CACHED-CENTURY-DATE-CONVERSION ELSE ADD 1 TO VALIDATION-ERRORS END-IF ADD 1 TO RECORDS-PROCESSED *> Batch progress reporting IF FUNCTION MOD(RECORDS-PROCESSED, 1000) = ZERO PERFORM DISPLAY-BATCH-PROGRESS END-IF END-PERFORM. CACHED-CENTURY-DATE-CONVERSION. *> Check cache first PERFORM CHECK-CONVERSION-CACHE IF CACHE-HIT-FOUND ADD 1 TO CACHE-HITS MOVE CE-RESULT(WS-CACHE-INDEX) TO WS-OUTPUT-DATE MOVE RECORDS-PROCESSED TO CE-LAST-USED(WS-CACHE-INDEX) ELSE ADD 1 TO CACHE-MISSES COMPUTE WS-OUTPUT-DATE = FUNCTION CENTURY-DATE(WS-INPUT-DATE, WS-PIVOT-YEAR) PERFORM UPDATE-CONVERSION-CACHE END-IF ADD 1 TO CONVERSION-COUNT. CHECK-CONVERSION-CACHE. MOVE 'N' TO CACHE-HIT-FOUND PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > CACHE-SIZE IF CE-VALID(WS-I) = 'Y' AND CE-INPUT(WS-I) = WS-INPUT-DATE AND CE-PIVOT(WS-I) = WS-PIVOT-YEAR MOVE 'Y' TO CACHE-HIT-FOUND MOVE WS-I TO WS-CACHE-INDEX EXIT PERFORM END-IF END-PERFORM. UPDATE-CONVERSION-CACHE. *> Find empty slot or least recently used PERFORM FIND-CACHE-SLOT MOVE WS-INPUT-DATE TO CE-INPUT(WS-CACHE-SLOT) MOVE WS-PIVOT-YEAR TO CE-PIVOT(WS-CACHE-SLOT) MOVE WS-OUTPUT-DATE TO CE-RESULT(WS-CACHE-SLOT) MOVE 'Y' TO CE-VALID(WS-CACHE-SLOT) MOVE RECORDS-PROCESSED TO CE-LAST-USED(WS-CACHE-SLOT). FIND-CACHE-SLOT. *> Look for empty slot first PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > CACHE-SIZE IF CE-VALID(WS-I) = 'N' MOVE WS-I TO WS-CACHE-SLOT EXIT PERFORM END-IF END-PERFORM *> If no empty slot, find least recently used IF WS-I > CACHE-SIZE MOVE 1 TO WS-CACHE-SLOT MOVE CE-LAST-USED(1) TO WS-OLDEST-USE PERFORM VARYING WS-I FROM 2 BY 1 UNTIL WS-I > CACHE-SIZE IF CE-LAST-USED(WS-I) < WS-OLDEST-USE MOVE WS-I TO WS-CACHE-SLOT MOVE CE-LAST-USED(WS-I) TO WS-OLDEST-USE END-IF END-PERFORM END-IF. DISPLAY-PERFORMANCE-METRICS. MOVE FUNCTION CURRENT-DATE(9:8) TO WS-END-TIME COMPUTE PROCESSING-TIME = WS-END-TIME - WS-START-TIME DISPLAY "=== CENTURY-DATE Performance Report ===" DISPLAY "Total Conversions: " CONVERSION-COUNT DISPLAY "Cache Hits: " CACHE-HITS DISPLAY "Cache Misses: " CACHE-MISSES DISPLAY "Validation Errors: " VALIDATION-ERRORS DISPLAY "Processing Time: " PROCESSING-TIME " seconds" IF (CACHE-HITS + CACHE-MISSES) > ZERO COMPUTE WS-HIT-RATIO = (CACHE-HITS / (CACHE-HITS + CACHE-MISSES)) * 100 DISPLAY "Cache Hit Ratio: " WS-HIT-RATIO "%" END-IF IF PROCESSING-TIME > ZERO COMPUTE WS-THROUGHPUT = CONVERSION-COUNT / PROCESSING-TIME DISPLAY "Throughput: " WS-THROUGHPUT " conversions/second" END-IF.

Comprehensive FAQ

Q: How do I choose the right pivot year for CENTURY-DATE?

The pivot year choice depends on your data characteristics and business domain. For personnel records, use 25 (1925-2024) to handle most employee birth dates. For contracts and transactions, use 70 (1970-2069) or 80 (1980-2079). For historical data, consider using 00 to favor the 1900s. Always analyze your actual data distribution before choosing a pivot.

Q: Can CENTURY-DATE handle invalid dates like February 30th?

CENTURY-DATE will perform the mathematical conversion regardless of date validity. It doesn't validate whether the resulting date is a real calendar date. You should implement separate validation logic to check for invalid dates like February 30th, April 31st, or February 29th in non-leap years after conversion.

Q: What happens if I don't specify a pivot year?

When no pivot year is specified, CENTURY-DATE uses a system default (usually 50), meaning years 00-49 become 2000-2049 and years 50-99 become 1950-1999. However, relying on defaults can cause unexpected behavior when the system default changes, so it's best practice to always specify your pivot year explicitly.

Q: How does CENTURY-DATE compare to manual century logic?

CENTURY-DATE is more efficient and less error-prone than manual IF-THEN logic for century determination. It's a single function call versus multiple conditional statements, reducing code complexity and maintenance overhead. It also provides consistent behavior across different programmers and maintains readability.

Q: Can I use CENTURY-DATE for date arithmetic?

Yes, CENTURY-DATE output can be used with other COBOL date functions for arithmetic operations. You can subtract dates, calculate intervals, or use the result with INTEGER-OF-DATE for more complex calculations. The four-digit year format is compatible with standard COBOL date arithmetic functions.

Q: How should I handle century-date conversions in batch processing?

For batch processing, implement caching for repeated conversions, validate input dates before conversion, and use consistent pivot years throughout the batch. Consider processing in chunks and implementing progress reporting for large volumes. Also, log conversion errors and implement restart capability for long-running batch jobs.

Interactive Quiz

Test Your CENTURY-DATE Knowledge

1. What does CENTURY-DATE convert?

2. With a pivot year of 30, what century does year 25 belong to?

3. What's the best practice for choosing pivot years?

Answers: 1-B, 2-B, 3-B