date_values 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9128f65130329b58d9b750e411178c545086d0b46121ebe8a502fd3bb2774d9f
4
- data.tar.gz: 39c349f3f8edb108890f1c3b267a75e3e16ef59f846fc5bebdc5198f38a89f31
3
+ metadata.gz: 76e212d3b12d520ef70a3072bb307cfec021b1f4a09fae4a03b75df64e8c2dcd
4
+ data.tar.gz: 7e230882c9b6cd8ea7147195143a0802a6f15c9cfcea6e04578edcd3235494ba
5
5
  SHA512:
6
- metadata.gz: 30ceca8989f62e0fa958b02858ccefef45cff6d637e77f0fa7f4f3e87c6be562fb5d7c444873ebedb0f0ccf665f2662806ff7a5a0103459e47cce86e7753988e
7
- data.tar.gz: d0c2a75cb71ae66715f1cf357602f948910d518d3d9901a57672f7457626e500fe6a91ebd18cb0d56738aeb6c2c66c74797043b92576f154d656fe4c138b9eae
6
+ metadata.gz: 9bdf4015dd33168d98fb6bdd3885e42ccb7a880862b67f400ca2c5fc394afad08a42b20f7af820548ecb482f178e128e0f6ee81893de90ce39ed9b2d1b9f9f64
7
+ data.tar.gz: 49b14bf137cd2139ade667faf3ffb6d2b3890830aa63f8f66138ca55ad5ed792570a0186dbcbcfa2f57876c3402bb29875b97087645610753af0f3f5621bfa4d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.2] - 2026-03-19
4
+
5
+ - Add `#strftime` to `YearMonth`, `MonthDay`, and `TimeOfDay`
6
+ - Add I18n backend extension for Rails `l` helper — looks up `year_month.formats`, `month_day.formats`, and `time_of_day.formats` in locale files
7
+
8
+ ## [0.1.1] - 2026-03-19
9
+
10
+ - Add `.from` class methods for converting from `Date` / `Time` (`YearMonth.from(date)`, `MonthDay.from(date)`, `TimeOfDay.from(time)`)
11
+
3
12
  ## [0.1.0] - 2026-03-19
4
13
 
5
14
  - `DateValues::YearMonth` — year-month value object with arithmetic (`+`, `-`), `Range` support, and `Date` conversion
data/README.md CHANGED
@@ -24,6 +24,7 @@ ym = YearMonth.new(2026, 3)
24
24
  ym.to_s # => "2026-03"
25
25
  ym.to_date # => #<Date: 2026-03-01>
26
26
 
27
+ YearMonth.from(Date.today) # => YearMonth[2026-03]
27
28
  YearMonth.parse('2026-03') # => YearMonth[2026-03]
28
29
 
29
30
  ym + 1 # => YearMonth[2026-04]
@@ -42,6 +43,7 @@ md = MonthDay.new(3, 19)
42
43
  md.to_s # => "--03-19"
43
44
  md.to_date(2026) # => #<Date: 2026-03-19>
44
45
 
46
+ MonthDay.from(Date.today) # => MonthDay[--03-19]
45
47
  MonthDay.parse('--03-19') # => MonthDay[--03-19]
46
48
  ```
47
49
 
@@ -53,9 +55,31 @@ tod.to_s # => "14:30"
53
55
 
54
56
  TimeOfDay.new(14, 30, 45).to_s # => "14:30:45"
55
57
 
58
+ TimeOfDay.from(Time.now) # => TimeOfDay[14:30]
56
59
  TimeOfDay.parse('14:30') # => TimeOfDay[14:30]
57
60
  ```
58
61
 
62
+ ### Pattern Matching
63
+
64
+ Built on `Data.define`, so pattern matching works out of the box:
65
+
66
+ ```ruby
67
+ case YearMonth.new(2026, 3)
68
+ in { year: 2026, month: (1..3) }
69
+ puts 'Q1 2026'
70
+ end
71
+
72
+ case MonthDay.new(12, 25)
73
+ in { month: 12, day: 25 }
74
+ puts 'Christmas'
75
+ end
76
+
77
+ case TimeOfDay.new(14, 30)
78
+ in { hour: (9..17) }
79
+ puts 'Business hours'
80
+ end
81
+ ```
82
+
59
83
  ## Rails Integration
60
84
 
61
85
  Opt-in ActiveModel type casting for ActiveRecord attributes:
@@ -70,6 +94,43 @@ class Shop < ApplicationRecord
70
94
  end
71
95
  ```
72
96
 
97
+ ### I18n / `l` Helper
98
+
99
+ All classes implement `#strftime`, and the Rails integration extends `I18n.l` to support them. Define formats in your locale files:
100
+
101
+ ```yaml
102
+ # config/locales/en.yml
103
+ en:
104
+ year_month:
105
+ formats:
106
+ default: '%B %Y'
107
+ month_day:
108
+ formats:
109
+ default: '%B %-d'
110
+ time_of_day:
111
+ formats:
112
+ default: '%-I:%M %p'
113
+ ```
114
+
115
+ ```yaml
116
+ # config/locales/ja.yml
117
+ ja:
118
+ year_month:
119
+ formats:
120
+ default: '%Y年%-m月'
121
+ month_day:
122
+ formats:
123
+ default: '%-m月%-d日'
124
+ time_of_day:
125
+ formats:
126
+ default: '%-H時%M分'
127
+ ```
128
+
129
+ ```ruby
130
+ I18n.l YearMonth.new(2026, 3), locale: :en # => "March 2026"
131
+ I18n.l YearMonth.new(2026, 3), locale: :ja # => "2026年3月"
132
+ ```
133
+
73
134
  ## License
74
135
 
75
136
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -13,6 +13,10 @@ module DateValues
13
13
  super
14
14
  end
15
15
 
16
+ def self.from(date)
17
+ new(date.month, date.day)
18
+ end
19
+
16
20
  def self.parse(str)
17
21
  raise ArgumentError, "invalid MonthDay: #{str}" unless str.match?(/\A--\d{2}-\d{2}\z/)
18
22
 
@@ -26,6 +30,11 @@ module DateValues
26
30
  [month, day] <=> [other.month, other.day]
27
31
  end
28
32
 
33
+ def strftime(format)
34
+ # 2000 is a leap year, so Feb 29 works
35
+ Date.new(2000, month, day).strftime(format)
36
+ end
37
+
29
38
  def to_date(year)
30
39
  Date.new(year, month, day)
31
40
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DateValues
4
+ module Rails
5
+ module I18nBackend
6
+ TYPES = {
7
+ DateValues::YearMonth => :year_month,
8
+ DateValues::MonthDay => :month_day,
9
+ DateValues::TimeOfDay => :time_of_day
10
+ }.freeze
11
+
12
+ def localize(locale, object, format = :default, options = EMPTY_HASH)
13
+ type = TYPES[object.class]
14
+ return super unless type
15
+
16
+ format_key = format.is_a?(Symbol) ? format : nil
17
+
18
+ if format_key
19
+ entry = I18n.t("#{type}.formats.#{format_key}", locale: locale, default: nil)
20
+ raise I18n::MissingTranslationData.new(locale, "#{type}.formats.#{format_key}") unless entry
21
+
22
+ format = entry
23
+ end
24
+
25
+ object.strftime(format)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -6,7 +6,10 @@ require 'active_model/type'
6
6
  require_relative 'rails/year_month_type'
7
7
  require_relative 'rails/month_day_type'
8
8
  require_relative 'rails/time_of_day_type'
9
+ require_relative 'rails/i18n_backend'
9
10
 
10
11
  ActiveModel::Type.register(:year_month, DateValues::Rails::YearMonthType)
11
12
  ActiveModel::Type.register(:month_day, DateValues::Rails::MonthDayType)
12
13
  ActiveModel::Type.register(:time_of_day, DateValues::Rails::TimeOfDayType)
14
+
15
+ I18n::Backend::Base.prepend(DateValues::Rails::I18nBackend)
@@ -12,6 +12,10 @@ module DateValues
12
12
  super
13
13
  end
14
14
 
15
+ def self.from(time)
16
+ new(time.hour, time.min, time.sec)
17
+ end
18
+
15
19
  def self.parse(str)
16
20
  parts = str.split(':')
17
21
  raise ArgumentError, "invalid TimeOfDay: #{str}" unless [2, 3].include?(parts.size)
@@ -25,6 +29,10 @@ module DateValues
25
29
  [hour, minute, second] <=> [other.hour, other.minute, other.second]
26
30
  end
27
31
 
32
+ def strftime(format)
33
+ Time.new(2000, 1, 1, hour, minute, second).strftime(format)
34
+ end
35
+
28
36
  def to_s
29
37
  if second.zero?
30
38
  format('%02d:%02d', hour, minute)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DateValues
4
- VERSION = "0.1.0"
4
+ VERSION = '0.1.2'
5
5
  end
@@ -12,6 +12,10 @@ module DateValues
12
12
  super
13
13
  end
14
14
 
15
+ def self.from(date)
16
+ new(date.year, date.month)
17
+ end
18
+
15
19
  def self.parse(str)
16
20
  raise ArgumentError, "invalid YearMonth: #{str}" unless str.match?(/\A\d{4}-\d{2}\z/)
17
21
 
@@ -45,6 +49,10 @@ module DateValues
45
49
  self + 1
46
50
  end
47
51
 
52
+ def strftime(format)
53
+ to_date.strftime(format)
54
+ end
55
+
48
56
  def to_date
49
57
  Date.new(year, month, 1)
50
58
  end
data/sig/date_values.rbs CHANGED
@@ -9,6 +9,8 @@ module DateValues
9
9
 
10
10
  def initialize: (Integer year, Integer month) -> void
11
11
 
12
+ def self.from: (Date date) -> YearMonth
13
+
12
14
  def self.parse: (String str) -> YearMonth
13
15
 
14
16
  def <=>: (YearMonth other) -> Integer
@@ -21,6 +23,8 @@ module DateValues
21
23
 
22
24
  def succ: () -> YearMonth
23
25
 
26
+ def strftime: (String format) -> String
27
+
24
28
  def to_date: () -> Date
25
29
 
26
30
  def to_s: () -> String
@@ -36,11 +40,15 @@ module DateValues
36
40
 
37
41
  def initialize: (Integer month, Integer day) -> void
38
42
 
43
+ def self.from: (Date date) -> MonthDay
44
+
39
45
  def self.parse: (String str) -> MonthDay
40
46
 
41
47
  def <=>: (MonthDay other) -> Integer
42
48
  | (untyped other) -> nil
43
49
 
50
+ def strftime: (String format) -> String
51
+
44
52
  def to_date: (Integer year) -> Date
45
53
 
46
54
  def to_s: () -> String
@@ -61,11 +69,15 @@ module DateValues
61
69
 
62
70
  def initialize: (Integer hour, Integer minute, ?Integer second) -> void
63
71
 
72
+ def self.from: (Time time) -> TimeOfDay
73
+
64
74
  def self.parse: (String str) -> TimeOfDay
65
75
 
66
76
  def <=>: (TimeOfDay other) -> Integer
67
77
  | (untyped other) -> nil
68
78
 
79
+ def strftime: (String format) -> String
80
+
69
81
  def to_s: () -> String
70
82
 
71
83
  def inspect: () -> String
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: date_values
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keita Urashima
@@ -22,6 +22,7 @@ files:
22
22
  - lib/date_values.rb
23
23
  - lib/date_values/month_day.rb
24
24
  - lib/date_values/rails.rb
25
+ - lib/date_values/rails/i18n_backend.rb
25
26
  - lib/date_values/rails/month_day_type.rb
26
27
  - lib/date_values/rails/time_of_day_type.rb
27
28
  - lib/date_values/rails/year_month_type.rb