Case Study 1: GlobalBank Transaction Date Processing and Statement Periods

Background

GlobalBank generates monthly statements for 3.2 million accounts. Accounts are assigned to one of 28 cycle groups (cycle days 1 through 28), meaning approximately 115,000 statements are generated each business day. Each statement must cover exactly one billing period, include all transactions within that period, and display accurate aging information for outstanding items.

The Problem

The legacy statement program contained a 200-line date calculation module written in the 1980s. It used 2-digit years (expanded during Y2K), hardcoded month lengths, and had known bugs: - Cycle day 29-31 caused abends for months with fewer days - February statements occasionally included March 1 transactions - Year-end boundary (December to January) failed intermittently

Maria Chen assigned Derek Washington to replace the entire date module with intrinsic function-based logic.

Solution Design

Derek's approach: 1. Statement period computation: Use INTEGER-OF-DATE and DATE-OF-INTEGER to compute start and end dates, with a days-in-month lookup table for cycle day adjustment 2. Transaction filtering: Compare transaction dates numerically against the period boundaries 3. Aging display: Compute days since each transaction using INTEGER-OF-DATE subtraction 4. Year-end handling: Intrinsic functions handle year boundaries automatically — no special-case code needed

Key Insight

The most important design decision was computing the last day of the previous month using the intrinsic functions rather than a lookup table:

*> Last day of previous month = day before the 1st
*> of current month
COMPUTE WS-PREV-MONTH-LAST =
    FUNCTION DATE-OF-INTEGER(
        FUNCTION INTEGER-OF-DATE(
            WS-CURRENT-MONTH-FIRST) - 1)

This single expression replaces 30 lines of IF/ELSE logic and automatically handles leap years, month lengths, and year boundaries.

Results

  • Code reduced from 200 lines to 45 lines
  • All three known bugs eliminated
  • Cycle day 29-31 handling added (previously unsupported)
  • Statement generation time unchanged (date computation is a negligible fraction)
  • Zero date-related production incidents in 18 months since deployment

Discussion Questions

  1. Why is it safer to compute the last day of a month using DATE-OF-INTEGER(first-of-next-month - 1) rather than using a days-in-month table?
  2. How should the system handle a transaction with a date outside the statement period boundaries?
  3. What happens if the batch runs past midnight during statement generation — how should the "current date" be determined?
  4. How would you add support for quarterly and annual statements using the same date module?