Open S-Asakoto opened 4 years ago
Thanks a lot for the proposal. Date library placeholders are now added. See ./lib/曆法.wy
and ./lib/*/西曆法.wy
.
The idea is, we have a platform-specific call to the target language's date/time API wrapped in 西曆法.wy
, which mainly just gives the unix/epoch time. Then, we have the main library implemented in wenyan language in 曆法.wy
, which calculates the year/month/day/hour calculations based on Chinese Calendar, see below for details:
吾嘗觀「「西曆法」」之書。方悟「紀元時」之義。
注曰「「今之年月日時刻者。當以紀元時(Unix timestamp)推算之。」」
今有一術。名之曰「今歲何歲」。是術曰。
注曰「「歲者。當以天干地支紀之。古之年歲或以帝王年號。」」
是謂「今歲何歲」之術也。
今有一術。名之曰「今月何月」。是術曰。
注曰「「月者。正月至臘月也。」」
是謂「今月何月」之術也。
今有一術。名之曰「今日何日」。是術曰。
批曰「「古有越人歌。曰。今日何日兮,得與王子同舟。」」
是謂「今日何日」之術也。
今有一術。名之曰「今時何時」。是術曰。
注曰「「時者。子丑寅卯辰巳午未申酉戌亥」」
是謂「今時何時」之術也。
今有一術。名之曰「今辰何辰」。是術曰。
注曰「「夜半、雞鳴、平旦、日出、食時、隅中、日中、日昳、晡時、日入、黃昏、人定。」」
注曰「「實於地支紀時無異。蓋借辰字表天色計時法也。」」
是謂「今辰何辰」之術也。
今有一術。名之曰「今刻何刻」。是術曰。
注曰「「說文解字曰。晝夜百刻。後世改為九十六、百八、百二十刻。未知孰為可法。」」
是謂「今刻何刻」之術也。
I'm going to gradually fill in the implementations. Since calendar calculations are somewhat complex, so:
Hey everyone, if you're a pro on Chinese calendar, your help would be very much appreciated!
Thanks.
The rules and formula for calculation of Chinese calendar have been changed dozens of times in history. The last major revision took effect in 1645 (時憲曆), and there were several minor revisions later, including a change in 1929 to use +08:00 standard time instead of Beijing apparent solar time to determine the date of astronomical events.
The modern rules are based on astronomical calculation of the position of the sun, earth and moon. Most Chinese calendar software computes dates with look up tables.
說文解字曰。晝夜百刻。後世改為九十六、百八、百二十刻。未知孰為可法。
Basically (I could get the details wrong)
? - 1645 | Since 1645 |
---|---|
1 日 = 12 時 = 24 half-時 | 1 日 = 12 時 = 24 (小) 時 |
1 日 = 100 刻 | 1 日 = 96 刻 |
1 half-時 = (4 + 1/6) 刻 = 4 大刻 + 1 小刻[1] | 1 (小) 時 = 4 刻 |
1 刻 = 100 分 | 1 刻 = 15 分 |
[1] 百二十刻 = 96 大刻 + 24 小刻
For the event of new moon on 2020 Chinese new year (2020-01-24T21:42:00Z UTC)
Convention | Notation |
---|---|
UTC+8, modern 24h | 05:42:00 |
UTC+8, post-1645 | 卯初二刻十二分 |
UTC+8, pre-1645 | 卯初二刻九十一分 |
Beijing mean time[2], modern 24h | 05:27:42 |
Beijing mean time[2], post-1645 | 卯初一刻十二分 |
Beijing mean time[2], pre-1645 | 卯初一刻九十二分 |
Beijing apparent time[2], modern 24h | 05:15:39 |
Beijing apparent time[2], post-1645 | 卯初一刻 |
Beijing apparent time[2], pre-1645 | 卯初一刻八分 |
[2] Based on longitude of ancient Beijing observatory (116°25'41"E)
(Obvious to modern people)
num2hanzi
does now.[3] 年 = calendar year, 歲 = winter solstice to winter solstice
The paper by H. Aslaksen may give some insight on how to calculate the days, but to be honest it will be a tedious job because we need to gather observational data and, as in the paper, Chinese calendar is based on the "exact movement" of the Sun and the Moon.
@statementreply @S-Asakoto Thanks so much for all the information! It is indeed complex but I think it is an interesting and meaningful problem worth the time to solve. It's probably not as urgent as other language features, and we can tackle it bit by bit.
Returning strings would make it hard to use for purposes other than printing
I agree! Let's return numbers.
歲 = winter solstice to winter solstice
Great to learn!
The last major revision took effect in 1645 (時憲曆)
Perhaps if input is a time before 1645, we use the old system, if input time is after, we use the new system. This way it works for ancient people from all times :)
ELP2000-85 seems to be an entry point for such an algorithm, but the formulae are for lunar movements, so dealing with 中氣 still needs further study.
Edit: found a paper that presents the algorithm: https://ytliu0.github.io/ChineseCalendar/docs/sunMoon.pdf I have implemented part of the algorithm in JS and it's 2000+ LOC. Can't imagine how long this could be in Wenyan.
Maybe we should only focus on how to approximate the motion with simpler functions? The image in the Wikipedia page about Supermoon implies a super simple way for lunar motion.
I'm going for a LUT based method for #466. It is inefficient if each call to the calendar library invokes some complicated astronomical computation.
Maybe we could implement a lower accuracy solar and lunar motion algorithm as a starting point for the LUTs, but not directly into the stdlib.
I have an idea on the implementation of date library:
吾有一時。名之曰「今」。
|var 今 = new Date();
吾有一時。曰二千八年八月八日八時八分八秒。名之曰「昔」。
|var 昔 = new Date(2008, 8 - 1, 8, 8, 8, 8);
夫「今」之年。
|今.getFullYear();
夫「今」之月。
|今.getMonth() + 1;
夫「今」之日。
|今.getDate();
夫「今」之時。
|今.getHours();
夫「今」之分。
|今.getMinutes();
夫「今」之秒。
|今.getSeconds();
夫「今」之毫秒。
|今.getMilliseconds();
夫「今」之曜。
|今.getDay();
昔之「昔」之年者。今二千十八是矣。
|昔.setFullYear(2018);
昔之「昔」之月者。今十二是矣。
|昔.setMonth(12 - 1);
TODO add functions for date-time calculations (no JS equivalents yet)