Module: ThirdBase::Date::InstanceMethods

Included in:
ThirdBase::Date
Defined in:
lib/third_base/date.rb

Instance Method Summary collapse

Instance Method Details

#+(d) ⇒ Object

Returns a new date with d number of days added to this date.

Raises:

  • (TypeError)


348
349
350
351
# File 'lib/third_base/date.rb', line 348

def +(d)
  raise(TypeError, "d must be an integer") unless d.is_a?(Integer)
  jd_to_civil(jd + d)
end

#-(d) ⇒ Object

Returns a new date with d number of days subtracted from this date. If d is a Date, returns the number of days between the two dates.



355
356
357
358
359
360
361
362
363
# File 'lib/third_base/date.rb', line 355

def -(d)
  if d.is_a?(self.class)
    jd - d.jd
  elsif d.is_a?(Integer)
    self + -d
  else
    raise TypeError, "d should be #{self.class} or Integer"
  end
end

#<<(m) ⇒ Object

Returns a new date with m number of months subtracted from this date.



387
388
389
# File 'lib/third_base/date.rb', line 387

def <<(m)
  self >> -m
end

#<=>(date) ⇒ Object

Compare two dates. If the given date is greater than self, return -1, if it is less, return 1, and if it is equal, return 0. If given date is a number, compare this date’s julian date to it.



394
395
396
397
398
399
400
401
# File 'lib/third_base/date.rb', line 394

def <=>(date)
  if date.is_a?(Numeric)
    jd <=> date
  else
    ((d = (year <=> date.year)) == 0) && ((d = (mon <=> date.mon)) == 0) && ((d = (day <=> date.day)) == 0)
    d
  end
end

#==(date) ⇒ Object

Dates are equel only if their year, month, and day match.



404
405
406
407
# File 'lib/third_base/date.rb', line 404

def ==(date)
  return false unless Date === date
  year == date.year and mon == date.mon and day == date.day
end

#===(d) ⇒ Object

If d is a date, only true if it is equal to this date. If d is Numeric, only true if it equals this date’s julian date.



414
415
416
417
418
419
420
# File 'lib/third_base/date.rb', line 414

def ===(d)
  case d
  when Numeric then jd == d
  when Date then self == d
  else false
  end
end

#>>(m) ⇒ Object

Returns a new date with m number of months added to this date. If the day of self does not exist in the new month, set the new day to be the last day of the new month.

Raises:

  • (TypeError)


368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/third_base/date.rb', line 368

def >>(m)
  raise(TypeError, "m must be an integer") unless m.is_a?(Integer)
  y = year
  n = mon + m
  if n > 12 or n <= 0
    a, n = n.divmod(12)
    if n == 0
      n = 12
      y += a - 1
    else
      y += a
    end
  end
  ndays = days_in_month(n, y)
  d = day > ndays ? ndays : day
  new_civil(y, n, d)
end

#cwdayObject

The commercial week day for this date.



423
424
425
# File 'lib/third_base/date.rb', line 423

def cwday
  @cwday || commercial[2]
end

#cweekObject

The commercial week for this date.



428
429
430
# File 'lib/third_base/date.rb', line 428

def cweek
  @cweek || commercial[1]
end

#cwyearObject

The commercial week year for this date.



433
434
435
# File 'lib/third_base/date.rb', line 433

def cwyear
  @cwyear || commercial[0]
end

#dayObject Also known as: mday

The day of the month for this date.



438
439
440
# File 'lib/third_base/date.rb', line 438

def day
  @day || civil[2]
end

#downto(d, &block) ⇒ Object

Yield every date between this date and given date to the block. The given date should be less than this date.



445
446
447
# File 'lib/third_base/date.rb', line 445

def downto(d, &block)
  step(d, -1, &block)
end

#eql?(date) ⇒ Boolean

Returns:

  • (Boolean)


409
410
411
# File 'lib/third_base/date.rb', line 409

def eql?(date)
  self == date
end

#hashObject

Unique value for this date, based on it’s year, month, and day of month.



450
451
452
# File 'lib/third_base/date.rb', line 450

def hash
  civil.hash
end

#initialize(opts) ⇒ Object

Called by Date.new!, Takes a hash with one of the following keys:

  • :civil : should be an array with 3 elements, a year, month, and day

  • :commercial : should be an array with 3 elements, a commercial week year, commercial week, and commercial week day

  • :jd : should be an integer specifying the julian date

  • :ordinal : should be an array with 2 elements, a year and day of year.

An ArgumentError is raised if the date is invalid. All Date objects are immutable once created.



329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/third_base/date.rb', line 329

def initialize(opts)
  if opts[:civil]
    @year, @mon, @day = opts[:civil]
    raise(ArgumentError, "invalid date") unless @year.is_a?(Integer) && @mon.is_a?(Integer) && @day.is_a?(Integer) && valid_civil?
  elsif opts[:ordinal]
    @year, @yday = opts[:ordinal]
    raise(ArgumentError, "invalid date") unless @year.is_a?(Integer) && @yday.is_a?(Integer) && valid_ordinal?
  elsif opts[:jd]
    @jd = opts[:jd]
    raise(ArgumentError, "invalid date") unless @jd.is_a?(Integer)
  elsif opts[:commercial]
    @cwyear, @cweek, @cwday = opts[:commercial]
    raise(ArgumentError, "invalid date") unless @cwyear.is_a?(Integer) && @cweek.is_a?(Integer) && @cwday.is_a?(Integer) && valid_commercial?
  else
    raise(ArgumentError, "invalid date format")
  end
end

#inspectObject

Programmer friendly readable string, much more friendly than the one in the standard date class.



456
457
458
# File 'lib/third_base/date.rb', line 456

def inspect
  "#<#{self.class} #{self}>"
end

#jdObject

This date’s julian date.



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/third_base/date.rb', line 461

def jd
  @jd ||= ( 
    y = year
    m = mon
    d = day
    if m <= 2
      y -= 1
      m += 12
    end
    a = (y / 100.0).floor
    jd = (365.25 * (y + 4716)).floor +
      (30.6001 * (m + 1)).floor +
      d - 1524 + (2 - a + (a / 4.0).floor)
  )
end

#leap?Boolean

Whether this date is in a leap year.

Returns:

  • (Boolean)


478
479
480
# File 'lib/third_base/date.rb', line 478

def leap?
  _leap?(year)
end

#monObject Also known as: month

The month number for this date (January is 1, December is 12).



483
484
485
# File 'lib/third_base/date.rb', line 483

def mon
  @mon || civil[1]
end

#step(limit, step = 1) ⇒ Object

Yield each date between this date and limit, adding step number of days in each iteration. Returns current date.



490
491
492
493
494
495
496
497
498
# File 'lib/third_base/date.rb', line 490

def step(limit, step=1)
  da = self
  op = %w(== <= >=)[step <=> 0]
  while da.__send__(op, limit)
    yield da
    da += step
  end
  self
end

#strftime(fmt = strftime_default) ⇒ Object

Format the time using a format string, or the default format string.



501
502
503
# File 'lib/third_base/date.rb', line 501

def strftime(fmt=strftime_default)
  fmt.gsub(STRFTIME_RE){|x| _strftime(x[1..1])}
end

#succObject Also known as: next

Return the day after this date.



506
507
508
# File 'lib/third_base/date.rb', line 506

def succ
  self + 1
end

#to_sObject

Alias for strftime with the default format



512
513
514
# File 'lib/third_base/date.rb', line 512

def to_s
  strftime
end

#upto(d, &block) ⇒ Object

Yield every date between this date and the given date to the block. The given date should be greater than this date.



518
519
520
# File 'lib/third_base/date.rb', line 518

def upto(d, &block)
  step(d, &block)
end

#wdayObject

Return the day of the week for this date. Sunday is 0, Saturday is 6.



523
524
525
# File 'lib/third_base/date.rb', line 523

def wday
  (jd + 1) % 7
end

#ydayObject

Return the day of the year for this date. January 1 is 1.



528
529
530
531
# File 'lib/third_base/date.rb', line 528

def yday
  h = leap? ? LEAP_CUMMULATIVE_MONTH_DAYS : CUMMULATIVE_MONTH_DAYS
  @yday ||= h[mon] + day
end

#yearObject

Return the year for this date.



534
535
536
# File 'lib/third_base/date.rb', line 534

def year
  @year || civil[0]
end