date_values 0.1.3 → 0.1.4
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +48 -12
- data/lib/date_values/month_day.rb +1 -1
- data/lib/date_values/rails/date_value_validator.rb +13 -0
- data/lib/date_values/rails/month_day_type.rb +2 -1
- data/lib/date_values/rails/time_of_day_type.rb +2 -1
- data/lib/date_values/rails/year_month_type.rb +2 -1
- data/lib/date_values/rails.rb +1 -0
- data/lib/date_values/time_of_day.rb +1 -1
- data/lib/date_values/version.rb +1 -1
- data/lib/date_values/year_month.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3ed7149400551e703761bd9ea324f55decb43cfe14e11d36d8e6e22f1fcb21a3
|
|
4
|
+
data.tar.gz: d809fce0b0215b62891a453b4e7e4278ad7a600ffea25cc045662f4a4ae1425b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 821ca618c27d3b17583c8420697ad11cbb3b9ee34dc44d7ea4d938ffd4500a4795b8aacd6b41df9864c982877d201c0dc616fecbca6342945c671b8b1f410679
|
|
7
|
+
data.tar.gz: f69de80391b67de78fafca31368c4f54683299c94740eba4047d0dff800ecb0647bcf208039473911fbf0fb60cbbb5595ef3c322d79154b72bc39e47056361a5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.1.4] - 2026-03-20
|
|
4
|
+
|
|
5
|
+
- Cast returns `nil` for invalid input instead of raising, following Rails convention
|
|
6
|
+
- Add `date_value` validator to distinguish "invalid input" from "no input"
|
|
7
|
+
- `#inspect` now uses `#<ClassName value>` format following Ruby convention
|
|
8
|
+
- Works with Rails standard validators (`comparison`, `inclusion`, `exclusion`)
|
|
9
|
+
|
|
3
10
|
## [0.1.3] - 2026-03-20
|
|
4
11
|
|
|
5
12
|
- Fix ActiveRecord type registration — use `ActiveSupport.on_load(:active_record)` to register types regardless of load order
|
data/README.md
CHANGED
|
@@ -24,27 +24,29 @@ 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
|
|
28
|
-
YearMonth.parse('2026-03') # => YearMonth
|
|
27
|
+
YearMonth.from(Date.today) # => #<DateValues::YearMonth 2026-03>
|
|
28
|
+
YearMonth.parse('2026-03') # => #<DateValues::YearMonth 2026-03>
|
|
29
29
|
|
|
30
|
-
ym + 1 # => YearMonth
|
|
31
|
-
ym - 1 # => YearMonth
|
|
30
|
+
ym + 1 # => #<DateValues::YearMonth 2026-04>
|
|
31
|
+
ym - 1 # => #<DateValues::YearMonth 2026-02>
|
|
32
32
|
YearMonth.new(2026, 3) - YearMonth.new(2025, 1) # => 14
|
|
33
33
|
|
|
34
34
|
# Range support
|
|
35
35
|
(YearMonth.new(2026, 1)..YearMonth.new(2026, 3)).to_a
|
|
36
|
-
# => [YearMonth
|
|
36
|
+
# => [#<DateValues::YearMonth 2026-01>, #<DateValues::YearMonth 2026-02>, #<DateValues::YearMonth 2026-03>]
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
### MonthDay
|
|
40
40
|
|
|
41
|
+
String representation uses ISO 8601 `--MM-DD` format (year omitted):
|
|
42
|
+
|
|
41
43
|
```ruby
|
|
42
44
|
md = MonthDay.new(3, 19)
|
|
43
45
|
md.to_s # => "--03-19"
|
|
44
46
|
md.to_date(2026) # => #<Date: 2026-03-19>
|
|
45
47
|
|
|
46
|
-
MonthDay.from(Date.today) # => MonthDay
|
|
47
|
-
MonthDay.parse('--03-19') # => MonthDay
|
|
48
|
+
MonthDay.from(Date.today) # => #<DateValues::MonthDay --03-20>
|
|
49
|
+
MonthDay.parse('--03-19') # => #<DateValues::MonthDay --03-19>
|
|
48
50
|
|
|
49
51
|
# Range membership
|
|
50
52
|
summer = MonthDay.new(6, 1)..MonthDay.new(8, 31)
|
|
@@ -59,8 +61,8 @@ tod.to_s # => "14:30"
|
|
|
59
61
|
|
|
60
62
|
TimeOfDay.new(14, 30, 45).to_s # => "14:30:45"
|
|
61
63
|
|
|
62
|
-
TimeOfDay.from(Time.now) # => TimeOfDay
|
|
63
|
-
TimeOfDay.parse('14:30') # => TimeOfDay
|
|
64
|
+
TimeOfDay.from(Time.now) # => #<DateValues::TimeOfDay 14:30>
|
|
65
|
+
TimeOfDay.parse('14:30') # => #<DateValues::TimeOfDay 14:30>
|
|
64
66
|
|
|
65
67
|
# Range membership
|
|
66
68
|
business_hours = TimeOfDay.new(9, 0)..TimeOfDay.new(17, 0)
|
|
@@ -109,6 +111,37 @@ Shop.where(billing_month: YearMonth.new(2026, 3))
|
|
|
109
111
|
# SELECT * FROM shops WHERE billing_month = '2026-03'
|
|
110
112
|
```
|
|
111
113
|
|
|
114
|
+
### Validation
|
|
115
|
+
|
|
116
|
+
All classes are `Comparable` and value-equal, so standard Rails validators work as-is:
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
class Contract < ApplicationRecord
|
|
120
|
+
attribute :start_month, :year_month
|
|
121
|
+
attribute :opens_at, :time_of_day
|
|
122
|
+
|
|
123
|
+
validates :start_month, comparison: {greater_than: -> { YearMonth.from(Date.current) }}
|
|
124
|
+
validates :opens_at, comparison: {
|
|
125
|
+
greater_than_or_equal_to: TimeOfDay.new(9, 0),
|
|
126
|
+
less_than_or_equal_to: TimeOfDay.new(17, 0)
|
|
127
|
+
}
|
|
128
|
+
end
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Invalid input (e.g. `"25:00"`) is cast to `nil` rather than raising, following the same convention as Rails' built-in types. The `date_value` validator detects this and gives a meaningful error message:
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
class Shop < ApplicationRecord
|
|
135
|
+
attribute :opens_at, :time_of_day
|
|
136
|
+
|
|
137
|
+
validates :opens_at, presence: true, date_value: true
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
Shop.new(opens_at: '25:00').errors[:opens_at] # => ["is invalid"]
|
|
141
|
+
Shop.new(opens_at: '').errors[:opens_at] # => ["can't be blank"]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
|
|
112
145
|
### I18n / `l` Helper
|
|
113
146
|
|
|
114
147
|
All classes implement `#strftime`, and the Rails integration extends `I18n.l` to support them. Define formats in your locale files:
|
|
@@ -125,6 +158,7 @@ en:
|
|
|
125
158
|
time_of_day:
|
|
126
159
|
formats:
|
|
127
160
|
default: '%-I:%M %p'
|
|
161
|
+
long: '%-I:%M:%S %p'
|
|
128
162
|
```
|
|
129
163
|
|
|
130
164
|
```yaml
|
|
@@ -138,12 +172,14 @@ ja:
|
|
|
138
172
|
default: '%-m月%-d日'
|
|
139
173
|
time_of_day:
|
|
140
174
|
formats:
|
|
141
|
-
default: '%-H
|
|
175
|
+
default: '%-H時%-M分'
|
|
176
|
+
long: '%-H時%-M分%-S秒'
|
|
142
177
|
```
|
|
143
178
|
|
|
144
179
|
```ruby
|
|
145
|
-
I18n.l YearMonth.new(2026, 3), locale: :en
|
|
146
|
-
I18n.l YearMonth.new(2026, 3), locale: :ja
|
|
180
|
+
I18n.l YearMonth.new(2026, 3), locale: :en # => "March 2026"
|
|
181
|
+
I18n.l YearMonth.new(2026, 3), locale: :ja # => "2026年3月"
|
|
182
|
+
I18n.l TimeOfDay.new(14, 30), format: :long # => "2:30:00 PM"
|
|
147
183
|
```
|
|
148
184
|
|
|
149
185
|
## License
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_model/validator'
|
|
4
|
+
|
|
5
|
+
class DateValueValidator < ActiveModel::EachValidator
|
|
6
|
+
def validate_each(record, attribute, value)
|
|
7
|
+
raw = record.read_attribute_before_type_cast(attribute)
|
|
8
|
+
return if raw.blank?
|
|
9
|
+
return unless value.nil?
|
|
10
|
+
|
|
11
|
+
record.errors.add(attribute, :invalid, **options)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -13,8 +13,9 @@ module DateValues
|
|
|
13
13
|
when Time then TimeOfDay.new(value.hour, value.min, value.sec)
|
|
14
14
|
when String then TimeOfDay.parse(value)
|
|
15
15
|
when nil then nil
|
|
16
|
-
else raise ArgumentError, "can't cast #{value.class} to TimeOfDay"
|
|
17
16
|
end
|
|
17
|
+
rescue ArgumentError
|
|
18
|
+
nil
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def serialize(value)
|
data/lib/date_values/rails.rb
CHANGED
|
@@ -7,6 +7,7 @@ require_relative 'rails/year_month_type'
|
|
|
7
7
|
require_relative 'rails/month_day_type'
|
|
8
8
|
require_relative 'rails/time_of_day_type'
|
|
9
9
|
require_relative 'rails/i18n_backend'
|
|
10
|
+
require_relative 'rails/date_value_validator'
|
|
10
11
|
|
|
11
12
|
ActiveModel::Type.register(:year_month, DateValues::Rails::YearMonthType)
|
|
12
13
|
ActiveModel::Type.register(:month_day, DateValues::Rails::MonthDayType)
|
data/lib/date_values/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.1.4
|
|
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/date_value_validator.rb
|
|
25
26
|
- lib/date_values/rails/i18n_backend.rb
|
|
26
27
|
- lib/date_values/rails/month_day_type.rb
|
|
27
28
|
- lib/date_values/rails/time_of_day_type.rb
|