Class: Fasti::CalendarTransition
- Inherits:
-
Object
- Object
- Fasti::CalendarTransition
- Defined in:
- lib/fasti/calendar_transition.rb
Overview
Manages Julian to Gregorian calendar transitions for a specific country.
This class provides country-specific calendar transition data and validation methods to handle historical calendar reforms. It uses Julian Day Numbers (JDN) for precise date calculations and gap management during transition periods.
Instance Attribute Summary collapse
-
#country ⇒ Symbol
readonly
Returns the country code for this transition.
Class Method Summary collapse
-
.supported_countries ⇒ Array<Symbol>
Returns list of supported countries with transition dates.
Instance Method Summary collapse
-
#create_date(year, month, day) ⇒ Date
Creates a Date object using the appropriate calendar system for this country.
-
#gregorian_start_jdn ⇒ Integer
Returns the Julian Day Number when this country adopted the Gregorian calendar.
-
#initialize(country) ⇒ CalendarTransition
constructor
Creates a new CalendarTransition instance for the specified country.
-
#transition_info ⇒ Hash
Returns information about this country’s calendar transition.
-
#valid_date?(date) ⇒ Boolean
Checks if a date exists in this country’s calendar system.
Constructor Details
#initialize(country) ⇒ CalendarTransition
Creates a new CalendarTransition instance for the specified country.
109 110 111 112 |
# File 'lib/fasti/calendar_transition.rb', line 109 def initialize(country) @country = country @transition_jdn = TRANSITIONS[@country] || DEFAULT_TRANSITION end |
Instance Attribute Details
#country ⇒ Symbol (readonly)
Returns the country code for this transition.
117 118 119 |
# File 'lib/fasti/calendar_transition.rb', line 117 def country @country end |
Class Method Details
.supported_countries ⇒ Array<Symbol>
Returns list of supported countries with transition dates.
102 103 104 |
# File 'lib/fasti/calendar_transition.rb', line 102 def self.supported_countries TRANSITIONS.keys.sort end |
Instance Method Details
#create_date(year, month, day) ⇒ Date
Creates a Date object using the appropriate calendar system for this country.
This method automatically selects Julian or Gregorian calendar based on the date and country’s transition point, ensuring appropriate calendar date representation.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/fasti/calendar_transition.rb', line 158 def create_date(year, month, day) # Try creating the date with Gregorian first (most common case) gregorian_date = Date.new(year, month, day, Date::GREGORIAN) if gregorian_date.jd >= @transition_jdn # Date is on or after transition - use Gregorian gregorian_date else # Date is before transition - use Julian julian_date = Date.new(year, month, day, Date::JULIAN) # Check if this date would fall in the gap if julian_date.jd >= @transition_jdn raise ArgumentError, "Date #{year}-#{month.to_s.rjust(2, "0")}-#{day.to_s.rjust(2, "0")} " \ "does not exist in #{@country.upcase} due to calendar transition" end julian_date end end |
#gregorian_start_jdn ⇒ Integer
Returns the Julian Day Number when this country adopted the Gregorian calendar.
132 133 134 |
# File 'lib/fasti/calendar_transition.rb', line 132 def gregorian_start_jdn @transition_jdn end |
#transition_info ⇒ Hash
Returns information about this country’s calendar transition.
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/fasti/calendar_transition.rb', line 233 def transition_info # Use explicit calendar system to avoid implicit Italian transition gregorian_start = Date.jd(@transition_jdn, Date::GREGORIAN) julian_end = Date.jd(@transition_jdn - 1, Date::JULIAN) # Calculate actual gap in calendar dates, not just JDN difference # For example: Oct 4 (Julian) -> Oct 15 (Gregorian) has 10 gap days (5-14) if @transition_jdn == DEFAULT_TRANSITION # For Italy, Ruby's Date class already handles the gap gap_days = 10 # Known historical gap for Italy else # For other countries, calculate based on calendar date differences # The gap is the difference between the date numbers minus 1 gap_days = gregorian_start.day - julian_end.day - 1 # Handle cross-month transitions (like Denmark Dec 21 -> Jan 1) if gap_days < 0 # When crossing months, need to account for days in the previous month # This is a simplified calculation - may need refinement for complex cases prev_month_days = Date.new(julian_end.year, julian_end.month, -1, Date::JULIAN).day gap_days = (prev_month_days - julian_end.day) + gregorian_start.day - 1 end end { country: @country, gregorian_start_jdn: @transition_jdn, gregorian_start_date: gregorian_start, julian_end_date: julian_end, gap_days: } end |
#valid_date?(date) ⇒ Boolean
Checks if a date exists in this country’s calendar system.
During calendar transitions, certain dates were skipped and never existed. This method validates whether a specific date is valid for this country.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/fasti/calendar_transition.rb', line 195 def valid_date?(date) # If we're dealing with the default transition (Italy), Ruby handles it correctly return true if @transition_jdn == DEFAULT_TRANSITION && date.jd != @transition_jdn - 1 # For other countries, check if the date falls in a gap # We need to check both Julian and Gregorian representations begin julian_version = Date.new(date.year, date.month, date.day, Date::JULIAN) gregorian_version = Date.new(date.year, date.month, date.day, Date::GREGORIAN) # If both versions have the same JDN, there's no ambiguity return true if julian_version.jd == gregorian_version.jd # Check if either version is valid for this country julian_valid = julian_version.jd < @transition_jdn gregorian_valid = gregorian_version.jd >= @transition_jdn julian_valid || gregorian_valid rescue ArgumentError # Invalid date in both calendar systems false end end |