class CalendariumRomanum::Temporale

One of the two main {Calendar} components. Handles seasons and celebrations of the temporale cycle for a given liturgical year.

Constants

C
SEASONS_SUNDAY_PRIMARY

seasons when Sundays have higher rank

SUNDAY_TRANSFERABLE_SOLEMNITIES

Which solemnities can be transferred to Sunday

SeasonWeek
WEEK

How many days in a week

Attributes

extensions[R]
transfer_to_sunday[R]
year[R]

@return [Integer]

Public Class Methods

celebrations() click to toggle source

@api private

# File lib/calendarium-romanum/temporale.rb, line 80
def celebrations
  @celebrations ||=
    begin
      %i(
        nativity
        holy_family
        mother_of_god
        epiphany
        baptism_of_lord
        ash_wednesday
        good_friday
        holy_saturday
        palm_sunday
        easter_sunday
        ascension
        pentecost
        holy_trinity
        corpus_christi
        mother_of_church
        sacred_heart
        christ_king
        immaculate_heart
      ).collect do |symbol|
        date_method = symbol
        C.new(
          date_method,
          CelebrationFactory.public_send(symbol)
        )
      end
      # Immaculate Heart of Mary and Mary, Mother of the Church
      # are actually movable *sanctorale* feasts,
      # but as it would make little sense
      # to add support for movable sanctorale feasts because of
      # two, we cheat a bit and handle them in temporale.
    end
end
create_celebration(title, rank, colour, symbol: nil, date: nil, sunday: nil) click to toggle source

Factory method creating temporale {Celebration}s with sensible defaults

See {Celebration#initialize} for argument description.

# File lib/calendarium-romanum/temporale.rb, line 64
def create_celebration(title, rank, colour, symbol: nil, date: nil, sunday: nil)
  Celebration.new(
    title: title,
    rank: rank,
    colour: colour,
    symbol: symbol,
    date: date,
    cycle: :temporale,
    sunday: sunday
  )
end
for_day(date) click to toggle source

Creates an instance for the liturgical year including given date

@param date [Date] @return [Temporale]

# File lib/calendarium-romanum/temporale.rb, line 56
def for_day(date)
  new(liturgical_year(date))
end
liturgical_year(date) click to toggle source

Determines liturgical year for the given date

@param date [Date] @return [Integer]

# File lib/calendarium-romanum/temporale.rb, line 41
def liturgical_year(date)
  year = date.year

  if date < Dates.first_advent_sunday(year)
    return year - 1
  end

  year
end
new(year, extensions: [], transfer_to_sunday: []) click to toggle source

@param year [Integer]

the civil year when the liturgical year _begins_

@param extensions [Array<#each_celebration>]

extensions implementing custom temporale celebrations

@param transfer_to_sunday [Array<Symbol>]

which solemnities should be transferred to a nearby
Sunday - see {SUNDAY_TRANSFERABLE_SOLEMNITIES}
for possible values
# File lib/calendarium-romanum/temporale.rb, line 23
def initialize(year, extensions: [], transfer_to_sunday: [])
  @year = year

  @extensions = extensions
  @transfer_to_sunday = transfer_to_sunday.sort
  validate_sunday_transfer!

  prepare_solemnities
end

Public Instance Methods

==(b) click to toggle source

@return [Boolean] @since 0.6.0

# File lib/calendarium-romanum/temporale.rb, line 349
def ==(b)
  self.class == b.class &&
    year == b.year &&
    transfer_to_sunday == b.transfer_to_sunday &&
    Set.new(extensions) == Set.new(b.extensions)
end
[](date) click to toggle source

Retrieve temporale celebration for the given day

@param date [Date] @return [Celebration] @since 0.6.0

# File lib/calendarium-romanum/temporale.rb, line 308
def [](date)
  sw = season_and_week(date)

  @solemnities[date] || @feasts[date] || sunday(date, sw) || @memorials[date] || ferial(date, sw)
end
date_range() click to toggle source

Date range of the liturgical year

@return [Range<Date>]

# File lib/calendarium-romanum/temporale.rb, line 143
def date_range
  start_date .. end_date
end
each_day() { |date, self| ... } click to toggle source

Enumerates dates and celebrations

@yield [Date, Celebration] @return [void, Enumerator] if called without a block, returns Enumerator @since 0.8.0

# File lib/calendarium-romanum/temporale.rb, line 341
def each_day
  return to_enum(__method__) unless block_given?

  date_range.each {|date| yield date, self[date] }
end
end_date() click to toggle source

Last day of the liturgical year

@return [Date]

# File lib/calendarium-romanum/temporale.rb, line 136
def end_date
  Dates.first_advent_sunday(year + 1) - 1
end
get(*args) click to toggle source

Retrieve temporale celebration for the given day

@overload get(date)

@param date [Date]

@overload get(month, day)

@param month [Integer]
@param day [Integer]

@return (see [])

# File lib/calendarium-romanum/temporale.rb, line 322
def get(*args)
  if args.size == 1 && args[0].is_a?(Date)
    date = args[0]
  else
    month, day = args
    date = Date.new @year, month, day
    unless date_range.include? date
      date = Date.new @year + 1, month, day
    end
  end

  self[date]
end
provides_celebration?(symbol) click to toggle source

Does this instance provide celebration identified by symbol symbol?

@param symbol [Symbol] @return [Boolean] @since 0.9.0

# File lib/calendarium-romanum/temporale.rb, line 361
def provides_celebration?(symbol)
  @all_celebration_symbols.include? symbol
end
range_check(date) click to toggle source

Check that the date belongs to the liturgical year. If it does not, throw exception.

@param date [Date] @return [void] @raise [RangeError]

# File lib/calendarium-romanum/temporale.rb, line 153
def range_check(date)
  # necessary in order to handle Date correctly
  date = date.to_date if date.class != Date

  unless date_range.include? date
    raise RangeError.new "Date out of range #{date}"
  end
end
season(date) click to toggle source

Determine liturgical season for a given date

@param date [Date] @return [Season] @raise [RangeError]

if the given date doesn't belong to the liturgical year
# File lib/calendarium-romanum/temporale.rb, line 223
def season(date)
  range_check date

  if first_advent_sunday <= date &&
     nativity > date
    Seasons::ADVENT

  elsif nativity <= date &&
        baptism_of_lord >= date
    Seasons::CHRISTMAS

  elsif ash_wednesday <= date &&
        good_friday > date
    Seasons::LENT

  elsif good_friday <= date &&
        easter_sunday >= date
    Seasons::TRIDUUM

  elsif easter_sunday < date &&
        pentecost >= date
    Seasons::EASTER

  else
    Seasons::ORDINARY
  end
end
season_beginning(s) click to toggle source

When the specified liturgical season begins

@param s [Season] @return [Date]

# File lib/calendarium-romanum/temporale.rb, line 255
def season_beginning(s)
  case s
  when Seasons::ADVENT
    first_advent_sunday
  when Seasons::CHRISTMAS
    nativity
  when Seasons::LENT
    ash_wednesday
  when Seasons::TRIDUUM
    good_friday
  when Seasons::EASTER
    easter_sunday + 1
  when Seasons::ORDINARY
    baptism_of_lord + 1
  else
    raise ArgumentError.new('unsupported season')
  end
end
season_week(seasonn, date) click to toggle source

Determine week of a season for a given date

@param seasonn [Season] @param date [Date]

# File lib/calendarium-romanum/temporale.rb, line 278
def season_week(seasonn, date)
  week1_beginning = season_beginning = season_beginning(seasonn)
  unless season_beginning.sunday?
    week1_beginning = Dates.sunday_after(season_beginning)
  end

  week = date_difference(date, week1_beginning) / WEEK + 1

  if seasonn == Seasons::ORDINARY || seasonn == Seasons::EASTER
    # ordinary time does not begin with Sunday, but the first week
    # is week 1, not 0
    week += 1
  end

  if seasonn == Seasons::ORDINARY
    if date > pentecost
      weeks_after_date = date_difference(Dates.first_advent_sunday(@year + 1), date) / WEEK
      week = 34 - weeks_after_date
      week += 1 if date.sunday?
    end
  end

  week
end
start_date() click to toggle source

First day of the liturgical year

@return [Date]

# File lib/calendarium-romanum/temporale.rb, line 129
def start_date
  first_advent_sunday
end
transferred_to_sunday?(solemnity) click to toggle source

Does this instance transfer the specified solemnity to Sunday?

@param solemnity [Symbol] @return [Boolean]

# File lib/calendarium-romanum/temporale.rb, line 122
def transferred_to_sunday?(solemnity)
  @transfer_to_sunday.include?(solemnity)
end

Private Instance Methods

date_difference(d1, d2) click to toggle source

helper: difference between two Dates in days

# File lib/calendarium-romanum/temporale.rb, line 444
def date_difference(d1, d2)
  (d1 - d2).numerator
end
ferial(date, season_week = nil) click to toggle source
# File lib/calendarium-romanum/temporale.rb, line 398
def ferial(date, season_week = nil)
  # Normally +season_week+ is provided, but the method is once called also from Calendar
  # and we definitely don't want Calendar to care that much about Temporale internals
  # So as to know how to retrieve the value, so in that case we provide it ourselves.
  season_week ||= season_and_week(date)

  rank = Ranks::FERIAL
  title = nil
  case season_week.season
  when Seasons::ADVENT
    if date >= Date.new(@year, 12, 17)
      rank = Ranks::FERIAL_PRIVILEGED
      nth = Ordinalizer.ordinal(date.day)
      title = I18n.t 'temporale.advent.before_christmas', day: nth
    end
  when Seasons::CHRISTMAS
    if date < mother_of_god
      rank = Ranks::FERIAL_PRIVILEGED

      nth = Ordinalizer.ordinal(date.day - nativity.day + 1) # 1-based counting
      title = I18n.t 'temporale.christmas.nativity_octave.ferial', day: nth
    elsif date > epiphany
      title = I18n.t 'temporale.christmas.after_epiphany.ferial', weekday: I18n.t("weekday.#{date.wday}")
    end
  when Seasons::LENT
    if season_week.week == 0
      title = I18n.t 'temporale.lent.after_ashes.ferial', weekday: I18n.t("weekday.#{date.wday}")
    elsif date > palm_sunday
      rank = Ranks::PRIMARY
      title = I18n.t 'temporale.lent.holy_week.ferial', weekday: I18n.t("weekday.#{date.wday}")
    end
    rank = Ranks::FERIAL_PRIVILEGED unless rank > Ranks::FERIAL_PRIVILEGED
  when Seasons::EASTER
    if season_week.week == 1
      rank = Ranks::PRIMARY
      title = I18n.t 'temporale.easter.octave.ferial', weekday: I18n.t("weekday.#{date.wday}")
    end
  end

  week_ord = Ordinalizer.ordinal season_week.week
  title ||= I18n.t "temporale.#{season_week.season.to_sym}.ferial", week: week_ord, weekday: I18n.t("weekday.#{date.wday}")

  self.class.create_celebration title, rank, season_week.season.colour
end
prepare_celebration_date(date_method, celebration) click to toggle source
# File lib/calendarium-romanum/temporale.rb, line 479
def prepare_celebration_date(date_method, celebration)
  date =
    if date_method.respond_to? :call
      date_method.call(year)
    else
      public_send(date_method)
    end

  add_to =
    if celebration.feast?
      @feasts
    elsif celebration.memorial?
      @memorials
    else
      @solemnities
    end
  add_to[date] = celebration
end
prepare_solemnities() click to toggle source

prepare dates of temporale solemnities

# File lib/calendarium-romanum/temporale.rb, line 449
def prepare_solemnities
  @solemnities = {}
  @feasts = {}
  @memorials = {}

  self.class.celebrations.each do |c|
    prepare_celebration_date c.date_method, c.celebration
  end

  @extensions.each do |extension|
    extension.each_celebration do |date_method, celebration|
      date_proc = date_method
      if date_method.is_a? Symbol
        date_proc = extension.method(date_method)
      end

      prepare_celebration_date date_proc, celebration
    end
  end

  @all_celebration_symbols = Set.new(
    @solemnities
      .merge(@feasts)
      .merge(@memorials)
      .each_value
      .collect(&:symbol)
      .compact # all should have a symbol, but we really want to prevent nil here
  )
end
season_and_week(date) click to toggle source
# File lib/calendarium-romanum/temporale.rb, line 374
def season_and_week(date)
  s = season(date)
  w = season_week(s, date)

  SeasonWeek.new(s, w)
end
sunday(date, season_week) click to toggle source
# File lib/calendarium-romanum/temporale.rb, line 384
def sunday(date, season_week)
  return nil unless date.sunday?

  rank = Ranks::SUNDAY_UNPRIVILEGED
  if SEASONS_SUNDAY_PRIMARY.include?(season_week.season)
    rank = Ranks::PRIMARY
  end

  week = Ordinalizer.ordinal season_week.week
  title = I18n.t "temporale.#{season_week.season.to_sym}.sunday", week: week

  self.class.create_celebration title, rank, season_week.season.colour, sunday: true
end
validate_sunday_transfer!() click to toggle source
# File lib/calendarium-romanum/temporale.rb, line 498
def validate_sunday_transfer!
  unsupported = @transfer_to_sunday - SUNDAY_TRANSFERABLE_SOLEMNITIES
  unless unsupported.empty?
    raise RuntimeError.new("Transfer of #{unsupported.inspect} to a Sunday not supported. Only #{SUNDAY_TRANSFERABLE_SOLEMNITIES} are allowed.")
  end
end