Class: Date

Inherits:
Object
  • Object
show all
Defined in:
lib/fat_core/date.rb

Constant Summary collapse

BOT =

Constants for Begining of Time (BOT) and End of Time (EOT) Both outside the range of what we would find in an accounting app.

Date.parse('1900-01-01')
EOT =
Date.parse('3000-12-31')
FED_DECLARED_HOLIDAYS =

Holidays decreed by executive order

[
 Date.parse('2012-12-24')
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.days_in_month(y, m) ⇒ Object



401
402
403
404
405
# File 'lib/fat_core/date.rb', line 401

def self.days_in_month(y, m)
  days = Time::COMMON_YEAR_DAYS_IN_MONTH[m]
  return(days) unless m == 2
  return Date.new(y, m, 1).leap? ? 29 : 28
end

.last_day_in_year_month(year, month) ⇒ Object



444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
# File 'lib/fat_core/date.rb', line 444

def self.last_day_in_year_month(year, month)
  days = [
          31, # Dec
          31, # Jan
          28, # Feb
          31, # Mar
          30, # Apr
          31, # May
          30, # Jun
          31, # Jul
          31, # Aug
          30, # Sep
          31, # Oct
          30, # Nov
          31, # Dec
         ]
  days[2] = 29 if Date.new(year, month, 1).leap?
  days[month % 12]
end

.nth_wday_in_year_month(n, wday, year, month) ⇒ Object



407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/fat_core/date.rb', line 407

def self.nth_wday_in_year_month(n, wday, year, month)
  # Return the nth weekday in the given month
  # If n is negative, count from last day of month
  if n > 0
    # Set d to the 1st wday in month
    d = Date.new(year, month, 1)
    while d.wday != wday
      d += 1
    end
    # Set d to the nth wday in month
    nd = 1
    while nd != n
      d += 7
      nd += 1
    end
    return d
  elsif n < 0
    n = -n
    # Set d to the last wday in month
    d = Date.new(year, month,
                 Date.last_day_in_year_month(year, month))
    while d.wday != wday;
      d -= 1
    end
    # Set d to the nth wday in month
    nd = 1
    while nd != n
      d -= 7
      nd += 1
    end
    return d
  else
    raise ArgumentError,
      'Arg 1 to nth_wday_in_month_year cannot be zero'
  end
end

.parse_american(str) ⇒ Date

Convert a string with an American style date into a Date object

An American style date is of the form MM/DD/YYYY, that is it places the month first, then the day of the month, and finally the year. The European convention is to place the day of the month first, DD/MM/YYYY. Because a date found in the wild can be ambiguous, e.g. 3/5/2014, a date string known to be using the American convention can be parsed using this method. Both the month and the day can be a single digit. The year can be either 2 or 4 digits, and if given as 2 digits, it adds 2000 to it to give the year.

Examples:

Date.parse_american('9/11/2001') #=> Date(2011, 9, 11)
Date.parse_american('9/11/01')   #=> Date(2011, 9, 11)
Date.parse_american('9/11/1')    #=> ArgumentError

Parameters:

  • str (#to_s)

    a stringling of the form MM/DD/YYYY

Returns:

  • (Date)

    the date represented by the string paramenter.



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/fat_core/date.rb', line 27

def self.parse_american(str)
  if str.to_s =~ %r{\A\s*(\d\d?)\s*/\s*(\d\d?)\s*/\s*(\d?\d?\d\d)\s*\z}
    year, month, day = $3.to_i, $1.to_i, $2.to_i
    if year < 100
      year += 2000
    end
    Date.new(year, month, day)
  else
    raise ArgumentError, "date string must be of form 'MM?/DD?/YY(YY)?'"
  end
end

.parse_spec(spec, spec_type = :from) ⇒ Object

Convert a ‘date spec’ to a Date. A date spec is a short-hand way of

specifying a date, relative to the computer clock.  A date spec can
interpreted as either a 'from spec' or a 'to spec'.

@example
Assuming that Date.current at the time of execution is 2014-07-26 and
using the default spec_type of :from.  The return values are actually Date
objects, but are shown below as textual dates.

A fully specified date returns that date:
    Date.parse_spec('2001-09-11')  # =>

Commercial weeks can be specified using, for example W32 or 32W, with the
week beginning on Monday, ending on Sunday.
    Date.parse_spec('2012-W32')    # =>
    Date.parse_spec('2012-W32', :to) # =>
    Date.parse_spec('W32') # =>

A spec of the form Q3 or 3Q returns the beginning or end of calendar
quarters.
    Date.parse_spec('Q3')         # =>

@param spec [#to_s] a stringling containing the spec to be interpreted
@param spec_type [:from, :to] interpret the spec as a from- or to-spec
  respectively, defaulting to interpretation as a to-spec.
@return [Date] a date object equivalent to the date spec


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/fat_core/date.rb', line 67

def self.parse_spec(spec, spec_type = :from)
  spec = spec.to_s.strip
  unless [:from, :to].include?(spec_type)
    raise ArgumentError "invalid date spec type: '#{spec_type}'"
  end

  today = Date.current
  case spec
  when /^(\d\d\d\d)-(\d\d?)-(\d\d?)*$/
    # A specified date
    Date.new($1.to_i, $2.to_i, $3.to_i)
  when /\AW(\d\d?)\z/, /\A(\d\d?)W\z/
    week_num = $1.to_i
    if week_num < 1 || week_num > 53
      raise ArgumentError, "invalid week number (1-53): 'W#{week_num}'"
    end
    spec_type == :from ? Date.commercial(today.year, week_num).beginning_of_week :
      Date.commercial(today.year, week_num).end_of_week
  when /\A(\d\d\d\d)-W(\d\d?)\z/, /\A(\d\d\d\d)-(\d\d?)W\z/
    year = $1.to_i
    week_num = $2.to_i
    if week_num < 1 || week_num > 53
      raise ArgumentError, "invalid week number (1-53): 'W#{week_num}'"
    end
    spec_type == :from ? Date.commercial(year, week_num).beginning_of_week :
      Date.commercial(year, week_num).end_of_week
  when /^(\d\d\d\d)-(\d)[Qq]$/, /^(\d\d\d\d)-[Qq](\d)$/
    # Year-Quarter
    year = $1.to_i
    quarter = $2.to_i
    unless [1, 2, 3, 4].include?(quarter)
      raise ArgumentError, "bad date format: #{spec}"
    end
    month = quarter * 3
    spec_type == :from ? Date.new(year, month, 1).beginning_of_quarter :
      Date.new(year, month, 1).end_of_quarter
  when /^([1234])[qQ]$/, /^[qQ]([1234])$/
    # Quarter only
    this_year = today.year
    quarter = $1.to_i
    date = Date.new(this_year, quarter * 3, 15)
    spec_type == :from ? date.beginning_of_quarter : date.end_of_quarter
  when /^(\d\d\d\d)-(\d\d?)*$/
    # Year-Month only
    spec_type == :from ? Date.new($1.to_i, $2.to_i, 1) :
      Date.new($1.to_i, $2.to_i, 1).end_of_month
  when /\A(\d\d?)\z/
    # Month only
    spec_type == :from ? Date.new(today.year, $1.to_i, 1) :
      Date.new(today.year, $1.to_i, 1).end_of_month
  when /^(\d\d\d\d)$/
    # Year only
    spec_type == :from ? Date.new($1.to_i, 1, 1) : Date.new($1.to_i, 12, 31)
  when /^(to|this_?)?day/
    today
  when /^(yester|last_?)?day/
    today - 1.day
  when /^(this_?)?week/
    spec_type == :from ? today.beginning_of_week : today.end_of_week
  when /last_?week/
    spec_type == :from ? (today - 1.week).beginning_of_week :
      (today - 1.week).end_of_week
  when /^(this_?)?biweek/
    spec_type == :from ? today.beginning_of_biweek : today.end_of_biweek
  when /last_?biweek/
    spec_type == :from ? (today - 1.week).beginning_of_biweek :
      (today - 1.week).end_of_biweek
  when /^(this_?)?semimonth/
    spec_type == :from ? today.beginning_of_semimonth : today.end_of_semimonth
  when /^last_?semimonth/
    spec_type == :from ? (today - 15.days).beginning_of_semimonth :
      (today - 15.days).end_of_semimonth
  when /^(this_?)?month/
    spec_type == :from ? today.beginning_of_month : today.end_of_month
  when /^last_?month/
    spec_type == :from ? (today - 1.month).beginning_of_month :
      (today - 1.month).end_of_month
  when /^(this_?)?bimonth/
    spec_type == :from ? today.beginning_of_bimonth : today.end_of_bimonth
  when /^last_?bimonth/
    spec_type == :from ? (today - 1.month).beginning_of_bimonth :
      (today - 1.month).end_of_bimonth
  when /^(this_?)?quarter/
    spec_type == :from ? today.beginning_of_quarter : today.end_of_quarter
  when /^last_?quarter/
    spec_type == :from ? (today - 3.months).beginning_of_quarter :
      (today - 3.months).end_of_quarter
  when /^(this_?)?year/
    spec_type == :from ? today.beginning_of_year : today.end_of_year
  when /^last_?year/
    spec_type == :from ? (today - 1.year).beginning_of_year :
      (today - 1.year).end_of_year
  when /^forever/
    spec_type == :from ? Date::BOT : Date::EOT
  when /^never/
    nil
  else
    raise ArgumentError, "bad date spec: '#{spec}''"
  end # !> previous definition of length was here
end

Instance Method Details

#add_chunk(chunk) ⇒ Object



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/fat_core/date.rb', line 326

def add_chunk(chunk)
  case chunk
  when :year
    next_year
  when :quarter
    next_month(3)
  when :bimonth
    next_month(2)
  when :month
    next_month
  when :semimonth
    self + 15.days
  when :biweek
    self + 14.days
  when :week
    self + 7.days
  when :day
    self + 1.days
  else
    raise LogicError, "add_chunk unknown chunk: '#{chunk}'"
  end
end

#add_fed_business_days(n) ⇒ Object



692
693
694
695
696
697
698
699
700
# File 'lib/fat_core/date.rb', line 692

def add_fed_business_days(n)
  d = self.dup
  if n < 0
    n.abs.times { d = d.prior_fed_workday }
  elsif n > 0
    n.times { d = d.next_fed_workday }
  end
  d
end

#add_nyse_business_days(n) ⇒ Object



711
712
713
714
715
716
717
718
719
# File 'lib/fat_core/date.rb', line 711

def add_nyse_business_days(n)
  d = self.dup
  if n < 0
    n.abs.times { d = d.prior_nyse_workday }
  elsif n > 0
    n.times { d = d.next_nyse_workday }
  end
  d
end

#americanObject

Format date in MM/DD/YYYY form



318
319
320
# File 'lib/fat_core/date.rb', line 318

def american
  strftime "%-m/%-d/%Y"
end

#beginning_of_bimonthObject



209
210
211
212
213
214
215
# File 'lib/fat_core/date.rb', line 209

def beginning_of_bimonth
  if month % 2 == 1
    beginning_of_month
  else
    (self - 1.month).beginning_of_month
  end
end

#beginning_of_bimonth?Boolean

Returns:

  • (Boolean)


275
276
277
278
# File 'lib/fat_core/date.rb', line 275

def beginning_of_bimonth?
  month % 2 == 1 &&
    self.beginning_of_month == self
end

#beginning_of_biweekObject

Note: we use a monday start of the week in the next two methods because commercial week counting assumes a monday start.



243
244
245
246
247
248
249
# File 'lib/fat_core/date.rb', line 243

def beginning_of_biweek
  if cweek % 2 == 1
    beginning_of_week(:monday)
  else
    (self - 1.week).beginning_of_week(:monday)
  end
end

#beginning_of_biweek?Boolean

Returns:

  • (Boolean)


301
302
303
# File 'lib/fat_core/date.rb', line 301

def beginning_of_biweek?
  self.beginning_of_biweek == self
end

#beginning_of_chunk(sym) ⇒ Object



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/fat_core/date.rb', line 349

def beginning_of_chunk(sym)
  case sym
  when :year
    beginning_of_year
  when :quarter
    beginning_of_quarter
  when :bimonth
    beginning_of_bimonth
  when :month
    beginning_of_month
  when :semimonth
    beginning_of_semimonth
  when :biweek
    beginning_of_biweek
  when :week
    beginning_of_week
  when :day
    self
  else
    raise LogicError, "unknown chunk sym: '#{sym}'"
  end
end

#beginning_of_month?Boolean

Returns:

  • (Boolean)


285
286
287
# File 'lib/fat_core/date.rb', line 285

def beginning_of_month?
  self.beginning_of_month == self
end

#beginning_of_quarter?Boolean

Returns:

  • (Boolean)


267
268
269
# File 'lib/fat_core/date.rb', line 267

def beginning_of_quarter?
  self.beginning_of_quarter == self
end

#beginning_of_semimonthObject



225
226
227
228
229
230
231
# File 'lib/fat_core/date.rb', line 225

def beginning_of_semimonth
  if day >= 16
    Date.new(year, month, 16)
  else
    beginning_of_month
  end
end

#beginning_of_semimonth?Boolean

Returns:

  • (Boolean)


293
294
295
# File 'lib/fat_core/date.rb', line 293

def beginning_of_semimonth?
  self.beginning_of_semimonth == self
end

#beginning_of_week?Boolean

Returns:

  • (Boolean)


309
310
311
# File 'lib/fat_core/date.rb', line 309

def beginning_of_week?
  self.beginning_of_week == self
end

#beginning_of_year?Boolean

Returns:

  • (Boolean)


259
260
261
# File 'lib/fat_core/date.rb', line 259

def beginning_of_year?
  self.beginning_of_year == self
end

#easter?Boolean

Returns:

  • (Boolean)


480
481
482
483
484
485
# File 'lib/fat_core/date.rb', line 480

def easter?
  # Am I Easter?
  # Easter is always in March or April
  return false unless [3, 4].include?(self.mon)
  return self == self.easter_this_year
end

#easter_this_yearObject



464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
# File 'lib/fat_core/date.rb', line 464

def easter_this_year
  # Return the date of Easter in self's year
  y = self.year
  a = y % 19
  b, c = y.divmod(100)
  d, e = b.divmod(4)
  f = (b + 8) / 25
  g = (b - f + 1) / 3
  h = (19 * a + b - d - g + 15) % 30
  i, k = c.divmod(4)
  l = (32 + 2*e + 2*i - h - k) % 7
  m = (a + 11*h + 22*l) / 451
  n, p = (h + l - 7*m + 114).divmod(31)
  return Date.new(y, n, p + 1)
end

#end_of_bimonthObject



217
218
219
220
221
222
223
# File 'lib/fat_core/date.rb', line 217

def end_of_bimonth
  if month % 2 == 1
    (self + 1.month).end_of_month
  else
    end_of_month
  end
end

#end_of_bimonth?Boolean

Returns:

  • (Boolean)


280
281
282
283
# File 'lib/fat_core/date.rb', line 280

def end_of_bimonth?
  month % 2 == 0 &&
    self.end_of_month == self
end

#end_of_biweekObject



251
252
253
254
255
256
257
# File 'lib/fat_core/date.rb', line 251

def end_of_biweek
  if cweek % 2 == 1
    (self + 1.week).end_of_week(:monday)
  else
    end_of_week(:monday)
  end
end

#end_of_biweek?Boolean

Returns:

  • (Boolean)


305
306
307
# File 'lib/fat_core/date.rb', line 305

def end_of_biweek?
  self.end_of_biweek == self
end

#end_of_chunk(sym) ⇒ Object



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/fat_core/date.rb', line 372

def end_of_chunk(sym)
  case sym
  when :year
    end_of_year
  when :quarter
    end_of_quarter
  when :bimonth
    end_of_bimonth
  when :month
    end_of_month
  when :semimonth
    end_of_semimonth
  when :biweek
    end_of_biweek
  when :week
    end_of_week
  when :day
    self
  else
    raise LogicError, "unknown chunk sym: '#{sym}'"
  end
end

#end_of_month?Boolean

Returns:

  • (Boolean)


289
290
291
# File 'lib/fat_core/date.rb', line 289

def end_of_month?
  self.end_of_month == self
end

#end_of_quarter?Boolean

Returns:

  • (Boolean)


271
272
273
# File 'lib/fat_core/date.rb', line 271

def end_of_quarter?
  self.end_of_quarter == self
end

#end_of_semimonthObject



233
234
235
236
237
238
239
# File 'lib/fat_core/date.rb', line 233

def end_of_semimonth
  if day <= 15
    Date.new(year, month, 15)
  else
    end_of_month
  end
end

#end_of_semimonth?Boolean

Returns:

  • (Boolean)


297
298
299
# File 'lib/fat_core/date.rb', line 297

def end_of_semimonth?
  self.end_of_semimonth == self
end

#end_of_week?Boolean

Returns:

  • (Boolean)


313
314
315
# File 'lib/fat_core/date.rb', line 313

def end_of_week?
  self.end_of_week == self
end

#end_of_year?Boolean

Returns:

  • (Boolean)


263
264
265
# File 'lib/fat_core/date.rb', line 263

def end_of_year?
  self.end_of_year == self
end

#engObject



192
193
194
# File 'lib/fat_core/date.rb', line 192

def eng
  strftime("%B %e, %Y")
end

#expand_to_period(sym) ⇒ Object



322
323
324
# File 'lib/fat_core/date.rb', line 322

def expand_to_period(sym)
  Period.new(beginning_of_chunk(sym), end_of_chunk(sym))
end

#fed_fixed_holiday?Boolean

Returns:

  • (Boolean)


499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
# File 'lib/fat_core/date.rb', line 499

def fed_fixed_holiday?
  # Fixed-date holidays on weekdays
  if self.mon == 1 && self.mday == 1
    # New Years (January 1),
    return true
  elsif self.mon == 7 && self.mday == 4
    # Independence Day (July 4),
    return true
  elsif self.mon == 11 && self.mday == 11
    # Veterans Day (November 11),
    return true
  elsif self.mon == 12 && self.mday == 25
    # Christmas (December 25), and
    return true
  elsif self.mon == 12 && self.mday == 31
    # New Year's Eve (December 31)
    return true;
  else
    return false
  end
end

#fed_holiday?Boolean

Returns:

  • (Boolean)


550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
# File 'lib/fat_core/date.rb', line 550

def fed_holiday?
  if FED_DECLARED_HOLIDAYS.include?(self)
    return true
  end

  # All Saturdays and Sundays are "holidays"
  if self.weekend? then return true end

  # Is self a fixed holiday
  return true if self.fed_fixed_holiday?

  # A Friday is a holiday if a fixed-date holiday
  # would fall on the following Saturday
  if self.wday == 5
    td = self + 1
    return true if td.fed_fixed_holiday?
  end

  # A Monday is a holiday if a fixed-date holiday
  # would fall on the preceding Sunday
  if self.wday == 1
    td = self - 1
    return true if td.fed_fixed_holiday?
  end

  # If Christmas falls on a Thursday, apparently, the Friday after is
  # treated as a holiday as well.  See 2003, 2008, for example.
  if self.wday == 5 and self.month == 12 and self.day == 26
    return true
  end

  # It's last chance is if its a movable feast
  return self.fed_moveable_feast?;
end

#fed_moveable_feast?Boolean

Returns:

  • (Boolean)


521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
# File 'lib/fat_core/date.rb', line 521

def fed_moveable_feast?
  # See if today is a "movable feast," all of which are
  # rigged to fall on Monday except Thanksgiving

  # No moveable feasts in certain months
  if [ 3, 4, 6, 7, 8, 12 ].include?(self.month)
    return false
  elsif self.wday == 1
    # MLK's Birthday (Third Monday in Jan)
    return true if self.nth_wday_in_month?(3, 1, 1)
    # Washington's Birthday (Third Monday in Feb)
    return true if self.nth_wday_in_month?(3, 1, 2)
    # Memorial Day (Last Monday in May)
    return true if self.nth_wday_in_month?(-1, 1, 5)
    # Labor Day (First Monday in Sep)
    return true if self.nth_wday_in_month?(1, 1, 9)
    # Columbus Day (Second Monday in Oct)
    return true if self.nth_wday_in_month?(2, 1, 10)
    # Other Mondays
    return false
  elsif self.wday == 4
    # Thanksgiving Day (Fourth Thur in Nov)
    return false unless self.month == 11
    return self.nth_wday_in_month?(4, 4, 11)
  else
    return false
  end
end

#fed_workday?Boolean

Returns:

  • (Boolean)


676
677
678
# File 'lib/fat_core/date.rb', line 676

def fed_workday?
  return ! self.fed_holiday?;
end

#isoObject



184
185
186
# File 'lib/fat_core/date.rb', line 184

def iso
  strftime("%Y-%m-%d")
end

#next_fed_workdayObject



684
685
686
687
688
689
690
# File 'lib/fat_core/date.rb', line 684

def next_fed_workday
  result = self + 1
  while result.fed_holiday?
    result += 1;
  end
  return result
end

#next_nyse_workdayObject



702
703
704
705
706
707
708
709
# File 'lib/fat_core/date.rb', line 702

def next_nyse_workday
  result = self.dup
  result += 1
  while result.nyse_holiday?
    result += 1;
  end
  return result
end

#nth_wday_in_month?(n, wday, month) ⇒ Boolean

Returns:

  • (Boolean)


487
488
489
490
491
492
493
494
495
496
497
# File 'lib/fat_core/date.rb', line 487

def nth_wday_in_month?(n, wday, month)
  # Is self the nth weekday in the given month of its year?
  # If n is negative, count from last day of month
  if self.wday != wday
    return false
  elsif self.mon != month
    return false
  else
    return self == Date.nth_wday_in_year_month(n, wday, self.year, month)
  end
end

#numObject



742
743
744
# File 'lib/fat_core/date.rb', line 742

def num
  strftime("%Y%m%d")
end

#nyse_fixed_holiday?Boolean

Rule: if it falls on Saturday, observe on preceding Friday. Rule: if it falls on Sunday, observe on following Monday.

New Year’s Day, January 1. Birthday of Martin Luther King, Jr., the third Monday in January. Washington’s Birthday, the third Monday in February. Good Friday Friday before Easter Sunday. NOTE: not a fed holiday Memorial Day, the last Monday in May. Independence Day, July 4. Labor Day, the first Monday in September. NOTE: Columbus and Veterans days not observed Thanksgiving Day, the fourth Thursday in November. Christmas Day, December 25.

Returns:

  • (Boolean)


604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
# File 'lib/fat_core/date.rb', line 604

def nyse_fixed_holiday?
  # Fixed-date holidays
  if self.mon == 1 && self.mday == 1
    # New Years (January 1),
    return true
  elsif self.mon == 7 && self.mday == 4
    # Independence Day (July 4),
    return true
  elsif self.mon == 12 && self.mday == 25
    # Christmas (December 25), and
    return true
  else
    return false
  end
end

#nyse_holiday?Boolean

Returns:

  • (Boolean)


651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
# File 'lib/fat_core/date.rb', line 651

def nyse_holiday?
  # All Saturdays and Sundays are "holidays"
  return true if self.weekend?

  # Is self a fixed holiday
  return true if self.nyse_fixed_holiday?

  # A Friday is a holiday if a fixed-date holiday
  # would fall on the following Saturday
  if self.wday == 5
    td = self + 1
    return true if td.nyse_fixed_holiday?
  end

  # A Monday is a holiday if a fixed-date holiday
  # would fall on the preceding Sunday
  if self.wday == 1
    td = self - 1
    return true if td.nyse_fixed_holiday?
  end

  # It's last chance is if its a movable feast
  return self.nyse_moveable_feast?;
end

#nyse_moveable_feast?Boolean

Returns:

  • (Boolean)


620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
# File 'lib/fat_core/date.rb', line 620

def nyse_moveable_feast?
  # See if today is a "movable feast," all of which are
  # rigged to fall on Monday except Thanksgiving

  # No moveable feasts in certain months
  if [ 6, 7, 8, 10, 12 ].include?(self.month)
    return false
  elsif self.wday == 1
    # MLK's Birthday (Third Monday in Jan)
    return true if self.nth_wday_in_month?(3, 1, 1)
    # Washington's Birthday (Third Monday in Feb)
    return true if self.nth_wday_in_month?(3, 1, 2)
    # Memorial Day (Last Monday in May)
    return true if self.nth_wday_in_month?(-1, 1, 5)
    # Labor Day (First Monday in Sep)
    return true if self.nth_wday_in_month?(1, 1, 9)
    # Other Mondays
    return false
  elsif self.wday == 4
    # Thanksgiving Day (Fourth Thur in Nov)
    return false unless self.month == 11
    return self.nth_wday_in_month?(4, 4, 11)
  elsif self.wday == 5
    # Good Friday, the Friday before Easter
    td = self + 2
    return td.easter?
  else
    return false
  end
end

#nyse_workday?Boolean

Returns:

  • (Boolean)


680
681
682
# File 'lib/fat_core/date.rb', line 680

def nyse_workday?
  return ! self.nyse_holiday?;
end

#orgObject



188
189
190
# File 'lib/fat_core/date.rb', line 188

def org
  strftime("[%Y-%m-%d %a]")
end

#predObject



176
177
178
# File 'lib/fat_core/date.rb', line 176

def pred
  self - 1.day
end

#prior_fed_workdayObject



721
722
723
724
725
726
727
# File 'lib/fat_core/date.rb', line 721

def prior_fed_workday
  result = self - 1
  while result.fed_holiday?
    result -= 1;
  end
  return result
end

#prior_nyse_workdayObject



729
730
731
732
733
734
735
736
# File 'lib/fat_core/date.rb', line 729

def prior_nyse_workday
  result = self.dup
  result -= 1
  while result.nyse_holiday?
    result -= 1;
  end
  return result
end

#quarterObject



196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/fat_core/date.rb', line 196

def quarter
  case month
  when (1..3)
    1
  when (4..6)
    2
  when (7..9)
    3
  when (10..12)
    4
  end
end

#succObject



180
181
182
# File 'lib/fat_core/date.rb', line 180

def succ
  self + 1.day
end

#tex_quoteObject

Allow erb documents can directly interpolate dates



754
755
756
# File 'lib/fat_core/date.rb', line 754

def tex_quote
  iso
end

#weekday?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/fat_core/date.rb', line 172

def weekday?
  !weekend?
end

#weekend?Boolean

Returns:

  • (Boolean)


168
169
170
# File 'lib/fat_core/date.rb', line 168

def weekend?
  saturday? || sunday?
end

#within_6mos_of?(d) ⇒ Boolean

Returns:

  • (Boolean)


746
747
748
749
750
751
# File 'lib/fat_core/date.rb', line 746

def within_6mos_of?(d)
  # Date 6 calendar months before self
  start_date = self - 6.months + 2.days
  end_date = self + 6.months - 2.days
  (start_date..end_date).cover?(d)
end