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 12:23
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » Help me take a look at my code -- to determine a leap year, where is the problem? View 3,141 Replies 16
Original Poster Posted 2006-11-01 22:12 ·  中国 上海 东方有线
初级用户
Credits 35
Posts 14
Joined 2006-10-16 05:53
19-year member
UID 65933
Status Offline
set UDAY=0
for /L %%i in (1971,1,%YEAR%) do (
set /a temp1="%%i%%4"
::Remainder when divided by 4
set /a temp2="%%i%%100"
::Remainder when divided by 100
set /a temp3="%%i%%400"
::Remainder when divided by 400
if %temp1%==0 if not %temp2%==0 set /a UDAY="%UDAY%+366"&set TAG=r else if %temp3%==0 set /a UDAY="%UDAY%+366"&set TAG=r else set /a UDAY="%UDAY%+365"&set TAG=p)


::The code is to determine whether it is a leap year and accumulate days
It seems that the tempx is not calculated, and I can't figure it out. Great guys, please give me some pointers, thank you very much!

[ Last edited by hhl on 2006-11-1 at 10:32 PM ]
Floor 2 Posted 2006-11-01 22:25 ·  中国 上海 东方有线
初级用户
Credits 35
Posts 14
Joined 2006-10-16 05:53
19-year member
UID 65933
Status Offline
There is a problem with the use of variables in the `if` condition. In the `if` statement, when using variables like `%temp1%`, `%temp2%`, `%temp3%`, since it's in a loop, you should use delayed expansion. The corrected code should be like this (assuming delayed expansion is enabled):

```batch
@echo off
setlocal enabledelayedexpansion
set UDAY=0
set YEAR=2023
for /L %%i in (1971,1,%YEAR%) do (
set /a temp1=%%i%%4
::Remainder when divided by 4
set /a temp2=%%i%%100
::Remainder when divided by 100
set /a temp3=%%i%%400
::Remainder when divided by 400
if!temp1!==0 (
if not!temp2!==0 (set /a UDAY=!UDAY!+366&set TAG=r) else if!temp3!==0 (set /a UDAY=!UDAY!+366&set TAG=r) else (set /a UDAY=!UDAY!+365&set TAG=p))
else (set /a UDAY=!UDAY!+365&set TAG=p)
)
endlocal
```

The main issue was that without delayed expansion, the variables `temp1`, `temp2`, `temp3` couldn't get the correct values in the `if` condition during the loop iteration.
Floor 3 Posted 2006-11-01 22:36 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
Credits 5,310
Posts 2,044
Joined 2005-09-26 12:00
20-year member
UID 42843
Gender Male
From 四川南充
Status Offline
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set UDAY=0
for /L %%i in (1971,1,%YEAR%) do (
set/a temp1=%%i%%4
set/a temp2=%%i%%100
set/a temp3=%%i%%400
echo !temp1! !UDAY!
if !temp1!==0 if not !temp2!==0 (set /a UDAY=!UDAY!+366&set TAG=r) else (if !temp3!==0 (set /a UDAY=!UDAY!+366&set TAG=r) else (set /a UDAY=!UDAY!+365&set TAG=p)))
Floor 4 Posted 2006-11-01 22:40 ·  中国 上海 东方有线
初级用户
Credits 35
Posts 14
Joined 2006-10-16 05:53
19-year member
UID 65933
Status Offline
Ask the super moderator:

What does SETLOCAL ENABLEDELAYEDEXPANSION mean?

What does the echo !temp1! !UDAY! sentence mean?

Why do the tempx and UDAY variables need to be enclosed in !!?
Floor 5 Posted 2006-11-01 22:44 ·  中国 江苏 苏州 电信
银牌会员
★★★
Credits 1,181
Posts 533
Joined 2006-08-14 12:54
19-year member
UID 60484
Status Offline
Floor 6 Posted 2006-11-01 22:45 ·  中国 江苏 苏州 电信
银牌会员
★★★
Credits 1,181
Posts 533
Joined 2006-08-14 12:54
19-year member
UID 60484
Status Offline
Search the forum for "variable delay".
Floor 7 Posted 2006-11-01 22:56 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
Credits 5,310
Posts 2,044
Joined 2005-09-26 12:00
20-year member
UID 42843
Gender Male
From 四川南充
Status Offline
Originally posted by hhl at 2006-11-1 22:40:
Ask the super moderator:
What does SETLOCAL ENABLEDELAYEDEXPANSION mean?
What does the echo !temp1! !UDAY! mean?
Why do the tempx and UDAY variables need to be enclosed in !!?

The echo !temp1! !UDAY! is for debugging.
You can enter:
for/?
at the command line to know why the tempx and UDAY variables need to be enclosed in !!
But your code still has some problems, let's modify it again:
SETLOCAL ENABLEDELAYEDEXPANSION
set UDAY=0
set YEAR=2000
for /L %%i in (1971,1,%YEAR%) do (
set/a temp1=%%i%%4
set/a temp2=%%i%%100
set/a temp3=%%i%%400
if !temp1!==0 (if not !temp2!==0 (set /a UDAY=!UDAY!+366&set TAG=r) else (if !temp3!==0 (set /a UDAY=!UDAY!+366&set TAG=r) else (set /a UDAY=!UDAY!+365&set TAG=p))) else set /a UDAY=!UDAY!+365&set TAG=p)


[ Last edited by 不得不爱 on 2006-11-1 at 10:57 PM ]
Floor 8 Posted 2006-11-01 23:04 ·  中国 广东 佛山 广东睿江科技有限公司
荣誉版主
★★★★
batch fan
Credits 5,226
Posts 1,737
Joined 2006-03-10 00:38
20-year member
UID 51697
From 成都
Status Offline
Originally posted by hhl at 2006-11-1 22:25:
::Algorithm, copied from the C language book, a leap year is a year divisible by 4 but not by 100; a year divisible by 400 is also a leap year...

  In my impression, as long as a year is divisible by 4, it is a leap year. Why is the algorithm in C so complicated and seems to be against the definition of a leap year?
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
Floor 9 Posted 2006-11-01 23:09 ·  中国 上海 东方有线
初级用户
Credits 35
Posts 14
Joined 2006-10-16 05:53
19-year member
UID 65933
Status Offline
Thanks, everyone upstairs, very grateful. Hehe, I'm a new CMD user, and I don't know many grammars and operators clearly.
Floor 10 Posted 2006-11-01 23:10 ·  中国 上海 东方有线
初级用户
Credits 35
Posts 14
Joined 2006-10-16 05:53
19-year member
UID 65933
Status Offline
Hehe, Moderator namejm, please refer to Tan Haoqiang's classic C book.
Floor 11 Posted 2006-11-01 23:18 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
Credits 5,310
Posts 2,044
Joined 2005-09-26 12:00
20-year member
UID 42843
Gender Male
From 四川南充
Status Offline
Originally posted by namejm at 2006-11-1 23:04:

In my impression, as long as the year is divisible by 4, it is a leap year. Why is the algorithm in C so complicated and seems a bit inconsistent with the definition of a leap year?

Haven't you studied the calendar?
Leap every 4 years
Leap less every 100 years
Leap more every 400 years
The reason is that each year is 365.2422 days
Floor 12 Posted 2006-11-01 23:28 ·  中国 广东 佛山 广东睿江科技有限公司
荣誉版主
★★★★
batch fan
Credits 5,226
Posts 1,737
Joined 2006-03-10 00:38
20-year member
UID 51697
From 成都
Status Offline
Hehe, I don't know much about the calendar. The concept of leap years even came from the math textbook in primary school. Please forgive me.
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
Floor 13 Posted 2006-11-02 00:45 ·  中国 广东 清远 联通
高级用户
★★
Credits 846
Posts 247
Joined 2006-10-27 12:03
19-year member
UID 68504
Gender Male
From 湖南==》广东
Status Offline
Haha, I didn't know that originally either. I just knew that those divisible by 4 are leap years. Now I know, thanks!
Floor 14 Posted 2006-11-02 03:53 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
Credits 1,218
Posts 485
Joined 2006-07-21 21:24
19-year member
UID 58987
From 湖南.娄底
Status Offline
The conditions for determining a leap year are:
1. Divisible by 4 but not divisible by 100.
2. Divisible by 100 and also divisible by 400.

C language is really powerful, and the simplest way to determine a leap year is completed by logical operations. It's a pity that batch processing doesn't have such an operation type. I wonder if more complex CMD code can be used to simulate logical operations.


@echo off
set /p year=Please enter the year:
set /a x=%year%%%4
set /a y=%year%%%100
set /a z=%year%%%400
if %x%==0 (
if %y%==0 (
if %z%==0 (
set term=1
) else (
set term=0
)
) else (
set term=1
)
) else (
set term=0
)
if %term%==1 (
echo %year% is a leap year.
) else (
echo %year% is not a leap year.
)
pause



@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /l %%i in (1971,1,2008) do (
set /a x=%%i%%4
set /a y=%%i%%100
set /a z=%%i%%400
if !x!==0 (
if !y!==0 (
if !z!==0 (
set term=1
) else (
set term=0
)
) else (
set term=1
)
) else (
set term=0
)
if !term!==1 (
set /a uday+=366
) else (
set /a uday+=365
)
)
echo The total number of days from 1971 to 2008 is:%uday%
pause


[ Last edited by pengfei on 2006-11-2 at 04:26 AM ]
Floor 15 Posted 2006-11-02 04:41 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
Credits 5,310
Posts 2,044
Joined 2005-09-26 12:00
20-year member
UID 42843
Gender Male
From 四川南充
Status Offline
```@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /l %%i in (1971,1,2008) do (
set /a x=%%i%%4
set /a y=%%i%%100
set /a z=%%i%%400
if !x!==0 if !y!==0 (if !z!==0 set/a t+=1) else set/a t+=1)
set/a t=(2008-1971+1)*365+t
echo The total number of days from 1971 to 2008 is: %t%
pause
```
Forum Jump: