fat_date 0.1.0 → 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/.rubocop.yml +3 -9
- data/.yardopts +4 -0
- data/CHANGELOG.org +8 -3
- data/README.md +685 -0
- data/README.org +205 -155
- data/Rakefile +20 -3
- data/doc/Date.html +153 -0
- data/doc/DateTime.html +148 -0
- data/doc/FatDate/Date/ClassMethods.html +1930 -0
- data/doc/FatDate/Date.html +8319 -0
- data/doc/FatDate/DateTime.html +203 -0
- data/doc/FatDate.html +158 -0
- data/doc/Numeric.html +298 -0
- data/doc/_index.html +167 -0
- data/doc/class_list.html +54 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +490 -0
- data/doc/file.README.html +780 -0
- data/doc/file_list.html +59 -0
- data/doc/frames.html +22 -0
- data/doc/index.html +780 -0
- data/doc/js/app.js +395 -0
- data/doc/js/full_list.js +244 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +814 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/fat_date/date.rb +25 -10
- data/lib/fat_date/date_time.rb +17 -0
- data/lib/fat_date/version.rb +1 -1
- data/lib/fat_date.rb +22 -7
- metadata +41 -3
data/README.org
CHANGED
|
@@ -1,64 +1,59 @@
|
|
|
1
1
|
#+TITLE: FatDate Guide
|
|
2
2
|
#+OPTIONS: toc:5
|
|
3
|
-
#+PROPERTY: header-args:ruby :colnames no :hlines yes :exports both :
|
|
4
|
-
#+PROPERTY: header-args:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
#+PROPERTY: header-args:ruby :results value :colnames no :hlines yes :exports both :dir "./"
|
|
4
|
+
#+PROPERTY: header-args:ruby+ :wrap example :session fat_date_session :eval yes
|
|
5
|
+
#+PROPERTY: header-args:ruby+ :prologue "$:.unshift('./lib') unless $:.first == './lib'; require 'fat_date'"
|
|
6
|
+
#+PROPERTY: header-args:sh :exports code :eval no
|
|
7
|
+
#+PROPERTY: header-args:bash :exports code :eval no
|
|
8
|
+
|
|
9
|
+
#+BEGIN_EXPORT markdown
|
|
10
|
+
[](https://github.com/ddoherty03/fat_date/actions/workflows/ruby.yml)
|
|
11
|
+
#+END_EXPORT
|
|
12
|
+
|
|
13
|
+
* Introduction
|
|
14
|
+
~fat_date~ collects core extensions for the Date class to make it more useful
|
|
15
|
+
in financial applications, including:
|
|
16
|
+
|
|
17
|
+
- determining when a =Date= is a federal or NYSE holiday with Presidential
|
|
18
|
+
decrees included,
|
|
19
|
+
- determining when a =Date= is part of a larger calendar-related "chunk," such
|
|
20
|
+
as a year, half, quarter, bimonth, month, semimonth, or week,
|
|
21
|
+
- calculating Easter for a =Date's= year, a date on which some "movable
|
|
22
|
+
feasts" depend, and
|
|
23
|
+
- parsing so-called "specs" that allow the beginning or ending =Date= of a
|
|
24
|
+
larger period of time to be returned, a facility put to good use in the
|
|
25
|
+
[[https://github.com/ddoherty03/fat_period][FatPeriod]] gem.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
* Version
|
|
29
|
+
|
|
30
|
+
#+begin_src ruby
|
|
31
|
+
FatDate::VERSION
|
|
19
32
|
#+end_src
|
|
20
33
|
|
|
21
34
|
#+RESULTS:
|
|
22
35
|
#+begin_example
|
|
23
|
-
|
|
24
|
-
Ruby LOADPATH:
|
|
25
|
-
./lib
|
|
26
|
-
/home/ded/.rbenv/rbenv.d/exec/gem-rehash
|
|
27
|
-
/home/ded/.rbenv/versions/3.4.1/lib/ruby/site_ruby/3.4.0
|
|
28
|
-
/home/ded/.rbenv/versions/3.4.1/lib/ruby/site_ruby/3.4.0/x86_64-linux
|
|
29
|
-
/home/ded/.rbenv/versions/3.4.1/lib/ruby/site_ruby
|
|
30
|
-
/home/ded/.rbenv/versions/3.4.1/lib/ruby/vendor_ruby/3.4.0
|
|
31
|
-
/home/ded/.rbenv/versions/3.4.1/lib/ruby/vendor_ruby/3.4.0/x86_64-linux
|
|
32
|
-
/home/ded/.rbenv/versions/3.4.1/lib/ruby/vendor_ruby
|
|
33
|
-
/home/ded/.rbenv/versions/3.4.1/lib/ruby/3.4.0
|
|
34
|
-
/home/ded/.rbenv/versions/3.4.1/lib/ruby/3.4.0/x86_64-linux
|
|
35
|
-
...
|
|
36
|
+
0.1.5
|
|
36
37
|
#+end_example
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
* FatDate
|
|
40
|
-
|
|
41
|
-
~fat_date~ is a simple gem to collect core extensions for the Date class to
|
|
42
|
-
make it more useful in financial applications.
|
|
43
|
-
|
|
44
39
|
* Installation
|
|
45
40
|
|
|
46
41
|
Add this line to your application's Gemfile:
|
|
47
42
|
|
|
48
|
-
#+begin_SRC ruby
|
|
43
|
+
#+begin_SRC ruby :eval no
|
|
49
44
|
gem 'fat_date', :git => 'https://github.com/ddoherty03/fat_date.git'
|
|
50
45
|
#+end_SRC
|
|
51
46
|
|
|
52
47
|
And then execute:
|
|
53
48
|
|
|
54
|
-
#+begin_src
|
|
49
|
+
#+begin_src sh
|
|
55
50
|
$ bundle
|
|
56
51
|
#+end_src
|
|
57
52
|
|
|
58
53
|
Or install it yourself as:
|
|
59
54
|
|
|
60
|
-
#+begin_src
|
|
61
|
-
$ gem install
|
|
55
|
+
#+begin_src sh
|
|
56
|
+
$ gem install fat_date
|
|
62
57
|
#+end_src
|
|
63
58
|
|
|
64
59
|
* Usage
|
|
@@ -86,25 +81,39 @@ method to a String. This is handy when you want to define a method that takes
|
|
|
86
81
|
a date argument but want the caller to be able to supply anything that can
|
|
87
82
|
reasonably be converted to a ~Date~:
|
|
88
83
|
|
|
89
|
-
#+begin_src ruby :results
|
|
90
|
-
$:.unshift("~/src/fat_core/lib")
|
|
91
|
-
require 'fat_core/date' # => true
|
|
92
|
-
|
|
84
|
+
#+begin_src ruby :results value raw
|
|
93
85
|
def tomorow_tomorrow(arg)
|
|
94
86
|
from = Date.ensure(arg) # => ArgumentError: cannot convert class 'Array' to a Date or DateTime
|
|
95
87
|
from + 2.days # => Mon, 03 Jun 2024, Wed, 16 Oct 2024 05:47:30 -0500, Sun, 03 Mar 2024
|
|
96
88
|
end # => :tomorow_tomorrow
|
|
97
89
|
|
|
98
|
-
|
|
99
|
-
puts tomorow_tomorrow(Time.now).to_s
|
|
100
|
-
# But it's only as good as Date.parse! If all it sees is 'March', it returns
|
|
101
|
-
# March 1 of the current year.
|
|
102
|
-
puts tomorow_tomorrow('Ides of March').to_s
|
|
90
|
+
tomorow_tomorrow('June 1').to_s
|
|
103
91
|
#+end_src
|
|
104
92
|
|
|
93
|
+
#+RESULTS:
|
|
105
94
|
#+begin_example
|
|
106
95
|
2025-06-03
|
|
107
|
-
|
|
96
|
+
#+end_example
|
|
97
|
+
|
|
98
|
+
If you give it a Time, it will return a ~DateTime~
|
|
99
|
+
#+begin_src ruby :results value raw
|
|
100
|
+
[Time.now, tomorow_tomorrow(Time.now)]
|
|
101
|
+
#+end_src
|
|
102
|
+
|
|
103
|
+
#+RESULTS:
|
|
104
|
+
#+begin_example
|
|
105
|
+
[2025-12-24 08:06:12.733499363 -0600, Fri, 26 Dec 2025 08:06:12 -0600]
|
|
106
|
+
#+end_example
|
|
107
|
+
|
|
108
|
+
But it's only as good as Date.parse! If all it sees is 'March', it returns
|
|
109
|
+
March 1 of the current year.
|
|
110
|
+
|
|
111
|
+
#+begin_src ruby :results value raw
|
|
112
|
+
tomorow_tomorrow('Ides of March').to_s
|
|
113
|
+
#+end_src
|
|
114
|
+
|
|
115
|
+
#+RESULTS:
|
|
116
|
+
#+begin_example
|
|
108
117
|
2025-03-03
|
|
109
118
|
#+end_example
|
|
110
119
|
|
|
@@ -112,26 +121,29 @@ reasonably be converted to a ~Date~:
|
|
|
112
121
|
~FatDate~ provides some concise methods for printing string versions of dates
|
|
113
122
|
that are often useful:
|
|
114
123
|
|
|
115
|
-
#+begin_SRC ruby :results
|
|
116
|
-
require_relative './lib/fat_date'
|
|
124
|
+
#+begin_SRC ruby :results value
|
|
117
125
|
d = Date.parse('1957-09-22')
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
methods = ['iso', 'num', 'tex_quote', 'eng', 'american', 'org']
|
|
127
|
+
tab = []
|
|
128
|
+
tab << ['Description', 'Result']
|
|
129
|
+
tab << nil
|
|
130
|
+
methods.each do |m|
|
|
131
|
+
tab << [m, d.send(m.to_sym)]
|
|
132
|
+
end
|
|
133
|
+
tab << ["org(active: true)", d.org(active: true)]
|
|
125
134
|
#+end_SRC
|
|
126
135
|
|
|
136
|
+
#+RESULTS:
|
|
127
137
|
#+begin_example
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
| Description | Result |
|
|
139
|
+
|-------------------+--------------------|
|
|
140
|
+
| iso | 1957-09-22 |
|
|
141
|
+
| num | 19570922 |
|
|
142
|
+
| tex_quote | 1957--09--22 |
|
|
143
|
+
| eng | September 22, 1957 |
|
|
144
|
+
| american | 9/22/1957 |
|
|
145
|
+
| org | [1957-09-22 Sun] |
|
|
146
|
+
| org(active: true) | <1957-09-22 Sun> |
|
|
135
147
|
#+end_example
|
|
136
148
|
|
|
137
149
|
Most of these are self-explanatory, but a couple are not. The
|
|
@@ -162,9 +174,7 @@ as "chunks", and they are the following:
|
|
|
162
174
|
~FatDate~ provides methods that query whether the date falls on the beginning
|
|
163
175
|
or end of each of these chunks:
|
|
164
176
|
|
|
165
|
-
#+begin_SRC ruby
|
|
166
|
-
require_relative './lib/fat_date'
|
|
167
|
-
|
|
177
|
+
#+begin_SRC ruby
|
|
168
178
|
tab = []
|
|
169
179
|
tab << ['Subject Date', 'Method', 'Result']
|
|
170
180
|
tab << nil
|
|
@@ -178,6 +188,7 @@ or end of each of these chunks:
|
|
|
178
188
|
tab
|
|
179
189
|
#+end_SRC
|
|
180
190
|
|
|
191
|
+
#+RESULTS:
|
|
181
192
|
#+begin_example
|
|
182
193
|
| Subject Date | Method | Result |
|
|
183
194
|
|--------------+-------------------------+--------|
|
|
@@ -203,8 +214,6 @@ It also provides corresponding methods that return the date at the beginning
|
|
|
203
214
|
or end of the calendar chunk, starting at the given date:
|
|
204
215
|
|
|
205
216
|
#+begin_SRC ruby
|
|
206
|
-
require './lib/fat_date'
|
|
207
|
-
|
|
208
217
|
tab = []
|
|
209
218
|
tab << ['Subject Date', 'Method', 'Result']
|
|
210
219
|
tab << nil
|
|
@@ -218,6 +227,7 @@ or end of the calendar chunk, starting at the given date:
|
|
|
218
227
|
tab
|
|
219
228
|
#+end_SRC
|
|
220
229
|
|
|
230
|
+
#+RESULTS:
|
|
221
231
|
#+begin_example
|
|
222
232
|
| Subject Date | Method | Result |
|
|
223
233
|
|--------------+--------------------------+------------|
|
|
@@ -242,8 +252,6 @@ or end of the calendar chunk, starting at the given date:
|
|
|
242
252
|
You can query which numerical half, quarter, etc. that a given date falls in:
|
|
243
253
|
|
|
244
254
|
#+begin_SRC ruby
|
|
245
|
-
require './lib/fat_date'
|
|
246
|
-
|
|
247
255
|
tab = []
|
|
248
256
|
tab << ['Subject Date', 'Method', 'Result']
|
|
249
257
|
tab << nil
|
|
@@ -255,17 +263,18 @@ You can query which numerical half, quarter, etc. that a given date falls in:
|
|
|
255
263
|
tab
|
|
256
264
|
#+end_SRC
|
|
257
265
|
|
|
266
|
+
#+RESULTS:
|
|
258
267
|
#+begin_example
|
|
259
268
|
| Subject Date | Method | Result |
|
|
260
269
|
|--------------+-------------+------------------------|
|
|
261
|
-
| 2017-
|
|
262
|
-
| 2017-
|
|
263
|
-
| 2017-
|
|
264
|
-
| 2017-
|
|
265
|
-
| 2017-05-
|
|
266
|
-
| 2017-
|
|
267
|
-
| 2017-05
|
|
268
|
-
| 2017-07-
|
|
270
|
+
| 2017-05-14 | d.year | in year number 2017 |
|
|
271
|
+
| 2017-07-23 | d.half | in half number 2 |
|
|
272
|
+
| 2017-06-28 | d.quarter | in quarter number 2 |
|
|
273
|
+
| 2017-06-12 | d.bimonth | in bimonth number 3 |
|
|
274
|
+
| 2017-05-24 | d.month | in month number 5 |
|
|
275
|
+
| 2017-06-16 | d.semimonth | in semimonth number 12 |
|
|
276
|
+
| 2017-06-05 | d.biweek | in biweek number 12 |
|
|
277
|
+
| 2017-07-16 | d.week | in week number 28 |
|
|
269
278
|
#+end_example
|
|
270
279
|
|
|
271
280
|
*** Parsing American Dates
|
|
@@ -275,8 +284,6 @@ will parse such a string as d/M/Y, often resulting in invalid date errors.
|
|
|
275
284
|
such strings.
|
|
276
285
|
|
|
277
286
|
#+begin_SRC ruby :results output
|
|
278
|
-
require './lib/fat_date'
|
|
279
|
-
|
|
280
287
|
begin
|
|
281
288
|
ss = '9/22/1957'
|
|
282
289
|
Date.parse(ss)
|
|
@@ -286,9 +293,13 @@ such strings.
|
|
|
286
293
|
end
|
|
287
294
|
#+end_SRC
|
|
288
295
|
|
|
296
|
+
#+RESULTS:
|
|
289
297
|
#+begin_example
|
|
298
|
+
=> false
|
|
290
299
|
Date.parse('9/22/1957') raises Date::Error (invalid date), but
|
|
291
300
|
Date.parse_american('9/22/1957') => 1957-09-22
|
|
301
|
+
=> nil
|
|
302
|
+
:org_babel_ruby_eoe
|
|
292
303
|
#+end_example
|
|
293
304
|
|
|
294
305
|
*** Holidays and Workdays
|
|
@@ -319,22 +330,52 @@ Methods concerning Federal holidays:
|
|
|
319
330
|
- Date#prior_until_fed_workday -- starting with this date, move back until
|
|
320
331
|
we hit a Federal workday
|
|
321
332
|
|
|
322
|
-
|
|
323
|
-
|
|
333
|
+
Whether a particular date is a federal holiday is complicated. Certain
|
|
334
|
+
holidays are statutory as set forth in [[https://www.govinfo.gov/content/pkg/USCODE-2024-title5/pdf/USCODE-2024-title5-partIII-subpartE-chap61-subchapI-sec6103.pdf][5 U.S.C. §6103]]. But if the holiday
|
|
335
|
+
falls on a Saturday, the prior Friday is observed; if on a Sunday, the
|
|
336
|
+
following Monday is observed. Inauguration Day after 1965 is observed by
|
|
337
|
+
employees in Washington, D.C., and surrounding areas, effectively shutting
|
|
338
|
+
down most federal agencies.
|
|
339
|
+
|
|
340
|
+
On top of that the days of Presidential funeral are federal holidays. On
|
|
341
|
+
top of that, each President can decree temporary holidays by Executive
|
|
342
|
+
Order, often to give employees Christmas Eve and the day after Christmas the
|
|
343
|
+
day off if they would not otherwise be off. The ~fat_date~ library attempts
|
|
344
|
+
to capture all of this, but the days of Presidential decrees are only good
|
|
345
|
+
for the last decade or so.
|
|
324
346
|
|
|
347
|
+
Here is a sampling:
|
|
325
348
|
|
|
349
|
+
#+begin_SRC ruby
|
|
326
350
|
result = []
|
|
327
351
|
result << ['Date', 'Federal Holiday?', 'Comment']
|
|
328
352
|
result << nil
|
|
353
|
+
result << ['2014-05-16', Date.parse('2014-05-16').fed_holiday?, 'Nuttin special']
|
|
329
354
|
result << ['2014-05-18', Date.parse('2014-05-18').fed_holiday?, 'A weekend']
|
|
330
|
-
result << ['2014-01-01', Date.parse('2014-
|
|
355
|
+
result << ['2014-01-01', Date.parse('2014-01-01').fed_holiday?, 'New Year']
|
|
356
|
+
result << ['1963-11-25', Date.parse('1963-11-25').fed_holiday?, 'JFK Funeral']
|
|
357
|
+
result << ['1973-01-25', Date.parse('1973-01-25').fed_holiday?, 'LBJ Funeral']
|
|
358
|
+
result << ['2003-12-25', Date.parse('2003-12-25').fed_holiday?, 'Christmas']
|
|
359
|
+
result << ['1961-01-20', Date.parse('1961-01-20').fed_holiday?, 'JFK Inauguration (before 1965)']
|
|
360
|
+
result << ['1969-01-20', Date.parse('1969-01-20').fed_holiday?, 'RMN Inauguration (after 1965)']
|
|
361
|
+
result << ['2012-12-24', Date.parse('2012-12-24').fed_holiday?, 'Christmas Eve Decreed by Obama']
|
|
362
|
+
result << ['2003-12-26', Date.parse('2003-12-26').fed_holiday?, 'Friday after Christmas']
|
|
331
363
|
#+end_SRC
|
|
332
364
|
|
|
365
|
+
#+RESULTS:
|
|
333
366
|
#+begin_example
|
|
334
|
-
| Date | Federal Holiday? | Comment
|
|
335
|
-
|
|
336
|
-
| 2014-05-
|
|
337
|
-
| 2014-
|
|
367
|
+
| Date | Federal Holiday? | Comment |
|
|
368
|
+
|------------+------------------+--------------------------------|
|
|
369
|
+
| 2014-05-16 | false | Nuttin special |
|
|
370
|
+
| 2014-05-18 | true | A weekend |
|
|
371
|
+
| 2014-01-01 | true | New Year |
|
|
372
|
+
| 1963-11-25 | true | JFK Funeral |
|
|
373
|
+
| 1973-01-25 | true | LBJ Funeral |
|
|
374
|
+
| 2003-12-25 | true | Christmas |
|
|
375
|
+
| 1961-01-20 | false | JFK Inauguration (before 1965) |
|
|
376
|
+
| 1969-01-20 | true | RMN Inauguration (after 1965) |
|
|
377
|
+
| 2012-12-24 | true | Christmas Eve Decreed by Obama |
|
|
378
|
+
| 2003-12-26 | true | Friday after Christmas |
|
|
338
379
|
#+end_example
|
|
339
380
|
|
|
340
381
|
**** NYSE
|
|
@@ -355,19 +396,16 @@ And we have similar methods for "holidays" or non-trading days on the NYSE:
|
|
|
355
396
|
|
|
356
397
|
Likewise, days on which the NYSE is closed can be gotten with:
|
|
357
398
|
|
|
358
|
-
#+begin_SRC ruby :results
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
puts Date.parse('2014-04-18').nyse_holiday?
|
|
399
|
+
#+begin_SRC ruby :results value raw
|
|
400
|
+
Date.parse('2014-04-18').nyse_holiday?
|
|
362
401
|
#+end_SRC
|
|
363
402
|
|
|
403
|
+
#+RESULTS:
|
|
364
404
|
#+begin_example
|
|
365
405
|
true
|
|
366
406
|
#+end_example
|
|
367
407
|
|
|
368
408
|
#+begin_SRC ruby :results value
|
|
369
|
-
require './lib/fat_date'
|
|
370
|
-
|
|
371
409
|
date_comments = [
|
|
372
410
|
['2014-04-18', 'Good Friday'],
|
|
373
411
|
['2014-05-18', 'Weekend'],
|
|
@@ -384,6 +422,7 @@ true
|
|
|
384
422
|
result
|
|
385
423
|
#+end_SRC
|
|
386
424
|
|
|
425
|
+
#+RESULTS:
|
|
387
426
|
#+begin_example
|
|
388
427
|
| Date | Federal Holiday? | NYSE Holiday? | Comment |
|
|
389
428
|
|------------------+------------------+---------------+-------------|
|
|
@@ -393,6 +432,7 @@ true
|
|
|
393
432
|
| [2014-01-01 Wed] | true | true | New Year |
|
|
394
433
|
#+end_example
|
|
395
434
|
|
|
435
|
+
|
|
396
436
|
*** Ordinal Weekdays in Month
|
|
397
437
|
It is often useful to find the 1st, 2nd, etc, Sunday, Monday, etc. in a given
|
|
398
438
|
month. ~FatDate~ provides the class method ~Date.nth_wday_in_year_month(nth,
|
|
@@ -400,8 +440,6 @@ wday, year, month)~ to return such dates. The first parameter can be
|
|
|
400
440
|
negative, which will count from the end of the month.
|
|
401
441
|
|
|
402
442
|
#+begin_src ruby
|
|
403
|
-
require './lib/fat_date'
|
|
404
|
-
|
|
405
443
|
results = []
|
|
406
444
|
results << ['n', 'Year', 'Month', 'nth Thursday']
|
|
407
445
|
results << nil
|
|
@@ -416,6 +454,7 @@ negative, which will count from the end of the month.
|
|
|
416
454
|
results
|
|
417
455
|
#+end_src
|
|
418
456
|
|
|
457
|
+
#+RESULTS:
|
|
419
458
|
#+begin_example
|
|
420
459
|
| n | Year | Month | nth Thursday |
|
|
421
460
|
|----+------+-------+------------------|
|
|
@@ -448,8 +487,6 @@ the reform happened after Easter in 1752.
|
|
|
448
487
|
- Date#easter? :: return whether the subject Date is Easter.
|
|
449
488
|
|
|
450
489
|
#+begin_src ruby
|
|
451
|
-
require './lib/fat_date'
|
|
452
|
-
|
|
453
490
|
yrs = [800, 1000, 1200, 1400, 1500, 1600, 1800, 2000]
|
|
454
491
|
result = []
|
|
455
492
|
result << ['Year', 'Easter Date']
|
|
@@ -460,6 +497,7 @@ the reform happened after Easter in 1752.
|
|
|
460
497
|
result
|
|
461
498
|
#+end_src
|
|
462
499
|
|
|
500
|
+
#+RESULTS:
|
|
463
501
|
#+begin_example
|
|
464
502
|
| Year | Easter Date |
|
|
465
503
|
|------+------------------|
|
|
@@ -473,7 +511,6 @@ the reform happened after Easter in 1752.
|
|
|
473
511
|
| 2000 | [2000-04-23 Sun] |
|
|
474
512
|
#+end_example
|
|
475
513
|
|
|
476
|
-
|
|
477
514
|
*** Date Specs
|
|
478
515
|
It is often desirable to get the first or last date of a specified time
|
|
479
516
|
period. For this ~FatDate~ provides the ~spec~ method that takes a string and
|
|
@@ -597,13 +634,13 @@ modifier' to change the date to the first day-of-week adjacent to the date
|
|
|
597
634
|
that the spec resolves to. This is done by appending one of the following to
|
|
598
635
|
the spec:
|
|
599
636
|
|
|
600
|
-
- '<Su', '<Mo', ... '<Sa' ::
|
|
637
|
+
- '<Su', '<Mo', ... '<Sa' :: skip to the first Sunday, Monday, etc.,
|
|
601
638
|
/before/ the date the spec resolves to.
|
|
602
|
-
- '<=Su', '<=Mo', ... '<=Sa' ::
|
|
639
|
+
- '<=Su', '<=Mo', ... '<=Sa' :: skip to the first Sunday, Monday, etc., /on
|
|
603
640
|
or before/ the date the spec resolves to.
|
|
604
|
-
- '>Su', '>Mo', ... '>Sa' ::
|
|
641
|
+
- '>Su', '>Mo', ... '>Sa' :: skip to the first Sunday, Monday, etc.,
|
|
605
642
|
/after/ the date the spec resolves to.
|
|
606
|
-
- '>=Su', '>=Mo', ... '>=Sa' ::
|
|
643
|
+
- '>=Su', '>=Mo', ... '>=Sa' :: skip to the first Sunday, Monday, etc., /on
|
|
607
644
|
or after/ the date the spec resolves to.
|
|
608
645
|
|
|
609
646
|
For example, ~Date.spec('2024<=Tu', :to)~ resolves to the last Tuesday
|
|
@@ -636,21 +673,22 @@ Some things to note with respect to ~Date.spec~:
|
|
|
636
673
|
6. 'fortnight' is a synonym for a biweek.
|
|
637
674
|
|
|
638
675
|
**** Examples
|
|
676
|
+
The following examples demonstrate all of the date specs available.
|
|
639
677
|
|
|
640
678
|
#+begin_src ruby results :value
|
|
641
|
-
require './lib/fat_date'
|
|
642
|
-
|
|
643
679
|
strs = ['today', '2024-07-04', '2024-05', '2024', '2024-333',
|
|
644
680
|
'08', '08-12', '2024-W36', '2024-36W', 'W36', '36W',
|
|
645
681
|
'2024-1H', '2024-2H', '1H', '2H',
|
|
646
682
|
'1957-1Q', '1957-2Q', '1957-3Q', '1957-4Q',
|
|
647
683
|
'1Q', '2Q', '3Q', '4Q',
|
|
684
|
+
'2015-06-A', '2015-06-B', '06-A', '06-B', 'A', 'B',
|
|
648
685
|
'2021-09-I', '2021-09-II',
|
|
649
686
|
'2021-09-i', '2021-09-ii', '2021-09-iii', '2021-09-iv', '2021-09-v',
|
|
650
687
|
'10-i', '10-iii',
|
|
651
688
|
'2016-04-3Tu', '2016-11-4Th', '2016-11-2Th',
|
|
652
689
|
'05-3We', '06-3Wed', '3Su', '4Sa',
|
|
653
|
-
'1830-E', 'E', '2012-E+10', '2024-E+40',
|
|
690
|
+
'1830-E', 'E', '2012-E+10', '2024-E+40', '2026-E<Fri',
|
|
691
|
+
'yestermonth', 'lastmonth', 'yesterfortnight', 'thisfortnight', 'nextfortnight',
|
|
654
692
|
'2025-E+50>=Su'
|
|
655
693
|
]
|
|
656
694
|
tab = []
|
|
@@ -662,58 +700,70 @@ Some things to note with respect to ~Date.spec~:
|
|
|
662
700
|
tab
|
|
663
701
|
#+end_src
|
|
664
702
|
|
|
703
|
+
#+RESULTS:
|
|
665
704
|
#+begin_example
|
|
666
|
-
| Spec
|
|
667
|
-
|
|
668
|
-
| 'today'
|
|
669
|
-
| '2024-07-04'
|
|
670
|
-
| '2024-05'
|
|
671
|
-
| '2024'
|
|
672
|
-
| '2024-333'
|
|
673
|
-
| '08'
|
|
674
|
-
| '08-12'
|
|
675
|
-
| '2024-W36'
|
|
676
|
-
| '2024-36W'
|
|
677
|
-
| 'W36'
|
|
678
|
-
| '36W'
|
|
679
|
-
| '2024-1H'
|
|
680
|
-
| '2024-2H'
|
|
681
|
-
| '1H'
|
|
682
|
-
| '2H'
|
|
683
|
-
| '1957-1Q'
|
|
684
|
-
| '1957-2Q'
|
|
685
|
-
| '1957-3Q'
|
|
686
|
-
| '1957-4Q'
|
|
687
|
-
| '1Q'
|
|
688
|
-
| '2Q'
|
|
689
|
-
| '3Q'
|
|
690
|
-
| '4Q'
|
|
691
|
-
| '
|
|
692
|
-
| '
|
|
693
|
-
| '
|
|
694
|
-
| '
|
|
695
|
-
| '
|
|
696
|
-
| '
|
|
697
|
-
| '2021-09-
|
|
698
|
-
| '
|
|
699
|
-
| '
|
|
700
|
-
| '
|
|
701
|
-
| '
|
|
702
|
-
| '
|
|
703
|
-
| '
|
|
704
|
-
| '
|
|
705
|
-
| '
|
|
706
|
-
| '
|
|
707
|
-
| '
|
|
708
|
-
| '
|
|
709
|
-
| '
|
|
710
|
-
| '
|
|
711
|
-
| '
|
|
705
|
+
| Spec | From | To |
|
|
706
|
+
|-------------------+------------------+------------------|
|
|
707
|
+
| 'today' | [2025-12-24 Wed] | [2025-12-24 Wed] |
|
|
708
|
+
| '2024-07-04' | [2024-07-04 Thu] | [2024-07-04 Thu] |
|
|
709
|
+
| '2024-05' | [2024-05-01 Wed] | [2024-05-31 Fri] |
|
|
710
|
+
| '2024' | [2024-01-01 Mon] | [2024-12-31 Tue] |
|
|
711
|
+
| '2024-333' | [2024-11-28 Thu] | [2024-11-28 Thu] |
|
|
712
|
+
| '08' | [2025-08-01 Fri] | [2025-08-31 Sun] |
|
|
713
|
+
| '08-12' | [2025-08-12 Tue] | [2025-08-12 Tue] |
|
|
714
|
+
| '2024-W36' | [2024-09-02 Mon] | [2024-09-08 Sun] |
|
|
715
|
+
| '2024-36W' | [2024-09-02 Mon] | [2024-09-08 Sun] |
|
|
716
|
+
| 'W36' | [2025-09-01 Mon] | [2025-09-07 Sun] |
|
|
717
|
+
| '36W' | [2025-09-01 Mon] | [2025-09-07 Sun] |
|
|
718
|
+
| '2024-1H' | [2024-01-01 Mon] | [2024-06-30 Sun] |
|
|
719
|
+
| '2024-2H' | [2024-07-01 Mon] | [2024-12-31 Tue] |
|
|
720
|
+
| '1H' | [2025-01-01 Wed] | [2025-06-30 Mon] |
|
|
721
|
+
| '2H' | [2025-07-01 Tue] | [2025-12-31 Wed] |
|
|
722
|
+
| '1957-1Q' | [1957-01-01 Tue] | [1957-03-31 Sun] |
|
|
723
|
+
| '1957-2Q' | [1957-04-01 Mon] | [1957-06-30 Sun] |
|
|
724
|
+
| '1957-3Q' | [1957-07-01 Mon] | [1957-09-30 Mon] |
|
|
725
|
+
| '1957-4Q' | [1957-10-01 Tue] | [1957-12-31 Tue] |
|
|
726
|
+
| '1Q' | [2025-01-01 Wed] | [2025-03-31 Mon] |
|
|
727
|
+
| '2Q' | [2025-04-01 Tue] | [2025-06-30 Mon] |
|
|
728
|
+
| '3Q' | [2025-07-01 Tue] | [2025-09-30 Tue] |
|
|
729
|
+
| '4Q' | [2025-10-01 Wed] | [2025-12-31 Wed] |
|
|
730
|
+
| '2015-06-A' | [2015-06-01 Mon] | [2015-06-15 Mon] |
|
|
731
|
+
| '2015-06-B' | [2015-06-16 Tue] | [2015-06-30 Tue] |
|
|
732
|
+
| '06-A' | [2025-06-01 Sun] | [2025-06-15 Sun] |
|
|
733
|
+
| '06-B' | [2025-06-16 Mon] | [2025-06-30 Mon] |
|
|
734
|
+
| 'A' | [2025-12-01 Mon] | [2025-12-15 Mon] |
|
|
735
|
+
| 'B' | [2025-12-16 Tue] | [2025-12-31 Wed] |
|
|
736
|
+
| '2021-09-I' | [2021-09-01 Wed] | [2021-09-05 Sun] |
|
|
737
|
+
| '2021-09-II' | [2021-09-06 Mon] | [2021-09-12 Sun] |
|
|
738
|
+
| '2021-09-i' | [2021-09-01 Wed] | [2021-09-05 Sun] |
|
|
739
|
+
| '2021-09-ii' | [2021-09-06 Mon] | [2021-09-12 Sun] |
|
|
740
|
+
| '2021-09-iii' | [2021-09-13 Mon] | [2021-09-19 Sun] |
|
|
741
|
+
| '2021-09-iv' | [2021-09-20 Mon] | [2021-09-26 Sun] |
|
|
742
|
+
| '2021-09-v' | [2021-09-27 Mon] | [2021-09-30 Thu] |
|
|
743
|
+
| '10-i' | [2025-10-01 Wed] | [2025-10-05 Sun] |
|
|
744
|
+
| '10-iii' | [2025-10-13 Mon] | [2025-10-19 Sun] |
|
|
745
|
+
| '2016-04-3Tu' | [2016-04-19 Tue] | [2016-04-19 Tue] |
|
|
746
|
+
| '2016-11-4Th' | [2016-11-24 Thu] | [2016-11-24 Thu] |
|
|
747
|
+
| '2016-11-2Th' | [2016-11-10 Thu] | [2016-11-10 Thu] |
|
|
748
|
+
| '05-3We' | [2025-05-21 Wed] | [2025-05-21 Wed] |
|
|
749
|
+
| '06-3Wed' | [2025-06-18 Wed] | [2025-06-18 Wed] |
|
|
750
|
+
| '3Su' | [2025-12-21 Sun] | [2025-12-21 Sun] |
|
|
751
|
+
| '4Sa' | [2025-12-27 Sat] | [2025-12-27 Sat] |
|
|
752
|
+
| '1830-E' | [1830-04-11 Sun] | [1830-04-11 Sun] |
|
|
753
|
+
| 'E' | [2025-04-20 Sun] | [2025-04-20 Sun] |
|
|
754
|
+
| '2012-E+10' | [2012-04-18 Wed] | [2012-04-18 Wed] |
|
|
755
|
+
| '2024-E+40' | [2024-05-10 Fri] | [2024-05-10 Fri] |
|
|
756
|
+
| '2026-E<Fri' | [2026-04-03 Fri] | [2026-04-03 Fri] |
|
|
757
|
+
| 'yestermonth' | [2025-11-01 Sat] | [2025-11-30 Sun] |
|
|
758
|
+
| 'lastmonth' | [2025-11-01 Sat] | [2025-11-30 Sun] |
|
|
759
|
+
| 'yesterfortnight' | [2025-12-08 Mon] | [2025-12-21 Sun] |
|
|
760
|
+
| 'thisfortnight' | [2025-12-22 Mon] | [2026-01-04 Sun] |
|
|
761
|
+
| 'nextfortnight' | [2026-01-05 Mon] | [2026-01-18 Sun] |
|
|
762
|
+
| '2025-E+50>=Su' | [2025-06-15 Sun] | [2025-06-15 Sun] |
|
|
712
763
|
#+end_example
|
|
713
764
|
|
|
714
765
|
* Contributing
|
|
715
|
-
|
|
716
|
-
1. Fork it ([[http://github.com/ddoherty03/fat_core/fork]] )
|
|
766
|
+
1. Fork it ([[http://github.com/ddoherty03/fat_date/fork]] )
|
|
717
767
|
2. Create your feature branch (~git checkout -b my-new-feature~)
|
|
718
768
|
3. Commit your changes (~git commit -am 'Add some feature'~)
|
|
719
769
|
4. Push to the branch (~git push origin my-new-feature~)
|
data/Rakefile
CHANGED
|
@@ -5,8 +5,25 @@ require "rspec/core/rake_task"
|
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
-
require
|
|
8
|
+
require 'gem_docs'
|
|
9
|
+
GemDocs.install
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
########################################################################
|
|
12
|
+
# Rubocop tasks
|
|
13
|
+
########################################################################
|
|
14
|
+
# Option A (recommended): Keep using Bundler and run rubocop via `bundle exec`.
|
|
15
|
+
# This wrapper task ensures the rubocop run uses the gems from your Gemfile,
|
|
16
|
+
# even when you invoke `rake rubocop` (no need to remember `bundle exec rake`).
|
|
17
|
+
#
|
|
18
|
+
# You can pass extra RuboCop CLI flags with the RUBOCOP_OPTS environment variable:
|
|
19
|
+
# RUBOCOP_OPTS="--format simple" rake rubocop
|
|
11
20
|
|
|
12
|
-
|
|
21
|
+
desc "Run rubocop under `bundle exec`"
|
|
22
|
+
task :rubocop do
|
|
23
|
+
opts = (ENV['RUBOCOP_OPTS'] || '').split
|
|
24
|
+
Bundler.with_unbundled_env do
|
|
25
|
+
sh 'bundle', 'exec', 'rubocop', *opts
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
task :default => [:spec, :rubocop]
|