Menu ▾ ▴

#1294 Basic time format hhmmss.sss: the decimal separator is written to and required in the data

unclassified
open
nobody
None
5 - default
2026-11-04
2026-11-04
No

In a basic time format with fractional seconds, such as hhmmss.sss, the decimal separator is part of the format but not of the data, so 12:34:56.125 is 123456125. libcob puts the separator into the data: FORMATTED-TIME, FORMATTED-DATETIME and FORMATTED-CURRENT-DATE return one character too many, and SECONDS-FROM-FORMATTED-TIME and TEST-FORMATTED-DATETIME reject the correct value.

To reproduce

basfrac.cob (attached) formats 12:34:56.125 with hhmmss.sss and reads 123456125 back:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. BASFRAC.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-SECS PIC 9(5)V999 VALUE 45296.125.
       01 WS-NUM  PIC 9(5)V999 VALUE 0.
       01 WS-POS  PIC 99 VALUE 0.
       PROCEDURE DIVISION.
           DISPLAY "FT  [" FUNCTION FORMATTED-TIME
               ("hhmmss.sss" WS-SECS) "]"
           DISPLAY "LEN " FUNCTION LENGTH
               (FUNCTION FORMATTED-TIME ("hhmmss.sss" WS-SECS))
           COMPUTE WS-NUM = FUNCTION SECONDS-FROM-FORMATTED-TIME
               ("hhmmss.sss" "123456125")
           DISPLAY "SFT " WS-NUM
           COMPUTE WS-POS = FUNCTION TEST-FORMATTED-DATETIME
               ("hhmmss.sss" "123456125")
           DISPLAY "TST " WS-POS
           STOP RUN.
cobc -std=cobol2014 -x basfrac.cob && ./basfrac

What happens

3.2.0 and 3.3-dev r5751 both print

FT  [123456.125]
LEN 000000010
SFT 00000.000
TST 07

basfrac2.cob, attached, shows the same for the standard's example 1014278124Z (hhmmss.ssssZ), for a combined date and time format and for FORMATTED-CURRENT-DATE; only its extended-format control is right.

What should happen

basfrac should print:

FT  [123456125]
LEN 000000009
SFT 45296.125
TST 00

ISO/IEC 1989:2023 15.3.3.2: "The decimal separator does not appear in the data associated with a basic common time format with fractional seconds representation." The same rule is in the 2014 FCD, 15.3.1.2.1.2; 2002 has none of these functions.

ISO 8601 keeps the decimal sign in a basic time (hhmmss,ss, example 232050,5; ISO/WD 8601-1 of 2016-02-16, clause 4.2.2.4); ISO/IEC 1989 15.3.3.2 takes it out, and for these functions that rule controls.

Why it happens

In libcob/intrinsic.c, cob_valid_time_format and parse_time_format_string keep with_colons for basic and extended, but the separator code ignores it. add_decimal_digits always writes COB_MODULE_PTR->decimal_point, test_decimal_places always expects it, and seconds_from_formatted_time reads a basic fraction from offset 7, one past where it starts. The three cob_intr_formatted_* functions make the returned item as long as the format string, and cob_intr_seconds_from_formatted_time copies that many characters of argument-2 for a time format, whatever its size.

Proposed fix

The attached n10-formatted-time-basic-fraction.patch (against 3.3-dev r5751) makes add_decimal_digits write the separator and test_decimal_places expect it only for an extended format, and makes seconds_from_formatted_time read a basic fraction from offset 6. A new time_format_data_length gives the data length, used for the FORMATTED-* results and for how much of argument-2 SECONDS-FROM-FORMATTED-TIME copies for a time format. With the patch both programs print the expected output.

This changes values that existing programs and stored data may hold, in every dialect: for a basic format with fractional seconds the FORMATTED-* functions return one character less, and a value with the separator that an earlier release wrote, such as 123456.125 for hhmmss.sss, is now rejected (SECONDS-FROM-FORMATTED-TIME returns 0 with EC-ARGUMENT-FUNCTION, TEST-FORMATTED-DATETIME returns 7). An argument-2 shorter than its time format is now rejected with EC-ARGUMENT-FUNCTION where r5751 read past it. The patch adds a NEWS item under "Changes that potentially effect recompilation of existing programs"; it does not tie the change to a dialect option.

It adds test 1100 "FUNCTION FORMATTED-TIME basic fractional seconds" to run_functions.at, corrects five tests that expected the separator in basic data, and adds ChangeLog entries. make check: 1373 expected, 9 skipped, 0 failed (1372 unpatched); the new test fails without the patch.

  • patches #19: the original FORMATTED-DATE, FORMATTED-TIME and FORMATTED-DATETIME implementation, written from the 2010 FCD.
  • bugs #1276: national format arguments; its case 4 names three functions this patch also changes.
  • A result scale that SECONDS-FROM-FORMATTED-TIME keeps from an earlier call is reported separately; nothing here depends on its fix.

Details

GnuCOBOL 3.2.0 (Ubuntu gnucobol3 3.2-4build1) and 3.3-dev r5751 (CI snapshot 3.3-dev.138 of 2026-10-29), x86_64 Linux, both programs run on both on 2026-11-04.

3 Attachments

Discussion


Log in to post a comment.