Skip to content

Instantly share code, notes, and snippets.

@hitode909
Last active January 22, 2026 05:29
Show Gist options
  • Select an option

  • Save hitode909/40901b50e1ffe54a7c8ca232185756e5 to your computer and use it in GitHub Desktop.

Select an option

Save hitode909/40901b50e1ffe54a7c8ca232185756e5 to your computer and use it in GitHub Desktop.
DateTime::Format::W3CDTF Nanosecond Validation Bug

DateTime::Format::W3CDTF Nanosecond Validation Bug

DateTime::Format::W3CDTF fails to parse datetime strings containing fractional seconds when used with Specio 0.50+.

DateTime 1.66 requires Specio 0.50+, which has stricter integer validation. This exposes a bug in DateTime::Format::W3CDTF that was previously hidden.

How to Run

# DateTime 1.65 + Specio 0.49 (works)
docker build -f Dockerfile.1.65 -t datetime-bug:1.65 .
docker run --rm datetime-bug:1.65

# DateTime 1.66 + Specio 0.50+ (fails)
docker build -f Dockerfile.1.66 -t datetime-bug:1.66 .
docker run --rm datetime-bug:1.66

Results

DateTime 1.65 + Specio 0.49 (Success)

DateTime version: 1.65
DateTime::Format::W3CDTF version: 0.08

Parsing: 2026-02-20T14:59:45.268Z
Success: 2026-02-20T14:59:45

DateTime 1.66 + Specio 0.50+ (Failure)

DateTime version: 1.66
DateTime::Format::W3CDTF version: 0.08

Parsing: 2026-02-20T14:59:45.268Z
Error: Validation failed for type named Nanosecond ... with value 268000000

Root Cause

  • Specio 0.50 introduced stricter validation for integer types (PositiveOrZeroInt)
  • DateTime::Format::W3CDTF passes nanoseconds as a floating-point number instead of an integer
  • DateTime 1.66 requires Specio 0.50+, so users upgrading to DateTime 1.66 will encounter this bug

Problem Location

DateTime::Format::W3CDTF line 101:

# Current code (produces float)
$p{nanosecond} = $p{fraction} * 1_000_000_000;

# Fix (produces integer)
use POSIX qw(floor);
$p{nanosecond} = floor($p{fraction} * 1_000_000_000);

Related

FROM perl:5.38
# Use Specio 0.49 (Specio 0.50+ has stricter integer validation)
RUN cpanm --notest Specio@0.49 && cpanm --notest DateTime@1.65 DateTime::Format::W3CDTF
WORKDIR /app
COPY test.pl .
CMD ["perl", "test.pl"]
FROM perl:5.38
# DateTime 1.66 requires Specio 0.50+ (stricter integer validation)
RUN cpanm --notest DateTime@1.66 DateTime::Format::W3CDTF
WORKDIR /app
COPY test.pl .
CMD ["perl", "test.pl"]
#!/usr/bin/env perl
use strict;
use warnings;
use DateTime;
use DateTime::Format::W3CDTF;
print "DateTime version: $DateTime::VERSION\n";
print "DateTime::Format::W3CDTF version: $DateTime::Format::W3CDTF::VERSION\n";
print "\n";
my $input = '2026-02-20T14:59:45.268Z';
print "Parsing: $input\n";
eval {
my $dt = DateTime::Format::W3CDTF->parse_datetime($input);
print "Success: $dt\n";
};
if ($@) {
print "Error: $@\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment