date_values 0.1.3 → 0.2.0
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 +11 -0
- data/README.md +14 -64
- data/lib/date_values/month_day.rb +6 -5
- 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 +5 -5
- metadata +1 -7
- data/lib/date_values/rails/i18n_backend.rb +0 -29
- data/lib/date_values/rails/month_day_type.rb +0 -30
- data/lib/date_values/rails/time_of_day_type.rb +0 -33
- data/lib/date_values/rails/year_month_type.rb +0 -30
- data/lib/date_values/rails.rb +0 -21
- data/sig/date_values/rails.rbs +0 -44
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f294856b7f5149ded52770b4d43d003b5cac6e8ee533f81ec003ac04caf9988b
|
|
4
|
+
data.tar.gz: 8c1f6046926d15cda1a01e55f89e2975b92e6cf515bbc21cb0b6892d816bf93b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 05e23c3cd91ddda9dcdf5ae63e81dd89c7a6bfd5150dab2893231ebe63c12bc64023cae0667c296e4e88db2dd5869ebdab39245370291cb29cbb9b2d906ad3e3
|
|
7
|
+
data.tar.gz: 28e82e5dc12f33c6e8af8b546338636ef2f6cda3273a2957bf7f86dcb4bb4a6074a4e2376c1c0ed0600f19e98b2783661710c8882b066eb05d3d9c1aa359aea8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2026-03-20
|
|
4
|
+
|
|
5
|
+
- **Breaking**: Rails integration extracted to [date_values-rails](https://github.com/ursm/date_values-rails). `require 'date_values/rails'` now requires installing `date_values-rails` gem.
|
|
6
|
+
|
|
7
|
+
## [0.1.4] - 2026-03-20
|
|
8
|
+
|
|
9
|
+
- Cast returns `nil` for invalid input instead of raising, following Rails convention
|
|
10
|
+
- Add `date_value` validator to distinguish "invalid input" from "no input"
|
|
11
|
+
- `#inspect` now uses `#<ClassName value>` format following Ruby convention
|
|
12
|
+
- Works with Rails standard validators (`comparison`, `inclusion`, `exclusion`)
|
|
13
|
+
|
|
3
14
|
## [0.1.3] - 2026-03-20
|
|
4
15
|
|
|
5
16
|
- Fix ActiveRecord type registration — use `ActiveSupport.on_load(:active_record)` to register types regardless of load order
|
data/README.md
CHANGED
|
@@ -24,27 +24,31 @@ 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
|
+
YearMonth.parse('2026/3') # also works
|
|
29
30
|
|
|
30
|
-
ym + 1 # => YearMonth
|
|
31
|
-
ym - 1 # => YearMonth
|
|
31
|
+
ym + 1 # => #<DateValues::YearMonth 2026-04>
|
|
32
|
+
ym - 1 # => #<DateValues::YearMonth 2026-02>
|
|
32
33
|
YearMonth.new(2026, 3) - YearMonth.new(2025, 1) # => 14
|
|
33
34
|
|
|
34
35
|
# Range support
|
|
35
36
|
(YearMonth.new(2026, 1)..YearMonth.new(2026, 3)).to_a
|
|
36
|
-
# => [YearMonth
|
|
37
|
+
# => [#<DateValues::YearMonth 2026-01>, #<DateValues::YearMonth 2026-02>, #<DateValues::YearMonth 2026-03>]
|
|
37
38
|
```
|
|
38
39
|
|
|
39
40
|
### MonthDay
|
|
40
41
|
|
|
42
|
+
String representation uses ISO 8601 `--MM-DD` format (year omitted):
|
|
43
|
+
|
|
41
44
|
```ruby
|
|
42
45
|
md = MonthDay.new(3, 19)
|
|
43
46
|
md.to_s # => "--03-19"
|
|
44
47
|
md.to_date(2026) # => #<Date: 2026-03-19>
|
|
45
48
|
|
|
46
|
-
MonthDay.from(Date.today) # => MonthDay
|
|
47
|
-
MonthDay.parse('--03-19') # => MonthDay
|
|
49
|
+
MonthDay.from(Date.today) # => #<DateValues::MonthDay --03-20>
|
|
50
|
+
MonthDay.parse('--03-19') # => #<DateValues::MonthDay --03-19>
|
|
51
|
+
MonthDay.parse('3/19') # also works
|
|
48
52
|
|
|
49
53
|
# Range membership
|
|
50
54
|
summer = MonthDay.new(6, 1)..MonthDay.new(8, 31)
|
|
@@ -59,8 +63,8 @@ tod.to_s # => "14:30"
|
|
|
59
63
|
|
|
60
64
|
TimeOfDay.new(14, 30, 45).to_s # => "14:30:45"
|
|
61
65
|
|
|
62
|
-
TimeOfDay.from(Time.now) # => TimeOfDay
|
|
63
|
-
TimeOfDay.parse('14:30') # => TimeOfDay
|
|
66
|
+
TimeOfDay.from(Time.now) # => #<DateValues::TimeOfDay 14:30>
|
|
67
|
+
TimeOfDay.parse('14:30') # => #<DateValues::TimeOfDay 14:30>
|
|
64
68
|
|
|
65
69
|
# Range membership
|
|
66
70
|
business_hours = TimeOfDay.new(9, 0)..TimeOfDay.new(17, 0)
|
|
@@ -90,61 +94,7 @@ end
|
|
|
90
94
|
|
|
91
95
|
## Rails Integration
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
```ruby
|
|
96
|
-
require 'date_values/rails'
|
|
97
|
-
|
|
98
|
-
class Shop < ApplicationRecord
|
|
99
|
-
attribute :billing_month, :year_month # string column "2026-03"
|
|
100
|
-
attribute :anniversary, :month_day # string column "--03-19"
|
|
101
|
-
attribute :opens_at, :time_of_day # string or time column
|
|
102
|
-
end
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Values are automatically serialized in queries:
|
|
106
|
-
|
|
107
|
-
```ruby
|
|
108
|
-
Shop.where(billing_month: YearMonth.new(2026, 3))
|
|
109
|
-
# SELECT * FROM shops WHERE billing_month = '2026-03'
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### I18n / `l` Helper
|
|
113
|
-
|
|
114
|
-
All classes implement `#strftime`, and the Rails integration extends `I18n.l` to support them. Define formats in your locale files:
|
|
115
|
-
|
|
116
|
-
```yaml
|
|
117
|
-
# config/locales/en.yml
|
|
118
|
-
en:
|
|
119
|
-
year_month:
|
|
120
|
-
formats:
|
|
121
|
-
default: '%B %Y'
|
|
122
|
-
month_day:
|
|
123
|
-
formats:
|
|
124
|
-
default: '%B %-d'
|
|
125
|
-
time_of_day:
|
|
126
|
-
formats:
|
|
127
|
-
default: '%-I:%M %p'
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
```yaml
|
|
131
|
-
# config/locales/ja.yml
|
|
132
|
-
ja:
|
|
133
|
-
year_month:
|
|
134
|
-
formats:
|
|
135
|
-
default: '%Y年%-m月'
|
|
136
|
-
month_day:
|
|
137
|
-
formats:
|
|
138
|
-
default: '%-m月%-d日'
|
|
139
|
-
time_of_day:
|
|
140
|
-
formats:
|
|
141
|
-
default: '%-H時%M分'
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
```ruby
|
|
145
|
-
I18n.l YearMonth.new(2026, 3), locale: :en # => "March 2026"
|
|
146
|
-
I18n.l YearMonth.new(2026, 3), locale: :ja # => "2026年3月"
|
|
147
|
-
```
|
|
97
|
+
See [date_values-rails](https://github.com/ursm/date_values-rails) for ActiveModel/ActiveRecord type casting, validation, and I18n support.
|
|
148
98
|
|
|
149
99
|
## License
|
|
150
100
|
|
|
@@ -18,10 +18,11 @@ module DateValues
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def self.parse(str)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
case str
|
|
22
|
+
when /\A--(\d{1,2})-(\d{1,2})\z/ then new($1.to_i, $2.to_i)
|
|
23
|
+
when /\A(\d{1,2})[\/\-](\d{1,2})\z/ then new($1.to_i, $2.to_i)
|
|
24
|
+
else raise ArgumentError, "invalid MonthDay: #{str}"
|
|
25
|
+
end
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
def <=>(other)
|
|
@@ -44,7 +45,7 @@ module DateValues
|
|
|
44
45
|
end
|
|
45
46
|
|
|
46
47
|
def inspect
|
|
47
|
-
"MonthDay
|
|
48
|
+
"#<DateValues::MonthDay #{self}>"
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
private
|
data/lib/date_values/version.rb
CHANGED
|
@@ -17,10 +17,10 @@ module DateValues
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def self.parse(str)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
case str
|
|
21
|
+
when /\A(\d{4})[\/\-](\d{1,2})\z/ then new($1.to_i, $2.to_i)
|
|
22
|
+
else raise ArgumentError, "invalid YearMonth: #{str}"
|
|
23
|
+
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def <=>(other)
|
|
@@ -62,7 +62,7 @@ module DateValues
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def inspect
|
|
65
|
-
"YearMonth
|
|
65
|
+
"#<DateValues::YearMonth #{self}>"
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
end
|
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.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Keita Urashima
|
|
@@ -21,16 +21,10 @@ files:
|
|
|
21
21
|
- Rakefile
|
|
22
22
|
- lib/date_values.rb
|
|
23
23
|
- lib/date_values/month_day.rb
|
|
24
|
-
- lib/date_values/rails.rb
|
|
25
|
-
- lib/date_values/rails/i18n_backend.rb
|
|
26
|
-
- lib/date_values/rails/month_day_type.rb
|
|
27
|
-
- lib/date_values/rails/time_of_day_type.rb
|
|
28
|
-
- lib/date_values/rails/year_month_type.rb
|
|
29
24
|
- lib/date_values/time_of_day.rb
|
|
30
25
|
- lib/date_values/version.rb
|
|
31
26
|
- lib/date_values/year_month.rb
|
|
32
27
|
- sig/date_values.rbs
|
|
33
|
-
- sig/date_values/rails.rbs
|
|
34
28
|
homepage: https://github.com/ursm/date_values
|
|
35
29
|
licenses:
|
|
36
30
|
- MIT
|
|
@@ -1,29 +0,0 @@
|
|
|
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
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module DateValues
|
|
4
|
-
module Rails
|
|
5
|
-
class MonthDayType < ActiveModel::Type::Value
|
|
6
|
-
def type
|
|
7
|
-
:month_day
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def cast(value)
|
|
11
|
-
case value
|
|
12
|
-
when MonthDay then value
|
|
13
|
-
when String then MonthDay.parse(value)
|
|
14
|
-
when nil then nil
|
|
15
|
-
else raise ArgumentError, "can't cast #{value.class} to MonthDay"
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def serialize(value)
|
|
20
|
-
value&.to_s
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def deserialize(value)
|
|
24
|
-
return nil if value.nil?
|
|
25
|
-
|
|
26
|
-
MonthDay.parse(value)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module DateValues
|
|
4
|
-
module Rails
|
|
5
|
-
class TimeOfDayType < ActiveModel::Type::Value
|
|
6
|
-
def type
|
|
7
|
-
:time_of_day
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def cast(value)
|
|
11
|
-
case value
|
|
12
|
-
when TimeOfDay then value
|
|
13
|
-
when Time then TimeOfDay.new(value.hour, value.min, value.sec)
|
|
14
|
-
when String then TimeOfDay.parse(value)
|
|
15
|
-
when nil then nil
|
|
16
|
-
else raise ArgumentError, "can't cast #{value.class} to TimeOfDay"
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def serialize(value)
|
|
21
|
-
value&.to_s
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def deserialize(value)
|
|
25
|
-
case value
|
|
26
|
-
when nil then nil
|
|
27
|
-
when Time then TimeOfDay.new(value.hour, value.min, value.sec)
|
|
28
|
-
when String then TimeOfDay.parse(value)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module DateValues
|
|
4
|
-
module Rails
|
|
5
|
-
class YearMonthType < ActiveModel::Type::Value
|
|
6
|
-
def type
|
|
7
|
-
:year_month
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def cast(value)
|
|
11
|
-
case value
|
|
12
|
-
when YearMonth then value
|
|
13
|
-
when String then YearMonth.parse(value)
|
|
14
|
-
when nil then nil
|
|
15
|
-
else raise ArgumentError, "can't cast #{value.class} to YearMonth"
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def serialize(value)
|
|
20
|
-
value&.to_s
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def deserialize(value)
|
|
24
|
-
return nil if value.nil?
|
|
25
|
-
|
|
26
|
-
YearMonth.parse(value)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
data/lib/date_values/rails.rb
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'date_values'
|
|
4
|
-
require 'active_support'
|
|
5
|
-
require 'active_model/type'
|
|
6
|
-
require_relative 'rails/year_month_type'
|
|
7
|
-
require_relative 'rails/month_day_type'
|
|
8
|
-
require_relative 'rails/time_of_day_type'
|
|
9
|
-
require_relative 'rails/i18n_backend'
|
|
10
|
-
|
|
11
|
-
ActiveModel::Type.register(:year_month, DateValues::Rails::YearMonthType)
|
|
12
|
-
ActiveModel::Type.register(:month_day, DateValues::Rails::MonthDayType)
|
|
13
|
-
ActiveModel::Type.register(:time_of_day, DateValues::Rails::TimeOfDayType)
|
|
14
|
-
|
|
15
|
-
ActiveSupport.on_load(:active_record) do
|
|
16
|
-
ActiveRecord::Type.register(:year_month, DateValues::Rails::YearMonthType)
|
|
17
|
-
ActiveRecord::Type.register(:month_day, DateValues::Rails::MonthDayType)
|
|
18
|
-
ActiveRecord::Type.register(:time_of_day, DateValues::Rails::TimeOfDayType)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
I18n::Backend::Base.prepend(DateValues::Rails::I18nBackend)
|
data/sig/date_values/rails.rbs
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
module DateValues
|
|
2
|
-
module Rails
|
|
3
|
-
class YearMonthType < ActiveModel::Type::Value
|
|
4
|
-
def type: () -> :year_month
|
|
5
|
-
|
|
6
|
-
def cast: (YearMonth value) -> YearMonth
|
|
7
|
-
| (String value) -> YearMonth
|
|
8
|
-
| (nil value) -> nil
|
|
9
|
-
|
|
10
|
-
def serialize: (YearMonth? value) -> String?
|
|
11
|
-
|
|
12
|
-
def deserialize: (String value) -> YearMonth
|
|
13
|
-
| (nil value) -> nil
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
class MonthDayType < ActiveModel::Type::Value
|
|
17
|
-
def type: () -> :month_day
|
|
18
|
-
|
|
19
|
-
def cast: (MonthDay value) -> MonthDay
|
|
20
|
-
| (String value) -> MonthDay
|
|
21
|
-
| (nil value) -> nil
|
|
22
|
-
|
|
23
|
-
def serialize: (MonthDay? value) -> String?
|
|
24
|
-
|
|
25
|
-
def deserialize: (String value) -> MonthDay
|
|
26
|
-
| (nil value) -> nil
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
class TimeOfDayType < ActiveModel::Type::Value
|
|
30
|
-
def type: () -> :time_of_day
|
|
31
|
-
|
|
32
|
-
def cast: (TimeOfDay value) -> TimeOfDay
|
|
33
|
-
| (Time value) -> TimeOfDay
|
|
34
|
-
| (String value) -> TimeOfDay
|
|
35
|
-
| (nil value) -> nil
|
|
36
|
-
|
|
37
|
-
def serialize: (TimeOfDay? value) -> String?
|
|
38
|
-
|
|
39
|
-
def deserialize: (Time value) -> TimeOfDay
|
|
40
|
-
| (String value) -> TimeOfDay
|
|
41
|
-
| (nil value) -> nil
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|