Skip to content

Conversation

sffc
Copy link
Member

@sffc sffc commented Sep 27, 2025

@CLAassistant

This comment was marked as spam.

@CLAassistant

This comment was marked as spam.

@sffc sffc changed the title Add a FastPinqi approximation for LunarChinese calendar Add a FastPingqi approximation for LunarChinese calendar Sep 27, 2025
@sffc
Copy link
Member Author

sffc commented Sep 27, 2025

I think this is probably the best Chinese approximation that doesn't require tables or sine functions.

The next step up in accuracy would be to use tables for the solar terms and new moons. We can pre-calculate the exact timings of the solar terms in a 12-period cycle, and the new moons in a 223-period cycle (the Saros cycle), and hard code these results, then just extrapolate these cycles to infinity. This gives more accurate results for the nearby centuries, until it ultimately still drifts.

But, we don't care too much about accuracy in the range of dates that will be using this approximation.

@Manishearth
Copy link
Member

Haven't looked deeply at the code yet but this approach seems interesting.

Can we get it to match the ground truth pre-1912 for a decent set of dates?

@sffc
Copy link
Member Author

sffc commented Sep 29, 2025

Haven't looked deeply at the code yet but this approach seems interesting.

Can we get it to match the ground truth pre-1912 for a decent set of dates?

It's worth trying, but I'm not sure if it will solve the problem completely, because although it adopts an older method for solar terms, it also uses a very simplistic method for the new moons, which will introduce its own errors.

@robertbastian
Copy link
Member

It's worth trying, but I'm not sure if it will solve the problem completely, because although it adopts an older method for solar terms, it also uses a very simplistic method for the new moons, which will introduce its own errors.

In addition to using different astronomics, pre-1912 calculations used local apparent time, not local mean time like this code.

The next step up in accuracy would be to use tables for the solar terms and new moons.

I think the main requirement for this approximation is that it does not break our internal and public assumptions. I see two main requirements:

  • related_iso needs to round-trip
    • the approximation needs to stay in sync with Gregorian years
  • the results need to be encodable as LunarChineseYearData
    • the approximation needs to produce new years no earlier than Jan 19, and no later than 64 days after that
    • the approximation needs to produce at most one leap month per year
    • ...?

As long as these requirements are upheld (I think they are), I don't see the need to overly complicate the calculations. Trying to match ground truth even for a short period is a losing battle and we have better solutions (just hardcode the data).

@Manishearth
Copy link
Member

Trying to match ground truth even for a short period is a losing battle and we have better solutions (just hardcode the data).

So the primary goal of this is to have a well-behaved approximation (ideally, one that does not break calendrical invariants in far past dates) that is less computation and less code.

I think if possible we should try and pick the parameters such that it matches in its tail end, before whatever our data cutoff date is (1912 or 1900). It's a thing we should try, not a goal: "hardcode the data" just pushes it further back. It seems good to have some best-effort overlap where possible.

@robertbastian
Copy link
Member

I think trying to match ground truth data is bad even. We should be very explicit about which ranges are correct ground truth data and which ranges are an approximation that only exists to satisfy temporal's need. If anyone actually wants to use the Chinese calendar for the 19th century or earlier, this approximation should give results as erroneous as possible so that users realise this and use correct ground truth data.

@Manishearth
Copy link
Member

That's reasonable.

@sffc
Copy link
Member Author

sffc commented Sep 30, 2025

In addition to using different astronomics, pre-1912 calculations used local apparent time, not local mean time like this code.

This code isn't opinionated between these. It is all based on the local time of the winter solstice and new moon in the constructor.

I think if possible we should try and pick the parameters such that it matches in its tail end, before whatever our data cutoff date is (1912 or 1900).

I agree that it seems nice to match the "tail end", but I don't have a good sense of how long this approximation will be matching the "tail end". It might be a few months or it might be a few years.

month_lengths,
leap_month: Some(potential_leap_month.unwrap()),
},
_ => unreachable!(),
Copy link
Member Author

Choose a reason for hiding this comment

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

The code has a lot of panics that will need to be cleaned up before we would graduate this.

@Manishearth
Copy link
Member

I was mostly hoping that if we can get it to match the ground truth we can make a wider claim of dates for free without carrying extra data

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.

4 participants