Project

General

Profile

Actions

Feature #21307

open

A way to strictly validate time input

Added by mame (Yusuke Endoh) 3 days ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:121815]

Description

Currently, Time.new sometimes silently rolls over invalid date/time values:

Time.new(2025, 2, 29, 0, 0, 0, "+00:00") #=> 2025-03-01 00:00:00
Time.new(2025, 1, 1, 24, 0, 0, "+00:00") #=> 2025-01-02 00:00:00
Time.new(2025, 1, 1, 0, 0, 60, "+00:00") #=> 2025-01-01 00:01:00

But in other cases, it raises ArgumentError:

Time.new(2025, 1, 32, 0, 0, 0, "+00:00") #=> argument out of range (ArgumentError)
Time.new(2025, 1, 1, 24, 0, 1, "+00:00") #=> sec out of range (ArgumentError)
Time.new(2025, 1, 1, 25, 0, 0, "+00:00") #=> hour out of range (ArgumentError)
Time.new(2025, 1, 1, 0, 60, 0, "+00:00") #=> min out of range (ArgumentError)
Time.new(2025, 1, 1, 0, 0, 61, "+00:00") #=> sec out of range (ArgumentError)

Is this inconsistency intentional? While automatic rollover can be useful, the current behavior feels unpredictable.


If this is by design, I would like to propose a strict version, e.g. Time.strict_new, that raises an error for any invalid value:

Time.strict_new(2025, 2, 29, 0, 0, 0, "+00:00") #=> ArgumentError

Right now, the only workaround is to compare the input with the resulting object, which is clunky:

def time_strict_new(year, mon, day, hour, min, sec, zone)
  r = Time.strict_new(year, mon, day, hour, min, sec, zone)
  raise ArgumentError if r.year != year
  raise ArgumentError if r.mon != mon
  raise ArgumentError if r.day != day
  raise ArgumentError if r.hour != hour
  raise ArgumentError if r.min != min
  raise ArgumentError if r.sec != sec
  r
end

In my case, I'm writing a TOML parser and need to reject invalid datetimes like 2100-02-29T15:15:15Z. The rollover behavior gets in the way.

No data to display

Actions

Also available in: Atom PDF

Like0