China DOS Union

-- Unite DOS · Advance DOS · Grow DOS --

Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum
DOS stands for freedom, openness and progress. Let us work hard, learn from the openness and GNU spirit of FreeDOS and Linux, and together build and grow a free GNU GPL world!

中国DOS联盟论坛
The time now is 2026-06-23 15:53
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » Batch version perpetual calendar DigestI View 16,198 Replies 44
Original Poster Posted 2007-05-26 20:43 ·  中国 广东 广州 天河区 电信
初级用户
Credits 82
Posts 15
Joined 2007-05-26 20:14
19-year member
UID 89403
Gender Male
Status Offline
────────── Moderator Note ──────────
For the improved code, please see qzwqzw's script on the 20th floor
────────── Moderator Note ──────────


::Algorithm: Kim Larsen calculation formula
::W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
::In the calendar ★=today
::Leap year calculation has not been added yet. So every February has 28 days


@echo off& color 27 & mode con cols=40 lines=20 & title Calendar, made by 泛滥棏慌°.QQ:173459058&&setlocal enabledelayedexpansion
set dated=%date%
:home
cls&echo/
set zdate=%date%
set y=%zdate:~0,4%
set m=%zdate:~5,2%
set d=%date:~8,2%
if %d% geq 32 (echo Invalid date.&pause>nul&exit)
set d1=01
if "%m%"=="01" (set /a y-=1& set /a m+=12)
if "%m%"=="02" (set /a y-=1& set /a m+=12)
::Week calculation formula
set /a w=(%d1%+2*%m%+3*(%m%+1)/5+%y%+%y%/4-%y%/100+%y%/400)%%7+1
set /a ww=(%d%+2*%m%+3*(%m%+1)/5+%y%+%y%/4-%y%/100+%y%/400)%%7+1
set 1=Mon&set 2=Tue&set 3=Wed&set 4=Thu&set 5=Fri&set 6=Sat&set 7=Sun
if "%date%"=="%dated%" (
echo This is the %date:~0,4%-%date:~5,2% calendar Today:%dated:~0,4%!-%dated:~5,2%-%dated:~8,2%
) else (
echo This is the %date:~0,4%-%date:~5,2% calendar ★=today
echo The date you queried is:%date%, week!%ww%!
)
::Leap year calculation has not been added yet. So every February has 28 days
set %m%m=31&set %m%m=28&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30
set %m%m=31&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30&set %m%m=31
set /a cyc=!%m%m!+%w%-1
set n=0
for /l %%i in (0,1,40) do (set w%%i= )
for /l %%i in (%w%,1,%cyc%) do (
set /a n+=1
set w%%i=0!n!
if !n! GEQ 10 set w%%i=!n!
if !n! EQU !d! set w%%i=★
)
echo/
echo Sun Mon Tue Wed Thu Fri Sat
echo ━━━━━━━━━━━━━━━━━━━━
echo %w0% %w1% %w2% %w3% %w4% %w5% %w6%
echo.
echo %w7% %w8% %w9% %w10% %w11% %w12% %w13%
echo.
echo %w14% %w15% %w16% %w17% %w18% %w19% %w20%
echo.
echo %w21% %w22% %w23% %w24% %w25% %w26% %w27%
echo.
echo %w28% %w29% %w30% %w31% %w32% %w33% %w34%
echo ━━━━━━━━━━━━━━━━━━━━
echo Enter year-month-day to view that month's calendar and the weekday of that day
set /p date=Format like (2007-02-03)-Exit:
if /i "%date%"=="E" exit
goto :home


[ Last edited by bjsh on 2007-7-31 at 02:36 PM ]
Recent Ratings for This Post ( 5 in total) Click for details
RaterScoreTime
lxmxn +12 2007-05-26 20:50
huzixuan +4 2007-05-27 15:39
qzwqzw +3 2007-05-27 16:18
Vampire +2 2007-06-02 23:50
AlexZhang +4 2007-08-01 18:42
Floor 2 Posted 2007-05-26 20:51 ·  中国 湖北 武汉 电信
版主
★★★★★
Credits 11,386
Posts 4,938
Joined 2006-07-23 17:10
19-year member
UID 59080
Status Offline
Not bad. If you add a function to judge leap years, it will be even more perfect.
Floor 3 Posted 2007-05-27 14:30 ·  中国 广东 东莞 电信
初级用户
Credits 107
Posts 48
Joined 2006-11-30 12:06
19-year member
UID 72174
Gender Male
Status Offline
It would be even better if it could check the lunar calendar too! Ha~
她希望我把粪土变黄金,我希望她视黄金如粪土!
Floor 4 Posted 2007-05-27 15:12 ·  中国 山西 运城 联通
银牌会员
★★★
天的白色影子
Credits 2,343
Posts 636
Joined 2004-03-06 00:00
22-year member
UID 19350
Gender Male
Status Offline
I tried it

Aside from 31-day months like 2006-12 showing 30 days

all the other months show 31 days

The problem is in these lines

set %m%m=31&set %m%m=28&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30
set %m%m=31&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30&set %m%m=31

Still needs more work
Floor 5 Posted 2007-05-27 16:13 ·  中国 山东 淄博 联通
中级用户
★★
Credits 272
Posts 99
Joined 2006-06-02 09:12
20-year member
UID 56414
Status Offline
This calendar is also pretty good
http://www.cn-dos.net/forum/viewthread.php?tid=27739&fpage=11

It can also support any year including leap years
http://www.cn-dos.net/forum/viewthread.php?tid=27739&page=2#pid195566

[ Last edited by my3439955 on 2007-5-27 at 04:20 PM ]
Floor 6 Posted 2007-05-27 16:23 ·  中国 山东 淄博 联通
中级用户
★★
Credits 272
Posts 99
Joined 2006-06-02 09:12
20-year member
UID 56414
Status Offline
Originally posted by ieutk at 2007-5-27 14:30:
It would be even better if it could check the lunar calendar too! Ha~


There is no regular formula for the lunar calendar; you can only calculate a certain span of time and then use a lookup table
If you don't believe it, look at those perpetual calendars that support the lunar calendar
Support for the lunar calendar generally will not exceed 200 years
For the Gregorian calendar there is no such limitation
You can go to any year
Floor 7 Posted 2007-05-27 17:45 ·  中国 广东 广州 天河区 电信
初级用户
Credits 82
Posts 15
Joined 2007-05-26 20:14
19-year member
UID 89403
Gender Male
Status Offline
Originally posted by qzwqzw at 2007-5-27 03:12 PM:
I tried it

Aside from 31-day months like 2006-12 showing 30 days

all the other months show 31 days

The problem is in these lines

set %m%m=31&set %m%m=28&set %m%m=31&set %m%m=30&set %m%m ...



Thanks to brother qzwqzw for helping test it. I've thought it over, and I'll post the revised version later.
Floor 8 Posted 2007-05-27 18:14 ·  中国 山西 运城 联通
银牌会员
★★★
天的白色影子
Credits 2,343
Posts 636
Joined 2004-03-06 00:00
22-year member
UID 19350
Gender Male
Status Offline
For the lunar calendar, maybe there is a way that doesn't require table lookup

My father told me that back in his hometown there was a fool

Normally he was crazy and muddle-headed

But he alone had mastered a "divine skill" that people really admired

Namely, he had memorized the old imperial almanac for the past five hundred years

Questions like big and small lunar months and leap months were no problem at all for him

I never met the man, and to this day I don't know what method he used

---------------------------------------------------------

From a rational point of view

The lunar calendar used nowadays

Although it was finalized only after revisions through many dynasties

Ultimately still comes from the earliest Xia calendar

And the revision and perfection of the Xia calendar mainly depended on achievements in astronomy

Other than that, there ought to be a purely mathematical way to calculate and predict it

[ Last edited by qzwqzw on 2007-5-27 at 06:17 PM ]
Floor 9 Posted 2007-05-27 19:50 ·  中国 广东 广州 天河区 电信
初级用户
Credits 82
Posts 15
Joined 2007-05-26 20:14
19-year member
UID 89403
Gender Male
Status Offline
qzwqzw brother, I changed this middle section
set %m%m=31&set %m%m=28&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30
set %m%m=31&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30&set %m%m=31
set /a cyc=!%m%m!+%w%-1

to
for %%i in (04 06 09 11) do if "%m%"=="%%i" set flag=1
if defined flag (set cyc1=30) else (set cyc1=31)
set /a leap=%y%%%4
if %m% equ 2 set cyc1=28
if %leap% EQU 0 (if %m% EQU 2 set cyc1=29)
set /a cyc=%cyc1%+%w%-1

The results didn't improve much. The bigger problem seems to be in for /l %%i in (%w%,1,%cyc%)
I really can't figure it out. Please help improve it.
Floor 10 Posted 2007-05-28 00:29 ·  中国 江西 南昌 电信
银牌会员
★★★
天的白色影子
Credits 2,343
Posts 636
Joined 2004-03-06 00:00
22-year member
UID 19350
Gender Male
Status Offline
The main problem is that the weekday order calculated by the formula is not consistent with the weekday order shown in the calendar

The formula calculates with Monday as the start and Sunday as the end

The calendar display is exactly the opposite

The solution is very simple

Just switch either the formula's weekday order or the calendar's display order

To switch the formula's weekday order, just move that +1 inside the parentheses

------------------------------------

Also, the 2006-12 problem is solved

You need to add one more display line and also add two more variables

-------------------------------------

There are still some other problems

For example, the bare variable in if %d% geq 32

And the leading-0 problem with variables m / d

And then there's the issue of variable naming conventions

---------------------------------------------

Below is my code


@echo off& color 27 & mode con cols=40 lines=20 && setlocal enabledelayedexpansion
set sdate=%date%
:home
cls&echo.
for /f "tokens=1,2,3 delims=-/: " %%i in ("%sdate%") do (
(set sy=%%i) && (set sm=%%j) && (set sd=%%k)
)
(set sm=10%sm%) && (set sd=10%sd%)
(set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set /a m=1%sm%-100, d=1%sd%-100
if %m% geq 13 (echo.Invalid date.&pause>nul&goto :eof)
if %d% geq 32 (echo.Invalid date.&pause>nul&goto :eof)
set fd=01
set y=%sy%
set /a leap="^!(y %% 4) & ^!(^!(y %% 100)) | ^!(y %% 400)"
::Week calculation formula
if 1%m% leq 12 (set /a y-=1& set /a m+=12)
set /a begin=(fd+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%%7
set /a week=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%%7

set weektbl=SunMonTueWedThuFriSat
set prmt=today
if "%sdate%"=="%date%" set prmt=Today
echo. %sy%-%sm% %prmt%:%sy%-%sm%-%sd%, week!weektbl:~%week%,1!

set /a flag=0, n=0
for %%i in (4 6 9 11) do if "%m%"=="%%i" set flag=1
set /a len=31 - flag
if "%m%"=="14" set /a len=28+leap
for /l %%i in (0,1,36) do (set w%%i= )
set /a end=%len%+%begin%-1
for /l %%i in (%begin%,1,%end%) do (
set /a n+=1
set temp=0!n!
set w%%i=!temp:~-2!
if !n! EQU !d! set w%%i=★
)
echo.
echo. Sun Mon Tue Wed Thu Fri Sat
echo.━━━━━━━━━━━━━━━━━━━━
echo. %w0% %w1% %w2% %w3% %w4% %w5% %w6%
echo.
echo. %w7% %w8% %w9% %w10% %w11% %w12% %w13%
echo.
echo. %w14% %w15% %w16% %w17% %w18% %w19% %w20%
echo.
echo. %w21% %w22% %w23% %w24% %w25% %w26% %w27%
echo.
echo. %w28% %w29% %w30% %w31% %w32% %w33% %w34%
echo.
echo. %w35% %w36%
echo.━━━━━━━━━━━━━━━━━━━━
echo.Enter year-month-day to view that month's calendar and the weekday of that day
set sdate=
set /p sdate=Format like (2007-02-03)-Exit:
if /i "%sdate%"=="" goto :eof
goto :home
Floor 11 Posted 2007-05-28 00:57 ·  中国 广东 广州 天河区 电信
初级用户
Credits 82
Posts 15
Joined 2007-05-26 20:14
19-year member
UID 89403
Gender Male
Status Offline
Thanks, now that's really perfect.
Floor 12 Posted 2007-06-02 23:38 ·  中国 广东 电信
荣誉版主
★★★★
batch fan
Credits 5,226
Posts 1,737
Joined 2006-03-10 00:38
20-year member
UID 51697
From 成都
Status Offline
  Based on the one on the 10th floor, I modified it a bit and got the following code. The changes in effect are as follows:

  1. The positions of the dates are fixed, while the weekday sequence changes dynamically;

  2. Dates below 10 do not have a leading 0;

  3. If you enter today's date again, it will always display "Today" instead of "that day";

@echo off
:: Algorithm: Kim Larsen calculation formula
:: W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
:: Treat January and February as the 13th and 14th months of the previous year
:: Example: if it is 2004-1-10 then convert it to: 2003-13-10 and substitute it into the formula.
color 27
mode con cols=40 lines=20
setlocal enabledelayedexpansion
set str=MonTueWedThuFriSatSunMonTueWedThuFriSatSun
set sdate=%date%

:Main
cls&echo.
:: Extract the date and check for errors
for /f "tokens=1,2,3 delims=-/: " %%i in ("%sdate%") do (
(set sy=%%i) && (set sm=%%j) && (set sd=%%k)
)
(set sm=10%sm%) && (set sd=10%sd%)
(set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set /a m=1%sm%-100, d=1%sd%-100
if %m% geq 13 (echo.Invalid date.&pause>nul&goto :eof)
if %d% geq 32 (echo.Invalid date.&pause>nul&goto :eof)

:: Calculate the number of days in each month
set max=31
for %%i in (4 6 9 11) do if %m% equ %%i set max=30
:: Calculate February adjustment
if %m% leq 2 (set /a y-=1& set /a m+=12)
set /a leap="^!(y%%4) & ^!(^!(y%%100)) | ^!(y%%400)"
if %m% equ 14 set /a max=28+%leap%

:: Calculate the weekday of the specified date
set /a w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%%7

:: Calculate the dynamic weekday sequence
set /a num=w-(d%%7-1)
set var=!str:~%num%,1!
for /l %%i in (0,1,6) do (
set var_tmp=!str:~%%i,1!
if "!var!"=="!var_tmp!" set var=!str:~%%i,7!
)


set prmt=that day
if "%sy%-%sm%-%sd%"=="%date%" set prmt=Today
echo. %sy%-%sm% %prmt%:%sy%-%sm%-%sd%,week !str:~%w%,1!
echo.

:: Generate the weekday sequence for the header
for /l %%i in (0,1,6) do set /p= !var:~%%i,1!<nul

:: Generate the date sequence
echo.
echo ━━━━━━━━━━━━━━━━━━━━
for /l %%i in (1,1,%max%) do (
set /a num=%%i%%7
set var= %%i
set var=!var:~-2!
if %d% equ %%i (
set /p= ★<nul
) else set /p= !var!<nul
if !num! equ 0 echo.&echo.
)
echo.
echo ━━━━━━━━━━━━━━━━━━━━
echo.Enter year-month-day to view that month's calendar and the weekday of that day
set sdate=
set /p sdate=Format like (2007-02-03)-Exit:
if not defined sdate exit
goto Main


[ Last edited by namejm on 2007-6-2 at 11:50 PM ]
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
Floor 13 Posted 2007-06-03 00:07 ·  中国 江西 南昌 电信
银牌会员
★★★
天的白色影子
Credits 2,343
Posts 636
Joined 2004-03-06 00:00
22-year member
UID 19350
Gender Male
Status Offline
This display method does not fit everyday habits

I guess it would be hard for people to accept

If you don't want to use too many variables

you can use for to output the dates in order

As long as you control the timing of line breaks, there won't be any problem

Also it would be best to control the range and format of the year

At most you only need to enter a two-digit year

50~99 is judged as 19xx
00~49 is judged as 20xx

There isn't much point in calculating weekdays too far away
Floor 14 Posted 2007-06-03 00:15 ·  中国 广东 电信
荣誉版主
★★★★
batch fan
Credits 5,226
Posts 1,737
Joined 2006-03-10 00:38
20-year member
UID 51697
From 成都
Status Offline
  The method of dynamically displaying the weekday sequence really doesn't quite fit common habits. I just thought it was interesting, so I adapted it a bit, hehe, just putting it out as a new effect.

  As for the sentence "There isn't much point in calculating weekdays too far away," I'm not sure what exactly that refers to. I don't have too many thoughts on it for now, but if you have any interesting ideas, I'd like to hear them too ^_^.
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
Floor 15 Posted 2007-06-03 02:16 ·  中国 江西 南昌 电信
银牌会员
★★★
天的白色影子
Credits 2,343
Posts 636
Joined 2004-03-06 00:00
22-year member
UID 19350
Gender Male
Status Offline
For example, the effect of the following code


@echo off
:: Algorithm: Kim Larsen calculation formula
:: W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
:: Treat January and February as the 13th and 14th months of the previous year
:: Example: if it is 2004-1-10 then convert it to: 2003-13-10 and substitute it into the formula.
color 27
mode con cols=40 lines=20
setlocal enabledelayedexpansion
set str=SunMonTueWedThuFriSat
set prmt=Today
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)
)
(set sy=00%sy%) && (set sm=10%sm%) && (set sd=10%sd%)
(set sy=%sy:~-2%) && (set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set /a y=1%sy%-100, m=1%sm%-100, d=1%sd%-100
if %y% lss 50 (set /a y+=2000) else (set /a y+=1900)
set sy=%y%
if %m% geq 13 (echo.Invalid date.&pause>nul&goto :eof)
if %d% geq 32 (echo.Invalid date.&pause>nul&goto :eof)

:: 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 February adjustment
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 weekday of the specified date
set /a w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%%7

echo. %sy%-%sm% %prmt%:%sy%-%sm%-%sd%,week !str:~%w%,1!
echo.

:: Generate the date sequence
set /a wb=(w+35-d) %% 7, we=wb+days+1, day=1
echo. Sun Mon Tue Wed Thu Fri Sat
echo. ━━━━━━━━━━━━━━━━━━━
set /p= <nul
for /l %%i in (0,1,36) do (
set "temp= "
if %%i GTR %wb% if %%i LSS %we% (
set temp=0!day!
set temp=!temp:~-2!
if !d! EQU !day! set temp=★
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 a date to view that month's calendar and the weekday of that day
echo.
set sdate=
set /p sdate= Format like: 07-02-03, Exit:
set prmt=that day
if defined sdate goto Main
Forum Jump: