ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:121815] [Ruby Feature#21307] A way to strictly validate time input
@ 2025-05-03 18:17 mame (Yusuke Endoh) via ruby-core
  2025-05-09  3:30 ` [ruby-core:121925] " mame (Yusuke Endoh) via ruby-core
  2025-05-09  3:31 ` [ruby-core:121926] " mame (Yusuke Endoh) via ruby-core
  0 siblings, 2 replies; 3+ messages in thread
From: mame (Yusuke Endoh) via ruby-core @ 2025-05-03 18:17 UTC (permalink / raw)
  To: ruby-core; +Cc: mame (Yusuke Endoh)

Issue #21307 has been reported by mame (Yusuke Endoh).

----------------------------------------
Feature #21307: A way to strictly validate time input
https://bugs.ruby-lang.org/issues/21307

* Author: mame (Yusuke Endoh)
* Status: Open
----------------------------------------
Currently, `Time.new` sometimes silently rolls over invalid date/time values:

```ruby
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`:

```ruby
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:

```ruby
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:

```ruby
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.




-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ruby-core:121925] [Ruby Feature#21307] A way to strictly validate time input
  2025-05-03 18:17 [ruby-core:121815] [Ruby Feature#21307] A way to strictly validate time input mame (Yusuke Endoh) via ruby-core
@ 2025-05-09  3:30 ` mame (Yusuke Endoh) via ruby-core
  2025-05-09  3:31 ` [ruby-core:121926] " mame (Yusuke Endoh) via ruby-core
  1 sibling, 0 replies; 3+ messages in thread
From: mame (Yusuke Endoh) via ruby-core @ 2025-05-09  3:30 UTC (permalink / raw)
  To: ruby-core; +Cc: mame (Yusuke Endoh)

Issue #21307 has been updated by mame (Yusuke Endoh).


Discussed at the dev meeting. This proposal was accepted as `struct: true` keyword argument, like

```ruby
Time.new(2025, 2, 29, 0, 0, 0, "+00:00", strict: true) #=> ArgumentError
```

----------------------------------------
Feature #21307: A way to strictly validate time input
https://bugs.ruby-lang.org/issues/21307#change-113033

* Author: mame (Yusuke Endoh)
* Status: Open
----------------------------------------
Currently, `Time.new` sometimes silently rolls over invalid date/time values:

```ruby
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`:

```ruby
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:

```ruby
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:

```ruby
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.




-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ruby-core:121926] [Ruby Feature#21307] A way to strictly validate time input
  2025-05-03 18:17 [ruby-core:121815] [Ruby Feature#21307] A way to strictly validate time input mame (Yusuke Endoh) via ruby-core
  2025-05-09  3:30 ` [ruby-core:121925] " mame (Yusuke Endoh) via ruby-core
@ 2025-05-09  3:31 ` mame (Yusuke Endoh) via ruby-core
  1 sibling, 0 replies; 3+ messages in thread
From: mame (Yusuke Endoh) via ruby-core @ 2025-05-09  3:31 UTC (permalink / raw)
  To: ruby-core; +Cc: mame (Yusuke Endoh)

Issue #21307 has been updated by mame (Yusuke Endoh).

Status changed from Open to Assigned
Assignee set to mame (Yusuke Endoh)

----------------------------------------
Feature #21307: A way to strictly validate time input
https://bugs.ruby-lang.org/issues/21307#change-113034

* Author: mame (Yusuke Endoh)
* Status: Assigned
* Assignee: mame (Yusuke Endoh)
----------------------------------------
Currently, `Time.new` sometimes silently rolls over invalid date/time values:

```ruby
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`:

```ruby
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:

```ruby
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:

```ruby
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.




-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-05-09  3:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-05-03 18:17 [ruby-core:121815] [Ruby Feature#21307] A way to strictly validate time input mame (Yusuke Endoh) via ruby-core
2025-05-09  3:30 ` [ruby-core:121925] " mame (Yusuke Endoh) via ruby-core
2025-05-09  3:31 ` [ruby-core:121926] " mame (Yusuke Endoh) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).