fat_core 5.1.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d377f4ea28c3310ce28733b4da66dad3e39dc13be3f5406ab1cce4b4e784924
4
- data.tar.gz: d1e6f6fb84c9211104a87c2e4d596a3637eaacfa5bc82349b3d5baaa2b9657df
3
+ metadata.gz: c2376c4bac5a7a1702ae4361cca280a07b1bfde4304f42fad41e0f37754d41c8
4
+ data.tar.gz: e87c81524e1901bf80443b421d62ad8ebffe7212916f0bd18817625e79795985
5
5
  SHA512:
6
- metadata.gz: 0f81e05b5728f6dc3a7fe556bcd48ff011a006375938afd269ced9d3b6266715118dd5281d7e5c2dd39665257ed8f49a86fc73ddb3d5c3a1f9b1bc728efecb15
7
- data.tar.gz: 8c6fd80723f159aaaf92cf52b249cb194f4394bb8f655963a4287c37523e8212e93ed27c7a9b40be8620bb45773cd47e38a701b0ceead250e1f69fd20fab162a
6
+ metadata.gz: c0b95bc966b857fae1bcfbf2b38dcb8e4275dee5b269091944f2dcd08830162ebf22b98072a49b9b40e1599b7c0f940beeffa4e08f9f6b9f05dc003ba81a3e8c
7
+ data.tar.gz: 6cf190c0656ba641ccfe10a27e832d9bbe2bb71dde2491c97179ae4acc677af884679a4c635aefe40379e5a022dda71549c705cc6c05e71a5e4d7037639c193b
data/.rubocop.yml CHANGED
@@ -1,25 +1,9 @@
1
1
  inherit_from:
2
2
  - ~/.rubocop.yml
3
3
 
4
- # inherit_gem:
5
- # rubocop-shopify: rubocop.yml
4
+ AllCops:
5
+ NewCops: enable
6
+ TargetRubyVersion: 3.0
6
7
 
7
- # require:
8
- # - rubocop-rspec
9
-
10
- # AllCops:
11
- # TargetRubyVersion: 2.7
12
- # Exclude:
13
- # - 'test/tmp/**/*'
14
- # - 'vendor/bundle/**/*'
15
-
16
- # Style/MethodCallWithArgsParentheses:
17
- # Exclude:
18
- # - '**/Gemfile'
19
-
20
- # Style/ClassAndModuleChildren:
21
- # Exclude:
22
- # - 'test/**/*'
23
-
24
- # Style/StringLiterals:
25
- # Enabled: false
8
+ Style/BitwisePredicate:
9
+ Enabled: false
data/Gemfile CHANGED
@@ -1,13 +1,19 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'damerau-levenshtein', git: 'https://github.com/ddoherty03/damerau-levenshtein'
4
- gem 'rubocop-shopify', require: false
5
-
6
3
  # Specify your gem's dependencies in fat_core.gemspec
7
4
  gemspec
8
5
 
9
- # group :debug do
10
- # gem "byebug"
11
- # gem "pry"
12
- # gem "pry-doc"
13
- # end
6
+ group :development do
7
+ gem 'rubocop-shopify', require: false
8
+ gem 'rubocop-rspec', require: false
9
+ gem 'rubocop-performance', require: false
10
+ gem 'rubocop-rake', require: false
11
+ gem 'bundler'
12
+ gem 'debug', '>= 1.0.0'
13
+ gem 'pry'
14
+ gem 'redcarpet'
15
+ gem 'pry-doc'
16
+ gem 'rake'
17
+ gem 'rspec'
18
+ gem 'simplecov'
19
+ end
data/README.org CHANGED
@@ -54,13 +54,11 @@ Many of these have little that is of general interest, but there are a few
54
54
  goodies.
55
55
 
56
56
  *** Date
57
-
58
57
  **** Constants
59
-
60
- ~FatCore~ adds two constants to the ~Date~ class, Date::BOT and Date::EOT.
61
- These represent the earliest and latest dates of practical commercial
62
- interest. The exact values are rather arbitrary, but they prove useful in
63
- date ranges, for example. They are defined as:
58
+ ~FatCore~ adds two date constants to the ~Date~ class, Date::BOT and
59
+ Date::EOT. These represent the earliest and latest dates of practical
60
+ commercial interest. The exact values are rather arbitrary, but they prove
61
+ useful in date ranges, for example. They are defined as:
64
62
 
65
63
  - ~Date::BOT~ :: January 1, 1900
66
64
  - ~Date::EOT~ :: December 31, 3000
@@ -69,7 +67,38 @@ date ranges, for example. They are defined as:
69
67
  - ~Date::PRESIDENTIAL_FUNERALS~ :: an Array of dates of presidential funerals,
70
68
  which are observed with a closing of most federal agencies
71
69
 
72
-
70
+ **** Ensure
71
+ The ~Date.ensure~ class method tries to convert its argument to a ~Date~
72
+ object by (1) applying the ~#to_date~ method or (2) applying the ~Date.parse~
73
+ method to a String. This is handy when you want to define a method that takes
74
+ a date argument but want the caller to be able to supply anything that can
75
+ reasonably be converted to a ~Date~:
76
+
77
+ #+begin_src ruby
78
+ $:.unshift("~/src/fat_core/lib")
79
+ require 'fat_core/date' # => true
80
+
81
+ def tomorow_tomorrow(arg)
82
+ from = Date.ensure(arg) # => ArgumentError: cannot convert class 'Array' to a Date or DateTime
83
+ from + 2.days # => Mon, 03 Jun 2024, Wed, 16 Oct 2024 05:47:30 -0500, Sun, 03 Mar 2024
84
+ end # => :tomorow_tomorrow
85
+
86
+ tomorow_tomorrow('June 1') # => Mon, 03 Jun 2024
87
+ tomorow_tomorrow(Time.now) # => Wed, 16 Oct 2024 05:47:30 -0500
88
+ # But it's only as good as Date.parse!
89
+ tomorow_tomorrow('Ides of March') # => Sun, 03 Mar 2024
90
+
91
+ tomorow_tomorrow([])
92
+ # =>
93
+
94
+ # ~> ArgumentError
95
+ # ~> cannot convert class 'Array' to a Date or DateTime
96
+ # ~>
97
+ # ~> /home/ded/src/fat_core/lib/fat_core/date.rb:1849:in `ensure_date'
98
+ # ~> /home/ded/src/fat_core/lib/fat_core/date.rb:1863:in `ensure'
99
+ # ~> /tmp/seeing_is_believing_temp_dir20241014-1457038-xj4k5x/program.rb:5:in `tomorow_tomorrow'
100
+ # ~> /tmp/seeing_is_believing_temp_dir20241014-1457038-xj4k5x/program.rb:14:in `<main>'
101
+ #+end_src
73
102
 
74
103
  **** Formatting
75
104
 
@@ -88,7 +117,6 @@ that are often useful:
88
117
  puts "American: #{d.american}"
89
118
  #+end_SRC
90
119
 
91
- #+RESULTS:
92
120
  #+begin_example
93
121
  ISO: 1957-09-22
94
122
  All Numbers: 19570922
@@ -112,7 +140,7 @@ convention of using en-dashes to separate the components.
112
140
 
113
141
  Many of the methods provided by ~FatCore~ deal with various calendar periods
114
142
  that are less common than those provided by the Ruby Standard Library or gems
115
- such as ~active_suupor~. This documentation refers to these calendar periods
143
+ such as ~active_support~. This documentation refers to these calendar periods
116
144
  as "chunks", and they are the following:
117
145
 
118
146
  - year,
@@ -134,7 +162,7 @@ or end of each of these chunks:
134
162
  tab = []
135
163
  d = Date.parse('2017-06-30')
136
164
  %i[beginning end].each do |side|
137
- %i(year half quarter bimonth month semimonth biweek week ).each do |chunk|
165
+ %i(year half quarter bimonth month semimonth biweek week).each do |chunk|
138
166
  meth = "#{side}_of_#{chunk}?".to_sym
139
167
  tab << [d.iso, meth.to_s, "#{d.send(meth)}"]
140
168
  end
@@ -231,7 +259,6 @@ You can query which numerical half, quarter, etc. that a given date falls in:
231
259
  objects.
232
260
 
233
261
  ***** American Dates
234
-
235
262
  Americans often write dates in the form M/d/Y, and the normal parse method
236
263
  will parse such a string as d/M/Y, often resulting in invalid date errors.
237
264
  ~FatCore~ adds the specialty parsing method, ~Date.parse_american~ to handle
@@ -256,15 +283,140 @@ Date.parse_american('9/22/1957') => 1957-09-22
256
283
  #+end_example
257
284
 
258
285
  ***** Date Specs
259
-
260
-
286
+ It is often desirable to get the first or last date of a specified time
287
+ period. For this ~FatCore~ provides the ~parse_spec~ method that takes a
288
+ string and an optional ~spec_type~ parameter of either ~:from~, indicating
289
+ that the first date of the period should be returned or ~:to~, indicating that
290
+ the last date of the period should be returned.
291
+
292
+ This method supports a rich set of ways to specify periods of time:
293
+
294
+ - YYYY-MM-DD :: returns a single day as the time period,
295
+ - YYYY-MM :: returns the specified month, beginning or end
296
+ - YYYY :: returns the specified year, beginning or end
297
+ - YYYY-ddd :: returns the ddd'th day of the specified year, beginning or end
298
+ - MM :: returns the specified month of the current year, beginning or end
299
+ - MM-DD :: returns the specified day of the specified month in the current
300
+ year, beginning or end,
301
+ - YYYY-Wnn or YYYY-nnW :: returns the nn'th commercial week of the given year
302
+ according to the ISO 8601 standard, in which the week containing the first
303
+ Thursday of the year counts as the first commercial week, even if that week
304
+ started in the prior calendar year,
305
+ - Wnn or nnW :: returns the nn'th commercial week of the current year,
306
+ - YYYY-1H or YYYY-2H :: returns the specified half year for the given year,
307
+ - 1H or 2H :: returns the specified half year for the current year,
308
+ - YYYY-1Q, YYYY-2Q, etc :: returns the calendar quarter for the given year,
309
+ - 1Q, 2Q, etc :: returns the calendar quarter for the current year,
310
+ - YYYY-MM-I or YYYY-MM-II :: returns the semi-month for the given month and
311
+ year, where the first semi-month always runs from the 1st to the 15th and
312
+ the second semi-month always runs from the 16th to the last day of the given
313
+ month, regardless of the number of days in the month,
314
+ - YYYY-MM-i or YYYY-MM-ii up to YYYY-MM-vi :: returns the given week within
315
+ the month, including any partial weeks,
316
+ - MM-i or MM-ii up to MM-vi :: returns the given week within the month of the
317
+ current year, including any partial weeks,
318
+ - i or ii up to vi :: returns the given week within the current month of the current
319
+ year, including any partial weeks,
320
+ - YYYY-MM-nSu up to YYYY-MM-nSa :: returns the single date that is the n'th
321
+ Sunday, Monday, etc., in the given month using the first two letters of the
322
+ English names for the days of the week,
323
+ - MM-nSu up to MM-nSa :: returns the single date that is the n'th Sunday,
324
+ Monday, etc., in the given month of the current year using the first two
325
+ letters of the English names for the days of the week,
326
+ - nSu up to nSa :: returns the single date that is the n'th Sunday, Monday,
327
+ etc., in the current month of the current year using the first two letters
328
+ of the English names for the days of the week,
329
+ - YYYY-nnn :: is the nnn'th day of the given year, exactly three digits needed,
330
+ - nnn :: is the nnn'th day of the current year, exactly three digits needed,
331
+ - YYYY-E :: returns the single date of Easter in the Western church for the
332
+ given year,
333
+ - E :: returns the single date of Easter in the Western church for the current
334
+ year,
335
+ - YYYY-E-n or YYYY-E+n :: returns the single date that falls n days before (-)
336
+ or after (+) Easter in the Western church for the given year,
337
+ - E-n or E+n :: returns the single date that falls n days before (-) or after
338
+ (+) Easter in the Western church for the current year,
339
+ - yesterday or yesteryear or lastday or last_year, etc :: the relative
340
+ prefixes, 'last' or 'yester' prepended to any chunk name returns the period
341
+ named by the chunk that precedes today's date.
342
+ - today or toyear or this-year or thissemimonth, etc :: the relative prefixes,
343
+ 'to' or 'this' prepended to any chunk name returns the period named by
344
+ the chunk that contains today's date.
345
+ - nextday or nextyear or next-year or nextsemimonth, etc :: the relative
346
+ prefixes, 'next' prepended to any chunk name returns the period named by the
347
+ chunk that follows today's date. As a special case, 'tomorrow' is treated as
348
+ equivalent to 'nextday'.
349
+ - forever :: returns the period Date::BOT to Date::EOT, which, for financial
350
+ applications is meant to stand in for eternity.
351
+ - never :: returns nil, representing no date.
352
+
353
+ Some things to note with respect to ~Date.parse_spec~:
354
+
355
+ 1. The second argument should be either ~:from~ or ~:to~, but it defaults to
356
+ ~:from~. If it is ~:from~, ~parse_spec~ returns the first date of the
357
+ specified period; if it is ~:to~, it returns the last date of the specified
358
+ period. When the "period" resolves to a single day, both arguments return
359
+ the same date, so ~parse_spec('2024-E', :from)~ and ~parse_spec('2024-E',
360
+ :to)~ both result in March 31, 2024.
361
+ 2. Where relevant, ~parse_spec~ accepts letters of either upper or lower case:
362
+ so 2024-1Q can be written 2024-1q and 'yesteryear' can be written
363
+ 'YeSterYeaR', and likewise for all components of the spec using letters.
364
+ 3. Date components can be separated with either a hyphen, as in the examples
365
+ above, or with a '/' as is common. Thus, 2024-11-09 can also be
366
+ 2024/11/09, or indeed, 2024/11-09 or 2024-11/09.
367
+ 4. The prefixes for relative periods can be separated from the period name by
368
+ a hyphen, and underscore, or by nothing at all. Thus, yester-day,
369
+ yester_day, and yesterday are all acceptable. Clearly neologisms such as
370
+ 'yestermonth' are quaint, but not harmful.
371
+ 5. On the other hand, to get a day-of-year spec right, you must use exactly 3
372
+ digits: 2024-011 is the 11th day of 2024, but 2024-11 is November of 2024.
261
373
 
262
374
  **** Holidays and Workdays
263
-
264
- - weekend?
265
- - weekday?
266
-
267
- **** Weekdays in Month
375
+ One of the original motivations for this library was to provide an easy way to
376
+ determine whether a given date is a federal holiday in the United States or,
377
+ nearly but not quite the same, a non-trading day on the New York Stock
378
+ Exchange. To that end, ~FatCore~ provides the following methods:
379
+
380
+ - Date#weekend? -- is this date on a weekend?
381
+ - Date#weekday? -- is this date on a week day?
382
+ - Date#easter_this_year -- the date of Easter in the Date's year
383
+
384
+ Methods concerning Federal holidays:
385
+
386
+ - Date#fed_holiday? -- is this date a Federal holiday? It knows about
387
+ obscurities such as holidays decreed by past Presidents, dates of
388
+ Presidential funerals, and the Federal rule for when holidays fall on a
389
+ weekend, whether it is moved to the prior Friday or the following Monday.
390
+ - Date#fed_workday? -- is it a date when the Federal government is open?,
391
+ inverse of Date#fed_holiday?
392
+ - Date#add_fed_workdays(n) -- n Federal workdays following (or preceding if n
393
+ negative) this date,
394
+ - Date#next_fed_workday -- the next Federal workday following this date,
395
+ - Date#prior_fed_workday -- the previous Federal workday before this date,
396
+ - Date#next_until_fed_workday -- starting with this date, move forward until
397
+ we hit a Federal workday
398
+ - Date#prior_until_fed_workday -- starting with this date, move back until
399
+ we hit a Federal workday
400
+
401
+ And we have similar methods for "holidays" or non-trading days on the NYSE:
402
+
403
+ - Date#nyse_holiday? -- is this date a NYSE holiday?
404
+ - Date#nyse_workday? -- is it a date when the NYSE is open for trading?,
405
+ inverse of Date#nyse_holiday?
406
+ - Date#add_nyse_workdays(n) -- n NYSE workdays following (or preceding if n
407
+ negative) this date,
408
+ - Date#next_nyse_workday -- the next NYSE workday following this date,
409
+ - Date#prior_nyse_workday -- the previous NYSE workday before this date,
410
+ - Date#next_until_nyse_~~workday -- starting with this date, move forward until
411
+ we hit a NYSE workday
412
+ - Date#prior_until_nyse_workday -- starting with this date, move back until
413
+ we hit a Federal workday
414
+
415
+ **** Ordinal Weekdays in Month
416
+ It is often useful to find the 1st, 2nd, etc, Sunday, Monday, etc. in a given
417
+ month. ~FatCore~ provides the class method ~Date.nth_wday_in_year_month(nth,
418
+ wday, year, month)~ to return such dates. The first parameter can be
419
+ negative, which will count from the end of the month.
268
420
 
269
421
  **** Easter
270
422
  The ~Date~ class extension adds two methods for determining whether a given
@@ -325,7 +477,6 @@ coverage on one Range by an Array of other Ranges:
325
477
  (0..12).gaps([(0..2), (5..7), (10..12)]) => [(3..4), (8..9)]
326
478
  #+end_SRC
327
479
 
328
- **
329
480
  * Enumerable
330
481
  FatCore::Enumerable extends Enumerable with the ~#each_with_flags~ method that
331
482
  yields the elements of the Enumerable but also yields two booleans, ~first~ and
data/Rakefile CHANGED
@@ -10,16 +10,23 @@ RDoc::Task.new do |rdoc|
10
10
  end
11
11
 
12
12
  YARD::Rake::YardocTask.new do |t|
13
- t.files = ['lib/**/*.rb', 'README.md']
13
+ t.files = ['lib/**/*.rb', 'README.md']
14
14
  t.options << '--no-private'
15
15
  t.options << '--embed-mixins'
16
16
  t.options << '--markup=markdown'
17
17
  t.options << '--markup-provider=redcarpet'
18
- #t.stats_options = ['--list-undoc']
18
+ # t.stats_options = ['--list-undoc']
19
19
  end
20
20
 
21
21
  RSpec::Core::RakeTask.new(:spec, :tag) do |t|
22
22
  t.rspec_opts = '--tag ~online -f p'
23
23
  end
24
24
 
25
- task :default => :spec
25
+ ########################################################################
26
+ # Rubocop tasks
27
+ ########################################################################
28
+ require 'rubocop/rake_task'
29
+
30
+ RuboCop::RakeTask.new
31
+
32
+ task :default => [:spec, :rubocop]
data/bin/easters CHANGED
@@ -1,17 +1,27 @@
1
- #! /usr/bin/env ruby
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require 'fat_core/date'
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'easters' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
4
10
 
5
- base = Date.new(30, 1, 1)
6
- 3000.times do |k|
7
- dt = Date.new(base.year + k, 1, 1)
8
- easter = dt.easter_this_year
9
- print "%04d: #{easter}" % dt.year
10
- if easter.month == 3 && easter.day <= 23
11
- print easter.day == 22 ? " <<<\n" : " <<\n"
12
- elsif easter.month == 4 && easter.day >= 24
13
- print easter.day == 25 ? " >>>\n" : " >>\n"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
14
18
  else
15
- print "\n"
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
16
21
  end
17
22
  end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("fat_core", "easters")
data/fat_core.gemspec CHANGED
@@ -25,16 +25,6 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^bin/easter}) { |f| File.basename(f) }
26
26
  spec.require_paths = ['lib']
27
27
 
28
- spec.add_development_dependency 'bundler'
29
- spec.add_development_dependency 'debug', '>= 1.0.0'
30
- spec.add_development_dependency 'pry'
31
- spec.add_development_dependency 'pry-doc'
32
- spec.add_development_dependency 'rake'
33
- spec.add_development_dependency 'redcarpet'
34
- spec.add_development_dependency 'rspec'
35
- spec.add_development_dependency 'simplecov'
36
- spec.add_development_dependency 'solargraph'
37
-
38
- spec.add_runtime_dependency 'activesupport'
39
- spec.add_runtime_dependency 'damerau-levenshtein'
28
+ spec.add_dependency 'activesupport'
29
+ spec.add_dependency 'damerau-levenshtein'
40
30
  end