# frozen_string_literal: true module JapaneseCalendar module Era # Returns the Japanese era name (nengo) since 1 January 1873 (Meiji 6). # # heisei = Time.new(1989, 1, 8) # => 1989-01-08 00:00:00 +0900 # heisei.era_name # => "平成" # heisei.era_name(:romaji) # => "Heisei" # # showa = Time.new(1926, 12, 25) # => 1926-12-25 00:00:00 +0900 # showa.era_name # => "昭和" # showa.era_name(:romaji) # => "Showa" # # taisho = Time.new(1912, 7, 30) # => 1912-07-30 00:00:00 +0900 # taisho.era_name # => "大正" # taisho.era_name(:romaji) # => "Taisho" # # meiji = Time.new(1873, 1, 1) # => 1873-01-01 00:00:00 +0900 # meiji.era_name # => "明治" # meiji.era_name(:romaji) # => "Meiji" # # Raises an error when the Japanese era name cannot be found. # # Time.new(1872, 12, 31).era_name # => RuntimeError def era_name(character = :kanji) unless %i(kanji romaji).include?(character) raise ArgumentError, "invalid character" end current_era.send("#{character}_name") end # Returns the Japanese year since 1 January 1873 (Meiji 6). # # Time.new(2016, 12, 11).era_year # => 28 # Time.new(1989, 1, 7).era_year # => 64 # Time.new(1926, 12, 24).era_year # => 15 # Time.new(1912, 7, 29).era_year # => 45 # # Raises an error when the Japanese year cannot be found. # # Time.new(1872, 12, 31).era_year # => RuntimeError def era_year year - current_era.beginning_of_period.year + 1 end # Formats time according to the directives in the given format string. # # date_of_birth = Time.new(1978, 7, 19) # # date_of_birth.strftime("%JN") # => "昭和" # date_of_birth.strftime("%JR") # => "Showa" # date_of_birth.strftime("%^JR") # => "SHOWA" # date_of_birth.strftime("%Jr") # => "S" # date_of_birth.strftime("%Jy") # => "53" # # date_of_birth.strftime("%JN%-Jy年") # => "昭和53年" # # Raises an error when the Japanese year cannot be found. # # Time.new(1872, 12, 31).strftime("%JN%-Jy年") # => RuntimeError def strftime(format) string = format.dup string.gsub!(/%JN/, era_name) string.gsub!(/%JR/, era_name(:romaji)) string.gsub!(/%\^JR/, era_name(:romaji).upcase) string.gsub!(/%Jr/, era_name(:romaji)[0]) string.gsub!(/%Jy/, "%02d" % era_year) string.gsub!(/%-Jy/, "%d" % era_year) string.gsub!(/%_Jy/, "%2d" % era_year) deprecated_japanese_calendar_era_name_strftime(string) deprecated_japanese_calendar_era_year_strftime(string) super(string) end private Period = Struct.new(:beginning_of_period, :kanji_name, :romaji_name) PERIODS = [ Period.new(Date.new(2019, 5, 1), "令和", "Reiwa").freeze, Period.new(Date.new(1989, 1, 8), "平成", "Heisei").freeze, Period.new(Date.new(1926, 12, 25), "昭和", "Showa" ).freeze, Period.new(Date.new(1912, 7, 30), "大正", "Taisho").freeze, Period.new(Date.new(1868, 1, 25), "明治", "Meiji" ).freeze ].freeze MEIJI_6 = Date.new(1873, 1, 1) def current_era error_proc = proc { raise "#{self.class.name.downcase} out of range" } error_proc.call if self.to_date < MEIJI_6 PERIODS.find(error_proc) do |period| period.beginning_of_period <= self.to_date end end def deprecated_japanese_calendar_era_name_strftime(string) if string =~ /%K/ warn "%K is deprecated. Please use %JN instead." string.gsub!(/%K/, era_name) end if string =~ /%O/ warn "%O is deprecated. Please use %JR instead." string.gsub!(/%O/, era_name(:romaji)) end if string =~ /%\^O/ warn "%^O is deprecated. Please use %^JR instead." string.gsub!(/%\^O/, era_name(:romaji).upcase) end if string =~ /%o/ warn "%o is deprecated. Please use %Jr instead." string.gsub!(/%o/, era_name(:romaji)[0]) end end def deprecated_japanese_calendar_era_year_strftime(string) if string =~ /%J/ warn "%J is deprecated. Please use %Jy instead." string.gsub!(/%J/, "%02d" % era_year) end if string =~ /%-J/ warn "%-J is deprecated. Please use %-Jy instead." string.gsub!(/%-J/, "%d" % era_year) end if string =~ /%_J/ warn "%_J is deprecated. Please use %_Jy instead." string.gsub!(/%_J/, "%2d" % era_year) end end end end