Clarion Code Comparison: ExtractDate v32
Original vs GCR Version
MAP Section (Declarations)
Original:
ValidateNumericDate(STRING pDateStr, *LONG pMonth, *LONG pDay, *LONG pYear),BYTE
ValidateISODate(STRING pDateStr, *LONG pYear, *LONG pMonth, *LONG pDay),BYTE
IsValidDayForMonth(LONG pDay, LONG pMonth, LONG pYear),BYTE
GCR:
ValidateNumericDate(STRING pDateStr),BYTE
ValidateISODate(STRING pDateStr),BYTE
IsValidDate(LONG pDay, LONG pMonth, LONG pYear),BYTE
Changes: Validation procedures no longer return extracted values via reference parameters; instead they only validate and return TRUE/FALSE. The function name IsValidDayForMonth was renamed to IsValidDate and consolidated.
ExtractDate PROCEDURE
No differences - Identical in both versions.
ExtractNumericDate PROCEDURE
Original: Uses traditional variable declaration and string concatenation with CLIP()
GCR: Major refactoring with significant performance improvements:
- Variable declarations simplified with AUTO keyword
- Removed unused variables (
Result, Pos, DateStart, InDate, Month, Day, Year)
- Changed loop logic to use
size(pText) + 1 to handle end-of-string
- Replaced string concatenation with direct character assignment:
DateStr[DateLen] = Char
- String length tracking with
DateLen instead of CLIP() operations
- Direct substring extraction:
DateStr[1 : DateLen] instead of repeated CLIP operations
- Simplified validation call - only passes date string, no output parameters
ValidateNumericDate PROCEDURE
Major refactoring from validation-only to integrated parsing:
Original:
- Extracts month, day, year as strings
- Validates NUMERIC() for each part
- Checks ranges and validates day for month
- Returns values via reference parameters
- Multiple CLIP() and SUB() operations
GCR:
- Direct string slicing without intermediate string variables
- Extracts Year first and validates immediately
- Extracts Month and Day using direct substring indexing
- Calls single
IsValidDate() function instead of separate validations
- Removed explicit numeric validation (implicit in direct conversion)
- Cleaner, more direct logic flow
ExtractISODate PROCEDURE
Original: Complex nested IF statements for format checking
GCR: Significant simplification:
- Removed
DashCount variable tracking
- Loop changed to
size(pText) + 1 pattern
- Direct string length tracking with
DateLen
- Character assignment instead of concatenation:
DateStr[DateLen] = Char
- Simplified format validation logic - just checks digit count and validates
- Removed separate handling of yyyymmdd vs yyyy-mm-dd at validation stage
- Single validation call with cleaner logic
ValidateISODate PROCEDURE
Major refactoring:
Original:
- Checks for dashes to determine format
- Extracts substrings into intermediate STRING variables
- Validates each part is NUMERIC()
- Separate day/month validation loops
- Calls
IsValidDayForMonth()
GCR:
- Uses CASE statement on string size (8 or 10 characters)
- Direct substring conversion to LONG values
- Dash position validation for 10-char format
- Single call to
IsValidDate()
- More compact and efficient
ExtractTextDate PROCEDURE
Significant refactoring:
Original:
- Manual punctuation replacement loop
- Token building with traditional string concatenation
- Separate array
Tokens and iteration logic
GCR:
- Token building integrated into main loop with direct character assignment
- Added
MonthTokLen array to track token lengths
- Removed explicit punctuation replacement (handled in CASE statement)
- Loop extended to
SIZE(pText) + 1 for consistent end-of-string handling
- Simplified month lookup with direct numeric range check first
- Changed validation to call
IsValidDate() directly
- Token length preservation for accurate formatting
IsValidDayForMonth / IsValidDate PROCEDURE
Complete rewrite:
Original:
- CASE statement iterating through all 12 months
- Separate handling for leap year
- Explicit DaysInMonth assignment for each case
- Long, repetitive CASE structure
GCR:
- New approach using STRING overlay with comma-separated day counts
DaysInMonth[pMonth] array overlay on STRING data
- Direct array lookup instead of CASE statement
- Simplified leap year check inline for February
- Much more compact and efficient
IsLeapYear PROCEDURE
No differences - Identical in both versions.
GetMonthNumber PROCEDURE
Minor changes:
Original:
Month variable declared as STRING(20)
- Separate UPPER() and CLIP() operations
Result explicitly initialized/returned
GCR:
Result declared with AUTO keyword
- UPPER() called directly in CASE statement
- Removed intermediate
Month variable
- More concise code
Summary of Overall Changes
Architecture Changes:
- Eliminated reference parameters from validation functions (parameters become return values via direct extraction)
- Renamed
IsValidDayForMonth() to IsValidDate() and completely rewrote it
- Shifted from building validated results in MAP procedures to direct parsing in validation routines
Performance Improvements:
- Replaced string concatenation with direct character/substring assignment
- Eliminated excessive CLIP() operations
- Changed from LOOP scanning with tracking to indexed string slicing
- Removed intermediate STRING variables
- Used AUTO keyword for better variable initialization
Code Quality:
- More concise and readable code
- Consistent loop pattern:
LOOP i = 1 TO size(pText) + 1
- Consolidated validation logic
- Better separation of concerns
- Reduced variable count and complexity
Specific Technical Optimizations:
- Direct byte-level string indexing instead of substring extraction and CLIP()
- LENGTH tracking variable instead of repeated CLIP(pText)
- OVERLAY technique for day-in-month validation instead of CASE statement
- Direct LONG type conversion from string slices
- Consistent AUTO keyword usage for variables