wenyan-lang / wenyan

文言文編程語言 A programming language for the ancient Chinese.
https://wy-lang.org/
MIT License
19.56k stars 1.1k forks source link

吾嘗觀『曆法』之書 (Date library implementation proposal) #425

Open S-Asakoto opened 4 years ago

S-Asakoto commented 4 years ago

I have an idea on the implementation of date library:

Wenyan JS equivalent
吾有一時。名之曰「今」。 | 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)

LingDong- commented 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.

statementreply commented 4 years ago

Calendar

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.

Time

說文解字曰。晝夜百刻。後世改為九十六、百八、百二十刻。未知孰為可法。

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)

Time Zone

(Obvious to modern people)

Library Design

[3] 年 = calendar year, 歲 = winter solstice to winter solstice

S-Asakoto commented 4 years ago

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.

LingDong- commented 4 years ago

@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 :)

S-Asakoto commented 4 years ago

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.

statementreply commented 4 years ago

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.