MainframeMaster
MainframeMaster

COBOL Tutorial

Progress0 of 0 lessons

COBOL Date Time Handling

Date and time handling in COBOL involves obtaining current date/time, formatting dates for display, performing date calculations, validating dates, and working with various date formats. COBOL provides functions like CURRENT-DATE and ACCEPT FROM DATE/TIME to get system date and time, and you use string manipulation and arithmetic to format, calculate, and validate dates. Effective date/time handling is essential for business applications that need timestamps, age calculations, date-based reporting, and temporal data processing.

Getting Current Date and Time

Using CURRENT-DATE Function

CURRENT-DATE is the most comprehensive way to get current date and time:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
WORKING-STORAGE SECTION. 01 CURRENT-DATE-TIME PIC X(21). PROCEDURE DIVISION. GET-CURRENT-DATE-TIME. MOVE FUNCTION CURRENT-DATE TO CURRENT-DATE-TIME *> CURRENT-DATE returns: YYYYMMDDHHMMSSssssss+HHMM *> Example: "20240115143045234567+0500" *> 2024-01-15 14:30:45.234567 +05:00 DISPLAY 'Current date/time: ' CURRENT-DATE-TIME STOP RUN.

CURRENT-DATE format breakdown:

  • Positions 1-4: Year (YYYY)
  • Positions 5-6: Month (MM, 01-12)
  • Positions 7-8: Day (DD, 01-31)
  • Positions 9-10: Hour (HH, 00-23)
  • Positions 11-12: Minute (MM, 00-59)
  • Positions 13-14: Second (SS, 00-59)
  • Positions 15-20: Microseconds (ssssss)
  • Positions 21: Sign (+ or -)
  • Positions 22-25: Timezone offset (HHMM)

Using ACCEPT FROM DATE

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
WORKING-STORAGE SECTION. 01 CURRENT-DATE-YYYYMMDD PIC 9(8). 01 CURRENT-DATE-YYMMDD PIC 9(6). PROCEDURE DIVISION. GET-DATE-ONLY. *> Get date in YYYYMMDD format ACCEPT CURRENT-DATE-YYYYMMDD FROM DATE YYYYMMDD *> Result: 20240115 *> Get date in YYMMDD format (2-digit year) ACCEPT CURRENT-DATE-YYMMDD FROM DATE YYMMDD *> Result: 240115 DISPLAY 'Date (YYYYMMDD): ' CURRENT-DATE-YYYYMMDD DISPLAY 'Date (YYMMDD): ' CURRENT-DATE-YYMMDD STOP RUN.

Using ACCEPT FROM TIME

cobol
1
2
3
4
5
6
7
8
9
10
11
12
WORKING-STORAGE SECTION. 01 CURRENT-TIME PIC 9(8). PROCEDURE DIVISION. GET-TIME-ONLY. *> Get time in HHMMSS format ACCEPT CURRENT-TIME FROM TIME *> Result: 143045 (2:30:45 PM) DISPLAY 'Current time: ' CURRENT-TIME STOP RUN.

Extracting Date Components

Use reference modification to extract date parts:

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
WORKING-STORAGE SECTION. 01 CURRENT-DATE-TIME PIC X(21). 01 DATE-YYYYMMDD PIC 9(8). 01 YEAR PIC 9(4). 01 MONTH PIC 9(2). 01 DAY PIC 9(2). 01 HOUR PIC 9(2). 01 MINUTE PIC 9(2). 01 SECOND PIC 9(2). PROCEDURE DIVISION. EXTRACT-COMPONENTS. MOVE FUNCTION CURRENT-DATE TO CURRENT-DATE-TIME *> Extract date portion (YYYYMMDD) MOVE CURRENT-DATE-TIME(1:8) TO DATE-YYYYMMDD *> Extract individual components MOVE CURRENT-DATE-TIME(1:4) TO YEAR *> 2024 MOVE CURRENT-DATE-TIME(5:2) TO MONTH *> 01 MOVE CURRENT-DATE-TIME(7:2) TO DAY *> 15 MOVE CURRENT-DATE-TIME(9:2) TO HOUR *> 14 MOVE CURRENT-DATE-TIME(11:2) TO MINUTE *> 30 MOVE CURRENT-DATE-TIME(13:2) TO SECOND *> 45 DISPLAY 'Year: ' YEAR DISPLAY 'Month: ' MONTH DISPLAY 'Day: ' DAY DISPLAY 'Time: ' HOUR ':' MINUTE ':' SECOND STOP RUN.

Formatting Dates

Format dates for display using STRING or reference modification:

Format as MM/DD/YYYY

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
WORKING-STORAGE SECTION. 01 DATE-YYYYMMDD PIC 9(8). 01 FORMATTED-DATE PIC X(10). 01 YEAR PIC 9(4). 01 MONTH PIC 9(2). 01 DAY PIC 9(2). PROCEDURE DIVISION. FORMAT-US-STYLE. ACCEPT DATE-YYYYMMDD FROM DATE YYYYMMDD *> Extract components MOVE DATE-YYYYMMDD(1:4) TO YEAR MOVE DATE-YYYYMMDD(5:2) TO MONTH MOVE DATE-YYYYMMDD(7:2) TO DAY *> Build MM/DD/YYYY format STRING MONTH DELIMITED BY SIZE '/' DELIMITED BY SIZE DAY DELIMITED BY SIZE '/' DELIMITED BY SIZE YEAR DELIMITED BY SIZE INTO FORMATTED-DATE END-STRING DISPLAY 'Formatted date: ' FORMATTED-DATE *> Output: 01/15/2024 STOP RUN.

Format as DD-MM-YYYY

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PROCEDURE DIVISION. FORMAT-EUROPEAN-STYLE. ACCEPT DATE-YYYYMMDD FROM DATE YYYYMMDD MOVE DATE-YYYYMMDD(1:4) TO YEAR MOVE DATE-YYYYMMDD(5:2) TO MONTH MOVE DATE-YYYYMMDD(7:2) TO DAY *> Build DD-MM-YYYY format STRING DAY DELIMITED BY SIZE '-' DELIMITED BY SIZE MONTH DELIMITED BY SIZE '-' DELIMITED BY SIZE YEAR DELIMITED BY SIZE INTO FORMATTED-DATE END-STRING DISPLAY 'Formatted date: ' FORMATTED-DATE *> Output: 15-01-2024 STOP RUN.

Date Validation

Validate dates to ensure they're correct:

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
WORKING-STORAGE SECTION. 01 INPUT-DATE PIC 9(8). 01 YEAR PIC 9(4). 01 MONTH PIC 9(2). 01 DAY PIC 9(2). 01 VALID-DATE-FLAG PIC X VALUE 'Y'. 88 VALID-DATE VALUE 'Y'. 88 INVALID-DATE VALUE 'N'. PROCEDURE DIVISION. VALIDATE-DATE. *> Assume INPUT-DATE contains YYYYMMDD format MOVE INPUT-DATE(1:4) TO YEAR MOVE INPUT-DATE(5:2) TO MONTH MOVE INPUT-DATE(7:2) TO DAY *> Check if date is numeric IF INPUT-DATE IS NOT NUMERIC SET INVALID-DATE TO TRUE ELSE *> Check month range IF MONTH < 1 OR MONTH > 12 SET INVALID-DATE TO TRUE ELSE *> Check day range based on month PERFORM CHECK-DAY-VALIDITY END-IF END-IF IF VALID-DATE DISPLAY 'Date is valid' ELSE DISPLAY 'ERROR: Invalid date' END-IF STOP RUN. CHECK-DAY-VALIDITY. *> Check day based on month EVALUATE MONTH WHEN 1 3 5 7 8 10 12 *> Months with 31 days IF DAY < 1 OR DAY > 31 SET INVALID-DATE TO TRUE END-IF WHEN 4 6 9 11 *> Months with 30 days IF DAY < 1 OR DAY > 30 SET INVALID-DATE TO TRUE END-IF WHEN 2 *> February - check for leap year PERFORM CHECK-FEBRUARY-DAY END-EVALUATE. CHECK-FEBRUARY-DAY. IF FUNCTION MOD(YEAR, 4) = 0 AND FUNCTION MOD(YEAR, 100) NOT = 0 OR FUNCTION MOD(YEAR, 400) = 0 *> Leap year - allow day 29 IF DAY < 1 OR DAY > 29 SET INVALID-DATE TO TRUE END-IF ELSE *> Not leap year - max day 28 IF DAY < 1 OR DAY > 28 SET INVALID-DATE TO TRUE END-IF END-IF.

Leap Year Handling

A year is a leap year if it's divisible by 4, except century years which must be divisible by 400:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WORKING-STORAGE SECTION. 01 YEAR PIC 9(4). 01 IS-LEAP-YEAR-FLAG PIC X. 88 IS-LEAP-YEAR VALUE 'Y'. 88 NOT-LEAP-YEAR VALUE 'N'. PROCEDURE DIVISION. CHECK-LEAP-YEAR. *> Leap year if: (divisible by 4 AND not century) *> OR (divisible by 400) IF (FUNCTION MOD(YEAR, 4) = 0 AND FUNCTION MOD(YEAR, 100) NOT = 0) OR FUNCTION MOD(YEAR, 400) = 0 SET IS-LEAP-YEAR TO TRUE DISPLAY YEAR ' is a leap year' ELSE SET NOT-LEAP-YEAR TO TRUE DISPLAY YEAR ' is not a leap year' END-IF STOP RUN.

Date Calculations

Adding Days to a Date

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
WORKING-STORAGE SECTION. 01 START-DATE PIC 9(8) VALUE 20240115. 01 DAYS-TO-ADD PIC 9(4) VALUE 30. 01 RESULT-DATE PIC 9(8). 01 YEAR PIC 9(4). 01 MONTH PIC 9(2). 01 DAY PIC 9(2). PROCEDURE DIVISION. ADD-DAYS. *> Simple approach: add days and handle overflow *> Note: This is simplified - full implementation *> needs to handle month/year boundaries MOVE START-DATE(1:4) TO YEAR MOVE START-DATE(5:2) TO MONTH MOVE START-DATE(7:2) TO DAY ADD DAYS-TO-ADD TO DAY *> Handle day overflow (simplified) *> Full implementation would check month lengths *> and handle year boundaries *> Build result date COMPUTE RESULT-DATE = YEAR * 10000 + MONTH * 100 + DAY DISPLAY 'Start date: ' START-DATE DISPLAY 'Days to add: ' DAYS-TO-ADD DISPLAY 'Result date: ' RESULT-DATE STOP RUN.

Common Date Formats

Common COBOL Date Formats
FormatExampleCommon Use
YYYYMMDD20240115Most common, sortable, compact
MM/DD/YYYY01/15/2024US display format
DD/MM/YYYY15/01/2024European display format
YYYY-MM-DD2024-01-15ISO-like format with separators
YYMMDD240115Legacy 2-digit year format

Best Practices

Follow these best practices:

  • Use YYYYMMDD: Most reliable format for storage and sorting
  • Always validate: Check dates before using in calculations
  • Handle leap years: Account for February 29 in leap years
  • Document formats: Clearly document date format assumptions
  • Use functions: Prefer CURRENT-DATE and ACCEPT FROM DATE over manual date entry
  • Test edge cases: Test month boundaries, year boundaries, leap years

Explain Like I'm 5: Date Time Handling

Think of date/time handling like reading a clock and calendar:

  • CURRENT-DATE is like asking "what time and date is it right now?"
  • Extracting components is like reading just the hour, or just the day
  • Formatting is like writing the date in different ways (1/15/2024 vs 15-01-2024)
  • Validation is like checking if a date makes sense (no February 30th!)
  • Leap years are like the special year that has an extra day in February

Just like you can read a clock to get the time, COBOL can get the current date/time and work with it!

Test Your Knowledge

1. What does CURRENT-DATE return?

  • Just the date
  • A 21-character string with date, time, and timezone
  • Just the time
  • A numeric value

2. How do you extract the year from a YYYYMMDD date?

  • DATE(1:4)
  • DATE(1:2)
  • DATE(5:4)
  • DATE(7:2)

3. What is the most common date format in mainframe COBOL?

  • MM/DD/YYYY
  • YYYYMMDD
  • DD-MM-YYYY
  • YYYY-MM-DD

4. How do you get just the current date (not time)?

  • Use CURRENT-DATE and extract first 8 characters
  • Use ACCEPT FROM DATE YYYYMMDD
  • Both of the above
  • Use a special DATE function

5. What makes a year a leap year?

  • Divisible by 4
  • Divisible by 4, except centuries which must be divisible by 400
  • Divisible by 100
  • Every 4 years regardless

6. How do you format a date as MM/DD/YYYY?

  • Use a special FORMAT function
  • Extract components and use STRING to build the format
  • COBOL cannot format dates
  • Use PICTURE editing

Related Concepts

Related Pages