MetricCalendar 1.0.0 → 1.0.1
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/lib/metric_calendar.rb +101 -22
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b09d0f43797e81cc342c4391c02e1ecb7060819b6c5ad9e756cf3827f9425590
|
|
4
|
+
data.tar.gz: dbf242e1f7c9a6c1ab7b56417bf0e1a2dfc66576e72944c7ee19235752e6e528
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8b6d5edc95adca7e75c6b5900a07f8d374f80e33e40512171e312c504bdbae3333f3f993af51cd3907943008e0ab503d0e610a3040f7a5a74cc1b8d5bb7abb22
|
|
7
|
+
data.tar.gz: 4e9840cf9288135efeb5af5b32513de537471fe16182aaf318dc14cff8bfa31a4b1fb828e2dce8f120dae358f144d93315ec443c9a4e7d64918da54215a09225
|
data/lib/metric_calendar.rb
CHANGED
|
@@ -3,29 +3,41 @@ require 'date'
|
|
|
3
3
|
module MetricCalendar
|
|
4
4
|
DAY_NAMES = %w[Primday Duoday Triday Quadday Quintday Hexday Septday Octday Novday Decday].freeze
|
|
5
5
|
MONTH_NAMES = %w[Unil Duil Tril Quadril Quintil Sextil Septil Octil Novil Decil Undecil Duodecil].freeze
|
|
6
|
+
SEASON_NAMES = %w[Rising Flourishing Gathering Stillness].freeze
|
|
6
7
|
TURNING_DAY_NAMES = %w[Vigil Balance Dawn].freeze
|
|
7
8
|
YULE_DAY_NAMES = ['Yule Eve', 'Midwinter', 'Kindling'].freeze
|
|
8
9
|
|
|
10
|
+
FORMAT_RE = /MMM|MM|M|DD|D|WW|W|Y|S/.freeze
|
|
11
|
+
|
|
9
12
|
# Struct for a Metric Calendar date. Fields:
|
|
10
|
-
# year
|
|
11
|
-
# month
|
|
12
|
-
# month_name
|
|
13
|
-
# day
|
|
14
|
-
# week_day
|
|
15
|
-
# day_name
|
|
16
|
-
# week
|
|
17
|
-
# season_index
|
|
18
|
-
# is_leap_year
|
|
19
|
-
# is_turning
|
|
20
|
-
# is_yule
|
|
21
|
-
# is_midsummer
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
13
|
+
# year - Metric year (Year 0 = spring equinox 1970)
|
|
14
|
+
# month - 1-12, 0 for Turning/Yule
|
|
15
|
+
# month_name - e.g. "Unil", "" for Turning/Yule
|
|
16
|
+
# day - 1-30, 0 for Turning/Yule
|
|
17
|
+
# week_day - 1-10, 0 for Turning/Yule
|
|
18
|
+
# day_name - e.g. "Primday", "" for Turning/Yule
|
|
19
|
+
# week - 1-36, 0 for Turning/Yule
|
|
20
|
+
# season_index - 0-3, -1 for Turning/Yule
|
|
21
|
+
# is_leap_year - true if this metric year has 3 Yule days
|
|
22
|
+
# is_turning - true during The Turning (3 days at spring equinox)
|
|
23
|
+
# is_yule - true during Yule
|
|
24
|
+
# is_midsummer - true on Quadril 1 (summer solstice)
|
|
25
|
+
# is_sextant - true on Duil 30
|
|
26
|
+
# is_trine - true on Quadril 30
|
|
27
|
+
# is_spiral - true on Quintil 18 (golden angle day)
|
|
28
|
+
# is_convergence - true on Quintil 24
|
|
29
|
+
# is_meridian - true on Sextil 30
|
|
30
|
+
# is_mask - true on Octil 13
|
|
31
|
+
# is_harmony - true on Octil 30
|
|
32
|
+
# is_rest - true on days 8-10 of any 10-day week
|
|
33
|
+
# special_day - "Vigil", "Balance", "Dawn", "Yule Eve", "Midwinter", "Kindling", or ""
|
|
34
|
+
# observance - name of observance, or "" if none
|
|
25
35
|
MetricDate = Struct.new(
|
|
26
36
|
:year, :month, :month_name, :day, :week_day, :day_name,
|
|
27
37
|
:week, :season_index, :is_leap_year, :is_turning, :is_yule,
|
|
28
|
-
:is_midsummer, :
|
|
38
|
+
:is_midsummer, :is_sextant, :is_trine, :is_spiral,
|
|
39
|
+
:is_convergence, :is_meridian, :is_mask, :is_harmony,
|
|
40
|
+
:is_rest, :special_day, :observance,
|
|
29
41
|
keyword_init: true
|
|
30
42
|
)
|
|
31
43
|
|
|
@@ -58,12 +70,15 @@ module MetricCalendar
|
|
|
58
70
|
year: metric_year, month: 0, month_name: '', day: 0, week_day: 0,
|
|
59
71
|
day_name: '', week: 0, season_index: -1,
|
|
60
72
|
is_leap_year: leap, is_turning: false, is_yule: false,
|
|
61
|
-
is_midsummer: false,
|
|
73
|
+
is_midsummer: false, is_sextant: false, is_trine: false, is_spiral: false,
|
|
74
|
+
is_convergence: false, is_meridian: false, is_mask: false, is_harmony: false,
|
|
75
|
+
is_rest: false, special_day: '', observance: ''
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
# The Turning (days 1-3)
|
|
65
79
|
if day_of_year <= 3
|
|
66
|
-
|
|
80
|
+
name = TURNING_DAY_NAMES[day_of_year - 1]
|
|
81
|
+
return MetricDate.new(**base.merge(is_turning: true, special_day: name, observance: name))
|
|
67
82
|
end
|
|
68
83
|
|
|
69
84
|
adjusted = day_of_year - 3
|
|
@@ -72,7 +87,8 @@ module MetricCalendar
|
|
|
72
87
|
m = (adjusted - 1) / 30 + 1
|
|
73
88
|
d = (adjusted - 1) % 30 + 1
|
|
74
89
|
elsif adjusted <= 270 + yule_day_count
|
|
75
|
-
|
|
90
|
+
name = YULE_DAY_NAMES[adjusted - 271]
|
|
91
|
+
return MetricDate.new(**base.merge(is_yule: true, special_day: name, observance: name))
|
|
76
92
|
else
|
|
77
93
|
post_yule = adjusted - 270 - yule_day_count
|
|
78
94
|
m = 9 + (post_yule - 1) / 30 + 1
|
|
@@ -82,6 +98,26 @@ module MetricCalendar
|
|
|
82
98
|
week_day = (d - 1) % 10 + 1
|
|
83
99
|
week = (m - 1) * 3 + (d - 1) / 10 + 1
|
|
84
100
|
|
|
101
|
+
is_midsummer = m == 4 && d == 1
|
|
102
|
+
is_sextant = m == 2 && d == 30
|
|
103
|
+
is_trine = m == 4 && d == 30
|
|
104
|
+
is_spiral = m == 5 && d == 18
|
|
105
|
+
is_convergence = m == 5 && d == 24
|
|
106
|
+
is_meridian = m == 6 && d == 30
|
|
107
|
+
is_mask = m == 8 && d == 13
|
|
108
|
+
is_harmony = m == 8 && d == 30
|
|
109
|
+
|
|
110
|
+
observance = if is_midsummer then 'Midsummer'
|
|
111
|
+
elsif is_sextant then 'The Sextant'
|
|
112
|
+
elsif is_trine then 'The Trine'
|
|
113
|
+
elsif is_spiral then 'The Spiral'
|
|
114
|
+
elsif is_convergence then 'Convergence'
|
|
115
|
+
elsif is_meridian then 'The Meridian'
|
|
116
|
+
elsif is_mask then 'The Mask'
|
|
117
|
+
elsif is_harmony then 'Harmony'
|
|
118
|
+
else ''
|
|
119
|
+
end
|
|
120
|
+
|
|
85
121
|
MetricDate.new(
|
|
86
122
|
year: metric_year,
|
|
87
123
|
month: m, month_name: MONTH_NAMES[m - 1],
|
|
@@ -89,13 +125,56 @@ module MetricCalendar
|
|
|
89
125
|
week: week, season_index: (m - 1) / 3,
|
|
90
126
|
is_leap_year: leap,
|
|
91
127
|
is_turning: false, is_yule: false,
|
|
92
|
-
is_midsummer:
|
|
93
|
-
|
|
128
|
+
is_midsummer: is_midsummer,
|
|
129
|
+
is_sextant: is_sextant,
|
|
130
|
+
is_trine: is_trine,
|
|
131
|
+
is_spiral: is_spiral,
|
|
132
|
+
is_convergence: is_convergence,
|
|
133
|
+
is_meridian: is_meridian,
|
|
134
|
+
is_mask: is_mask,
|
|
135
|
+
is_harmony: is_harmony,
|
|
94
136
|
is_rest: week_day >= 8,
|
|
95
|
-
special_day: ''
|
|
137
|
+
special_day: '',
|
|
138
|
+
observance: observance
|
|
96
139
|
)
|
|
97
140
|
end
|
|
98
141
|
|
|
142
|
+
# Format a MetricDate using a pattern string.
|
|
143
|
+
#
|
|
144
|
+
# Tokens:
|
|
145
|
+
# MMM month name (e.g. "Unil")
|
|
146
|
+
# MM month zero-padded (e.g. "01")
|
|
147
|
+
# M month number (e.g. "1")
|
|
148
|
+
# DD day zero-padded (e.g. "04")
|
|
149
|
+
# D day number (e.g. "4")
|
|
150
|
+
# WW weekday name (e.g. "Quintday")
|
|
151
|
+
# W weekday number (e.g. "5")
|
|
152
|
+
# Y year number (e.g. "56")
|
|
153
|
+
# S season name (e.g. "Rising")
|
|
154
|
+
#
|
|
155
|
+
# Example: format(d, "WW, MMM D, Year Y") => "Quintday, Unil 4, Year 56"
|
|
156
|
+
#
|
|
157
|
+
# @param date [MetricDate]
|
|
158
|
+
# @param pattern [String]
|
|
159
|
+
# @return [String]
|
|
160
|
+
def self.format(date, pattern)
|
|
161
|
+
season_name = date.season_index >= 0 && date.season_index <= 3 ? SEASON_NAMES[date.season_index] : ''
|
|
162
|
+
pattern.gsub(FORMAT_RE) do |token|
|
|
163
|
+
case token
|
|
164
|
+
when 'MMM' then date.month_name
|
|
165
|
+
when 'MM' then format('%02d', date.month)
|
|
166
|
+
when 'M' then date.month.to_s
|
|
167
|
+
when 'DD' then format('%02d', date.day)
|
|
168
|
+
when 'D' then date.day.to_s
|
|
169
|
+
when 'WW' then date.day_name
|
|
170
|
+
when 'W' then date.week_day.to_s
|
|
171
|
+
when 'Y' then date.year.to_s
|
|
172
|
+
when 'S' then season_name
|
|
173
|
+
else token
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
99
178
|
# Convert a Metric Calendar date back to a Gregorian Date.
|
|
100
179
|
# @param year [Integer] Metric year
|
|
101
180
|
# @param period_type [String] "turning", "month", or "yule"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: MetricCalendar
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Rabarts
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A Ruby library for working with the Metric Calendar — a rational decimal
|
|
14
14
|
calendar system with 10-day weeks and 12 months of 30 days.
|