Skip to content

Generate era definitions from manakai data-locale - #30

Merged
sugi merged 1 commit into
masterfrom
feature/era-defs-from-manakai
Jul 13, 2026
Merged

Generate era definitions from manakai data-locale#30
sugi merged 1 commit into
masterfrom
feature/era-defs-from-manakai

Conversation

@sugi

@sugi sugi commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

Replace the Wikipedia-scraping era generator (build-util/parse_wikipedia.rb) with build-util/gen-era-def.rb, which generates lib/wareki/era_def.rb from manakai/data-locale data/calendar/era-defs.json — the same source already used for the kyuureki calendar data.

Generator design

  • Eras are selected by the jp_era / jp_north_era / jp_south_era flags (exactly the same 248 eras as before).
  • Era names come from name_ja (name can be Simplified Chinese, e.g. 慶応 → 庆应), first year from offset + 1, day numbers from jd + 0.5 (manakai uses midnight-based JD).
  • Pre-Meiji eras keep the existing convention that the end day is the next era's start day (= manakai end_day + 1); Meiji and later stay disjoint.
  • The retroactive Meiji start (Keio 4/1/1 = JDN 2403357) is derived from YEAR_DEFS instead of manakai's deprecated official_start_day.
  • The array layout (main sequence → southern block → northern block → 応永 and later) is preserved, since find_era's northern-court priority relies on reverse_each order.

The generated file is byte-stable across runs and can also fetch the JSON directly from the canonical URL when run without arguments.

Data changes from the new source

  • 正平/建徳/文中 transition days now follow manakai (建徳 changed on kyuureki 1370-02-05, 文中 on 1372-04-28). Only visible when parsing southern-court dates; jd→era lookup is shadowed by northern eras (応安 etc.) as designed.
  • 白雉 and 朱鳥 now cover until the end of their last kyuureki year instead of the day era usage ceased (manakai lastyearend semantics). One spec date adjusted accordingly.
  • ERA_NORTH_DEFS: 元徳 now ends at the 正慶 transition, matching the northern court actually keeping 元徳 until 正慶. Name lookup is unaffected because ERA_BY_NAME prefers ERA_DEFS entries.

All other 248 era names, first years, and boundaries are identical to the previous Wikipedia-derived data.

Verification

  • rspec: 93 examples, 0 failures
  • Regenerated output is idempotent, identical whether read from a local file or fetched from the canonical URL, and robust under a non-UTF-8 locale
  • Exercised via the public API: parse of 建徳元年2月5日 (new boundary), 朱鳥 year-end coverage, retroactive Meiji lookup, northern-court priority, and 令和 parsing

🤖 Generated with Claude Code

https://claude.ai/code/session_01VvNJPFUie1qcaBoU3kTdxY

Replace the Wikipedia-scraping era generator (parse_wikipedia.rb) with
build-util/gen-era-def.rb, which builds lib/wareki/era_def.rb from
manakai/data-locale era-defs.json.

Data changes from the new source:
- 正平/建徳/文中 transition days follow manakai (建徳 changed on
  kyuureki 1370-02-05, 文中 on 1372-04-28)
- 白雉 and 朱鳥 now cover until the end of their last kyuureki year
  instead of the day era usage ceased
- ERA_NORTH_DEFS: 元徳 now ends at the 正慶 transition as the northern
  court kept 元徳 until 正慶; name lookup is unaffected because
  ERA_BY_NAME prefers ERA_DEFS entries

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VvNJPFUie1qcaBoU3kTdxY

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the Wikipedia-based era definition generator with a new script (build-util/gen-era-def.rb) that generates era definitions from manakai/data-locale's era-defs.json. This updates several historical era boundaries (such as 白雉, 朱鳥, 正平, 建徳, and 文中) in lib/wareki/era_def.rb and updates the test suite accordingly. The reviewer feedback suggests adding defensive checks in the generator script to prevent potential NoMethodError crashes when handling missing or nil court-specific start and end days in the JSON data.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread build-util/gen-era-def.rb
Comment on lines +46 to +48
def north_court?(era)
era['jp_north_era'] == 1 && jdn(era['north_start_day']) > @split_start
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If era['north_start_day'] is nil or absent in the JSON data, calling jdn on it will raise a NoMethodError. Adding a defensive check to ensure north_start_day is present before calling jdn prevents potential crashes if the upstream data structure changes or contains incomplete records.

  def north_court?(era)
    era['jp_north_era'] == 1 && era['north_start_day'] && jdn(era['north_start_day']) > @split_start
  end

Comment thread build-util/gen-era-def.rb
Comment on lines +79 to +81
def court_era(era, court)
build_era(era, start_day: era["#{court}_start_day"], end_day: era["#{court}_end_day"])
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If era["#{court}_start_day"] or era["#{court}_end_day"] is nil or absent in the JSON data, calling jdn or end_jdn on them will raise a NoMethodError. Providing a fallback to era['start_day'] and era['end_day'] (similar to how main_era handles end_day) makes the generator much more robust against incomplete court-specific data.

  def court_era(era, court)
    build_era(era, start_day: era["#{court}_start_day"] || era['start_day'], end_day: era["#{court}_end_day"] || era['end_day'])
  end

Comment thread build-util/gen-era-def.rb
Comment on lines +88 to +89
souths = souths.sort_by { |e| jdn(e['south_start_day']) }.map { |e| court_era(e, :south) }
norths = norths.sort_by { |e| jdn(e['north_start_day']) }.map { |e| court_era(e, :north) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When sorting souths and norths, if south_start_day or north_start_day is nil or absent, calling jdn on them will raise a NoMethodError. Falling back to start_day ensures the sorting is robust and safe from crashes.

    souths = souths.sort_by { |e| jdn(e['south_start_day'] || e['start_day']) }.map { |e| court_era(e, :south) }
    norths = norths.sort_by { |e| jdn(e['north_start_day'] || e['start_day']) }.map { |e| court_era(e, :north) }

@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 97.13%. remained the same — feature/era-defs-from-manakai into master

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the Wikipedia-scraping era-definition generator with a generator that derives lib/wareki/era_def.rb from manakai/data-locale’s era-defs.json, aligning era sourcing with the existing kyuureki calendar data pipeline.

Changes:

  • Add build-util/gen-era-def.rb and remove the old build-util/parse_wikipedia.rb generator.
  • Regenerate lib/wareki/era_def.rb from manakai data (adjusting specific historical boundaries as described).
  • Update documentation and specs to reflect the new data source and corrected boundaries.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
spec/utils_spec.rb Updates a boundary-related spec case to match manakai semantics for 朱鳥 coverage.
README.md Updates documentation to state manakai/data-locale as the source for both era and calendar data.
lib/wareki/era_def.rb Regenerated era definition constants and adds “generated file” header comments.
ChangeLog Notes the generator/source change and the resulting boundary corrections.
build-util/parse_wikipedia.rb Removes the Wikipedia-based generator.
build-util/gen-era-def.rb Adds the new manakai-based era definition generator script.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread build-util/gen-era-def.rb
Comment on lines +50 to +52
def modern?(era)
era['start_year'] >= MEIJI_FIRST_YEAR
end
Comment thread build-util/gen-era-def.rb
Comment on lines +115 to +118
if $0 == __FILE__
io = ARGV.first ? File.open(ARGV.first) : URI.open(Wareki::EraDefGenerator::SOURCE_URL)
Wareki::EraDefGenerator.new(io).generate
end
@sugi
sugi merged commit 2516502 into master Jul 13, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants