Project

General

Profile

Actions

Feature #21972

open

Add Date.birthday and Date.age to track Ruby's milestones

Feature #21972: Add Date.birthday and Date.age to track Ruby's milestones
2

Added by jinroq (Jinroq SAITOH) 1 day ago. Updated about 12 hours ago.

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

Description

Since its inception in 1993, Ruby has grown beyond a mere programming language to become a rich culture beloved by developers worldwide. However, the standard date library surprisingly lacks a formal interface to commemorate Ruby's own historical milestones.

The fact that developers cannot programmatically reference Ruby’s heritage is a missed opportunity to foster affection and respect for the language's identity. To rectify this historical oversight, I propose adding the following methods to reference Ruby's key anniversaries and calculate the elapsed years.

New Features

  • Date.birthday(version = nil)
    Returns the "birthday" of significant moments in Ruby's history.

    • nil (default): 1993-02-24 (The day the name "Ruby" was decided).
    • 0.95: 1995-12-21 (The first public release date).
    • 1.0: 1996-12-25 (The first stable release date).
  • Date.age(version = nil)
    Calculates the current age (in full years) based on today's date and the specified milestone.

    • Date.age: Years since the name "Ruby" was born.
    • Date.age(0.95): Years since Ruby was first introduced to the public as OSS.
    • Date.age(1.0): Years since Ruby began its journey as a stable language.

Usage Example

# Check the "age" of each edition
puts "Name age: #{Date.age}"       # => 33 (as of 2026)
puts "OSS age:  #{Date.age(0.95)}" # => 30
puts "Stable:   #{Date.age(1.0)}"  # => 29

# Perform a special action on a specific anniversary
if Date.today == Date.birthday(1.0)
  celebrate_stable_anniversary!
end

Implementation and Testing

The attached patch (birthday_and_age.patch) includes the implementation of these methods along with a rigorous test suite (test/date/test_date_birthday.rb).
The tests cover argument dispatching, ArgumentError for invalid inputs, and edge cases for age calculation (e.g., boundaries before and after the actual birthday), ensuring production-level quality.

Equipping Ruby with the intelligence to reflect upon its own origins is a vital step toward the next 30 or 40 years of its evolution.

(Note: This proposal was submitted on a special day that encourages looking at our history with both deep respect and a touch of creative imagination, as is traditional for such a significant date in the calendar.)


Files

birthday_and_age.patch (8.08 KB) birthday_and_age.patch jinroq (Jinroq SAITOH), 03/31/2026 02:38 PM

Updated by ufuk (Ufuk Kayserilioglu) 1 day ago 1Actions #1 [ruby-core:125158]

I think these methods should live on the new Ruby module as Ruby.birthday and Ruby.age instead:

puts "Today: #{Date.today}"       # => Today: 2026-04-01

# Check the "age" of Ruby
puts "Age: #{Ruby.age}"           # => 33

# Perform a special action on a specific anniversary
puts "Birthday: #{Ruby.birthday}" # => Birthday: 1993-02-24

Updated by shugo (Shugo Maeda) about 18 hours ago Actions #2 [ruby-core:125162]

Under current Japanese law, a person's age increases at midnight on the day before their birthday. However, it might be better to use the traditional 'Kazeidoshi' (East Asian age reckoning) system, as its logic is much simpler.

Updated by jinroq (Jinroq SAITOH) about 17 hours ago Actions #3 [ruby-core:125165]

ufuk (Ufuk Kayserilioglu) wrote in #note-1:

I think these methods should live on the new Ruby module as Ruby.birthday and Ruby.age instead:

puts "Today: #{Date.today}"       # => Today: 2026-04-01

# Check the "age" of Ruby
puts "Age: #{Ruby.age}"           # => 33

# Perform a special action on a specific anniversary
puts "Birthday: #{Ruby.birthday}" # => Birthday: 1993-02-24

That's a great insight! Moving these to a Ruby module makes the intent much clearer and keeps the Date class clean.

One thing to consider: Should Ruby.birthday still return a Date object? If so, we'll need to ensure the Ruby module plays nice with the date library's loading behavior.

What do you think about providing these under Ruby but keeping the implementation within date library for now to avoid core dependency issues?

Updated by jinroq (Jinroq SAITOH) about 16 hours ago Actions #4 [ruby-core:125166]

shugo (Shugo Maeda) wrote in #note-2:

Under current Japanese law, a person's age increases at midnight on the day before their birthday. However, it might be better to use the traditional 'Kazeidoshi' (East Asian age reckoning) system, as its logic is much simpler.

Is “Kazeidoshi” the same as ‘Kazoedoshi’? For the purposes of this discussion, I will refer to it as “Kazoedoshi.”

That's a fascinating point about Japanese law. In keeping with Ruby's origins, I agree that supporting 'Kazoedoshi' (East Asian age reckoning) would be a culturally rich addition.

The simplicity of (current_year - birth_year) + 1 is indeed very 'Ruby-like' in its elegance. I’ll update the proposal to include a kazoedoshi: true keyword argument, allowing users to choose between legal precision and traditional simplicity.

# Compare legal age (default) and traditional age (Kazoedoshi)
# Assuming today is 2026-04-01:

# 1. The name "Ruby" (1993-02-24)
puts "Name age (Legal): #{Date.age}"                         # => 33
puts "Name age (Kazoedoshi): #{Date.age(kazoedoshi: true)}"  # => 34

# 2. First Stable Release (1996-12-25)
# Note: In Kazoedoshi, a person becomes 2 years old on the first New Year's Day
# after birth, even if they were born on Dec 25th.
puts "Stable age (Legal): #{Date.age(1.0)}"                        # => 29
puts "Stable age (Kazoedoshi): #{Date.age(1.0, kazoedoshi: true)}" # => 31

# Usage in a conditional:
# Perfect for celebrating Ruby's milestones in a traditional East Asian style.
if Date.age(kazoedoshi: true) == 35
  puts "Celebrating Ruby's 35th year by the ancient Kazoedoshi tradition!"
end

Updated by shugo (Shugo Maeda) about 14 hours ago Actions #5 [ruby-core:125170]

jinroq (Jinroq SAITOH) wrote in #note-4:

Under current Japanese law, a person's age increases at midnight on the day before their birthday. However, it might be better to use the traditional 'Kazeidoshi' (East Asian age reckoning) system, as its logic is much simpler.

Is “Kazeidoshi” the same as ‘Kazoedoshi’? For the purposes of this discussion, I will refer to it as “Kazoedoshi.”

Ah, yes, it's "Kazoedoshi".

The simplicity of (current_year - birth_year) + 1 is indeed very 'Ruby-like' in its elegance. I’ll update the proposal to include a kazoedoshi: true keyword argument, allowing users to choose between legal precision and traditional simplicity.

It sounds good:)

Updated by duerst (Martin Dürst) about 14 hours ago Actions #6 [ruby-core:125171]

Here is another proposal: Why not count using administrative/fiscal years? The administrative/fiscal year (年度 ('nendo') in Japanese, as opposed to simply 年 for (calendar) year) starts on April 1st.

As an example, 1993-02-24 to 1993-3-31 would be Ruby 元年度 (元年 ('gannen') is used for the first year of an era instead of the straightforward 一年). Ruby 2年度 would start on 1993-04-01. So today would be the first day of Ruby 35年度。

April 1st is also the start of the school/academic year in Japan. Counting this way also shows that Ruby is very well suited for educational contexts.

Updated by jinroq (Jinroq SAITOH) about 12 hours ago Actions #7 [ruby-core:125172]

duerst (Martin Dürst) wrote in #note-6:

Here is another proposal: Why not count using administrative/fiscal years? The administrative/fiscal year (年度 ('nendo') in Japanese, as opposed to simply 年 for (calendar) year) starts on April 1st.

As an example, 1993-02-24 to 1993-3-31 would be Ruby 元年度 (元年 ('gannen') is used for the first year of an era instead of the straightforward 一年). Ruby 2年度 would start on 1993-04-01. So today would be the first day of Ruby 35年度。

April 1st is also the start of the school/academic year in Japan. Counting this way also shows that Ruby is very well suited for educational contexts.

That's a great point of view!

However, it seems better to implement this proposal in the Ruby module proposed by ufuk, rather than in Date. Since it's a Ruby module, let's create a file called mruby.rb.

Actions

Also available in: PDF Atom