1. ホーム
  2. スクリプト・コラム
  3. DOS/BAT(ドス・バット

万年暦(旧暦含む)の一括実装コード

2022-01-02 04:33:36

コアソースコード

:: Monthly Calendar Search Tool Originally published in CN-DOS
:: Original: foxjl Updated: namejm, qzwqzw, foxjl
:: Calculate the lunar date part of the idea and algorithm from "Fun Dong"
:: The input date format is: year - month - day (- can be replaced with :, /, can be mixed)
:: Inside the calendar, ★ = day
:: Multiple formats of date input are supported.
:: ① If only one number is entered, it is considered to be a query for the month of the current year, automatically intercepting the last two digits of the query, with ★ marked on the 1st day.
::: ② If two numbers are input, it is considered as querying the year and month, ★ marked on the 1st day.
:: ③ If you enter all, ★ mark on the specified date 
:: Regarding the conversion of the year.
:: ① If the number entered on the year is less than three, the conversion is made as follows. 
:: 50~99 will be converted to 19xx
:: 0~49 will be converted to 20xx
:: ② If more than two digits are entered in the year, the last four digits will be intercepted (with zeros added to the higher digit).
:: Calculate the date of the year according to the rules in ①. 
:: 07-08-04 Add the calculation of Chinese zodiac and stem-branch year for solar calendar; fix the bug of wrong date loop.
:: 08-01-13 Add the function of calculating the date of the lunar calendar, there will be an error of about one day.
@echo off
color 1f
mode con cols=40 lines=20
setlocal enabledelayedexpansion
set str=day one, two, three, four, five, six, seven, eight, nine
set sdate=%date%
:Main
cls&echo.
:: Date extraction, formatting and validation
for /f "tokens=1,2,3 delims=-/: " %%i in ("%sdate%") do (
  (set sy=%%i) && (set sm=%%j) && (set sd=%%k)
)
if not defined sd set sd=1
if not defined sm set sm=%sy%&set sy=%date:~0,4%
(set sy=0000%sy%) && (set sm=00%sm%) && (set sd=00%sd%)
(set sy=%sy:~-4%) && (set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set /a y=1%sy%-10000, m=1%sm%-100, d=1%sd%-100 2>nul
if errorlevel 9167 goto Error
if %y% lss 100 (
  if %y% lss 50 (set /a y+=2000) else (set /a y+=1900)
  set sy=!y!
)
if %m% lss 13 if %d% lss 32 goto Calc
:Error
echo. wrong date.
pause>nul
cd.
set sdate=%date%
goto Main
:Calc
::Calculate the lunar part
set/a Q=(y-1901)/4
set/a R=y-1901-4*Q
set n=0
for %%i in (0,31,59,90,120,151,181,212,243,273,304,334) do (
set /a n+=1
if %m% equ !n! set z=%%i)
set /a leap="^! (y%%%4) & ^! (^! (y%%100)) | ^! (y%%400)"
if %m% gtr 2 (if %leap% equ 0 (set /a z-=1) else (set /a z+=leap))
set/a n=(140*Q+106*(R+1)+z*10+d*10)/295,H=(140*Q+106*(R+1)+z*10+d*10-295*n)/10
if %h% equ 0 set h=29
if %h% leq 10 (if %h% equ 10 (set h=first ten) else (set h=first %h%)) else (set h=%h:~0,1% ten%h:~-1% number)
for /l %%i in (1,1,9) do (call set h=%%h:%%i=!str:~%%i,1!%%)
set h=%h:0=%
:: Calculate the year of the Chinese zodiac and its branches
set sx=Monkey, Rooster, Dog, Pig, Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Goat
set tg=Geng, Xin, Non, Dec, A, B, C, D, E, H
set dz=申酉戌亥子丑寅卯辰巳午未
set /a sxnum=%sy% %% 12
set /a tgnum=%sy:~-1%
title lunar!tg:~%tgnum%,1!!dz:~%sxnum%,1! year zodiac:!sx:~%sxnum%,1! lunar:%h%
:: Calculate the number of days in each month
set days=31
for %%i in (4 6 9 11) do if %m% equ %%i set days=30
:: Calculate the deviation for February
set /a leap="^! (y%%%4) & ^! (^! (y%%100)) | ^! (y%%400)"
if %m% equ 2 set /a days=28+%leap%
if %m% leq 2 (set /a y-=1& set /a m+=12)
:: Calculate the number of days of the week for the specified date
set /a w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%%7
echo. %sy%year%sm%month Date:%sy%-%sm%-%sd%,week!str:~%w%,1!
echo.
:: Generate the monthly calendar
set /a wb=(w+35-d) %% 7, we=wb+days+1, day=1
echo. day one two three four five six
echo. ━━━━━━━━━━━━━━━━━━━
set /p= <nul
for /l %%i in (0,1,37) do (
  set "temp= "
  if %%i GTR %wb% if %%i LSS %we% (
    set temp= !day!
    set temp=!temp:~-2!
    EQU !day! set temp=★ if !d!
    set /a day+=1
  )
  set /p= !temp!<nul
  set /a "wm=(%%i+1)%%7"
  if !wm! equ 0 echo.&echo.&set /p= <nul
)
echo.
echo ━━━━━━━━━━━━━━━━━━━
echo. enter the date to query the day of the week and display the monthly calendar for the month
echo.
set sdate=
set /p sdate= formatted as: 2007-02-03, [Enter] to exit:
if defined sdate goto Main

以下、各計算部のアルゴリズムです。

曜日を計算する。
キム・ラーセンの公式
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
式中、dは日付の日数+1、mは月数、yは年数を表しています。
注)他の計算式と異なる点が1つあります。
1月と2月は前年の13ヶ月目と14ヶ月目として考えてください。
例 2004-1-10であれば、次のように変換します。2003-13-10に変換して計算式に代入します。

干支と幹枝の年号の計算方法は

生まれた年の数字÷12、その商の余りを割って干支に並べるとすぐに分かる。
干支は 猿(0)、酉(1)、戌(2)、亥(3)、鼠(4)、丑(5)、寅(6)、卯(7)、辰(8)、巳(9)、馬(10)、山羊(11)です。

天の茎と地の枝のアルゴリズム。
まず、十全の天の茎と十二の地の枝を覚えられるようになることです。
10本の天の茎。A、B、C、D、E、F、G、X、N、J。
12の地上の枝。子、醜、殷、毛、陳、斯、呉、魏、申、庸、許、海。
まず、天の茎が前、地の枝が後ということですが、例えば今年2005年は李禹煥の年、まず天の茎を計算しましょう、計算式があります。
A、B、C、D、E、F、G、X、N、J。
は時代の下一桁で、例えば今年は2005年、下一桁は5、対応する天幹はBです。
地球分岐のアルゴリズム:年数を12で割って、その後の余りがある地球分岐を表し、余りがある。
4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3.
地上の枝は 子、醜、殷、毛、陳、斯、呉、魏、申、庸、許、海。
例えば、2005年:年末の数字は5、対応する天の幹は乙、2005年を12で割ると余りは1、対応する地上の枝は乙なので、2005年は乙卯の年であると言えます。

旧暦の日付部分のアルゴリズムは
旧暦の日付は、満月を月の数え方の単位とし、旧暦の1日を1日、15日を15日、29日を29日(旧暦の30日)としています。太陽暦の日付を太陰暦の日付に変換したい場合、次の2つの方法があります。1つは、"New Perpetual Calendar"を確認することです。例えば、1984年6月8日は太陰暦で何日でしょうか? 年鑑を開くと、6月10日は旧暦の11日で、6月8日は旧暦の9日であることを逆に説明します。2つ目は、公式を使って旧暦の日付を推論することができます。
させる。西暦の年数-1977年(または1901年)=4Q+R
すると、太陰暦の日付=14Q+10.6(R+1)+その年の日付列の数-29.5n
(注:式中のQ, R, nは自然数、R<4)
例 1994年5月7日の旧暦の日付は
1994-1977 = 17 = 4 x 4 + 1
したがって Q=4、R=1 では:5月7日の旧暦の日付は
14×4+10.6(1+1)+(31+28+31+30+7)-29.5n
= 204.2- 29.5n
次に、29.5から204.2を引くと商6が得られる・・・。.27.2、6はnの値、余りの27は旧暦の27日です。

バッチ式カレンダーの実装コード(旧暦の日付も含む)については、この記事がすべてです。バッチカレンダーについては、Script Houseの過去記事を検索していただくか、引き続き以下の関連記事をご覧ください。