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 +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +61 -0
- data/lib/date_values/month_day.rb +9 -0
- data/lib/date_values/rails/i18n_backend.rb +29 -0
- data/lib/date_values/rails.rb +3 -0
- data/lib/date_values/time_of_day.rb +8 -0
- data/lib/date_values/version.rb +1 -1
- data/lib/date_values/year_month.rb +8 -0
- data/sig/date_values.rbs +12 -0
- 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: 76e212d3b12d520ef70a3072bb307cfec021b1f4a09fae4a03b75df64e8c2dcd
|
|
4
|
+
data.tar.gz: 7e230882c9b6cd8ea7147195143a0802a6f15c9cfcea6e04578edcd3235494ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
data/lib/date_values/rails.rb
CHANGED
|
@@ -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)
|
data/lib/date_values/version.rb
CHANGED
|
@@ -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.
|
|
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
|