Skip to content

Discrepancy in behavior between fractional second parsing between std::chrono::parse and scnlib #139

Description

@lenard-mosys

Observed behavior

consider the following:

#include <chrono>
#include <sstream>
#include <iostream>

#include <scn/scan.h>
#include <scn/chrono.h>

int main() {
    const auto datetime = std::string_view("2025-02-05T16:00:01.010101");
    std::chrono::sys_time<std::chrono::nanoseconds> tp;
    auto is = std::istringstream(std::string(datetime));
    is >> std::chrono::parse("%Y-%m-%dT%H:%M:%S", tp);
    if (is.fail()) { return 1; }
    std::cout << tp.time_since_epoch().count() << std::endl;

    auto result = scn::scan<std::chrono::system_clock::time_point>(
        datetime, "{:%Y-%m-%dT%H:%M:%S}");
    if (!result) { return 2; }
    std::cout << result->value().time_since_epoch().count() << std::endl;

    return 0;
}

This program outputs:

1738771201010101000
1738771201000000000

https://godbolt.org/z/vPfxP9bvG

Here std::chrono::parse and scn::scan use the same chrono format specifier for the datetime, but scnlib parses up to the decimal point, and std::chrono::parse parses up to the end of the input string.

Otherwise scn::scan can parse datetimes fine, including the fractional seconds if they include some terminator, like "2025-02-05T16:00:01.010101Z" with the format string %Y-%m-%dT%H:%M:%SZ.

It looks like the difference is that std::chrono::parse eagerly parses, while scnlib lazily.

Expected behavior

  1. std::chrono::parse and scnlib::scan to behave consistently when parsing date and time.
  2. Overall eager seems to be preferable in this case, regardless of what std::chrono::parse is doing.

Notes

Changing this possibly breaks existing user code. As a compromise a distinct eager seconds format specifier could be added (if it doesn't exist already, I didn't look too hard), and a change in behavior could be considered for %S in a major version bump.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions