Module: Sekki24::Lunisolar::Calendar
- Defined in:
- lib/sekki24/lunisolar/calendar.rb
Constant Summary collapse
- LEAP_MONTH_RULE =
:winter_solstice_priority- MIN_LUNISOLAR_YEAR =
MIN_YEAR - 1
- MAX_LUNISOLAR_YEAR =
MAX_YEAR
Class Method Summary collapse
- .clear_cache! ⇒ Object
- .convert(value, tz:) ⇒ Object
- .to_gregorian(year, month, day, leap:, tz:) ⇒ Object
- .year(year, tz:) ⇒ Object
Class Method Details
.clear_cache! ⇒ Object
71 72 73 74 75 76 77 |
# File 'lib/sekki24/lunisolar/calendar.rb', line 71 def clear_cache! @cache_mutex.synchronize do @range_cache.clear @year_cache.clear end MonthBuilder.clear_cache! end |
.convert(value, tz:) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/sekki24/lunisolar/calendar.rb', line 18 def convert(value, tz:) local_date = local_date(value, tz) validate_gregorian_year(local_date.year) month = generated_range(local_date.year, tz).find { |entry| entry.include?(local_date) } raise Error, "could not assign lunisolar month for #{local_date}" unless month Date.new( year: month.year, month: month.month, day: (local_date - month.start_date).to_i + 1, leap: month.leap?, gregorian_date: local_date, month_length: month.length ) end |
.to_gregorian(year, month, day, leap:, tz:) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/sekki24/lunisolar/calendar.rb', line 47 def to_gregorian(year, month, day, leap:, tz:) lunar_year = validate_lunar_year(year) month_number = Integer(month) day_number = Integer(day) raise ArgumentError, "leap must be true or false" unless [true, false].include?(leap) unless (1..12).cover?(month_number) raise ArgumentError, "lunar month must be between 1 and 12" end target = self.year(lunar_year, tz: tz).find do |entry| entry.month == month_number && entry.leap? == leap end raise ArgumentError, "lunisolar month does not exist" unless target unless (1..target.length).cover?(day_number) raise ArgumentError, "lunar day must be between 1 and #{target.length}" end result = target.start_date + day_number - 1 validate_gregorian_year(result.year) result rescue TypeError raise ArgumentError, "lunar month and day must be Integers" end |
.year(year, tz:) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/sekki24/lunisolar/calendar.rb', line 34 def year(year, tz:) lunar_year = validate_lunar_year(year) cache_key = [lunar_year, TimeScale.timezone_key(tz)].freeze cached = @cache_mutex.synchronize { @year_cache[cache_key] } return cached if cached months = generated_range(lunar_year, tz).select { |month| month.year == lunar_year }.freeze unless [12, 13].include?(months.length) raise Error, "expected 12 or 13 lunisolar months for #{lunar_year}, got #{months.length}" end @cache_mutex.synchronize { @year_cache[cache_key] ||= months } end |