Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

DOS Batch program countdown days until a given date.

765 views
Skip to first unread message

Chris Roberts

unread,
Feb 2, 2022, 10:02:05 AM2/2/22
to
DOS Batch program to countdown days/year (countdown date)

Hi,
Maybe someone can assist?
I am having trouble figuring out how to do this using a DOS/BATCH program.

For instance.
$ echo %date%%time%
Wed 02/02/2022 9:54:30.16

Would someone here know how I can subtract todays date from 11/8/22 to easily see how many days I still have to go?

Thanks
crzzy1


Kerr-Mudd, John

unread,
Feb 2, 2022, 11:48:37 AM2/2/22
to
--
Bah, and indeed Humbug.

Kerr-Mudd, John

unread,
Feb 2, 2022, 11:53:51 AM2/2/22
to
On Wed, 2 Feb 2022 07:02:02 -0800 (PST)
Chris Roberts <thec...@gmail.com> wrote:

Timo Salmi has probably "curated" an answer;

FWSE phrase "batch date arithmetic"



or are you a troll? 11/8/22 is ambiguous (US v UK date format)

Herbert Kleebauer

unread,
Feb 2, 2022, 12:06:00 PM2/2/22
to
Below are two subroutines which convert a date to the
numbers of days since 1. Jan. 1901 and reverse. Just call
the subroutine :date2day for both dates and calculate
the difference.



@echo off
setlocal disabledelayedexpansion

:: extract the variables %y% %m% %d% from the %date% variable
:: (this depends on the local date format)
:: valid year range: 1901-2099

set /a y=2004
set /a m=3
set /a d=1

call :date2day
set /a w=%w%-1
call :day2date

echo %y% %m% %d%
goto :eof


:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: convert the date in %y% %m% %d% to the number of days (%w%) ::
:: since 1901 (day 0 is 1. Jan. 1901) ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:date2day
set /a w=(%y%-1901)*365+(%y%-1901)/4+%d%-1+(!(%y% %% 4))*(!((%m%-3)^&16))
set /a w=(%w%+(%m%-1)*30+2*(!((%m%-7)^&16))-1+((65611044^>^>(2*%m%))^&3))
echo %y% %m% %d% %w%
goto :eof

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: convert the number of days in %w% to the date (%y% %m% %d%) ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:day2date
set /a x=%w%/1461
set /a w=%w%-%x%*1461
set /a z=%w%/365-((%w%/365)^>^>2)
set /a w=%w%-%z%*365
set /a y=1901+%x%*4+%z%
set /a v=%w%-!(%y% %% 4)
set /a m=!!(%w%/31)+!!(%v%/59)+!!(%v%/90)+!!(%v%/120)+!!(%v%/151)+!!(%v%/181)
set /a m=%m%+!!(%v%/212)+!!(%v%/243)+!!(%v%/273)+!!(%v%/304)+!!(%v%/334)+1
set /a d=%w%+1-(!(%y% %% 4))*(!((%m%-3)^&16))
set /a d=%d%-((%m%-1)*30+2*(!((%m%-7)^&16))-1+((65611044^>^>(2*%m%))^&3))
goto :eof

Chris Roberts

unread,
Feb 2, 2022, 2:13:25 PM2/2/22
to
Nope, Not a troll. I used the world renown election day 11/8/22 just for my example.
UK has the date format all backwards and Who's Timo Salmi? Who "Curates" answers anyway? :-)

Chris Roberts

unread,
Feb 2, 2022, 2:19:00 PM2/2/22
to
That's a cool script, I may use it.
But it says it "extract from the %date% variable" and then does NOT use %date% at all and instead statically defines the date.
I don't totally get :day2date It seems like a lot of variables for this simple task.

Thanks,
crzzy1

Herbert Kleebauer

unread,
Feb 2, 2022, 4:08:53 PM2/2/22
to
On 02.02.2022 20:18, Chris Roberts wrote:

> That's a cool script, I may use it.
> But it says it "extract from the %date% variable" and then does NOT use %date% at all and instead statically defines the date.

It says, you should extract the variables %y% %m% %d%
from the %date% variable. Because the code depends on
the local date format, it is not done in my example
but instead some fixed values are used to show the
usage of the two subroutines.


> I don't totally get :day2date It seems like a lot of variables for this simple task.

If it is a simple task, then do it yourself and
show us your code. Maybe there really is a much
simpler solution (I wanted a version without "IF"
and "GOTO").

Kerr-Mudd, John

unread,
Feb 2, 2022, 5:13:15 PM2/2/22
to
On Wed, 2 Feb 2022 11:13:23 -0800 (PST)
Chris Roberts <thec...@gmail.com> wrote:

> On Wednesday, February 2, 2022 at 11:53:51 AM UTC-5, Kerr-Mudd, John wrote:
> > On Wed, 2 Feb 2022 07:02:02 -0800 (PST)
> > Chris Roberts <thec...@gmail.com> wrote:
> > > DOS Batch program to countdown days/year (countdown date)
> > >
> > > Hi,
> > > Maybe someone can assist?
> > > I am having trouble figuring out how to do this using a DOS/BATCH program.
> > >
> > > For instance.
> > > $ echo %date%%time%
> > > Wed 02/02/2022 9:54:30.16
> > >
> > > Would someone here know how I can subtract todays date from 11/8/22 to easily see how many days I still have to go?
> >
> >
> > >
> > Timo Salmi has probably "curated" an answer;
> >
> > FWSE phrase "batch date arithmetic"
> >
> >
> >
> > or are you a troll? 11/8/22 is ambiguous (US v UK date format)
> > --
> > Bah, and indeed Humbug.
>
> Nope, Not a troll. I used the world renown election day 11/8/22 just for my example.
> UK has the date format all backwards and Who's Timo Salmi? Who "Curates" answers anyway? :-)

This fellow:

http://www.elisanet.fi/tsalmi/info/tscmd001.html

He copied stuff from amb onto his web pages which he then claimed his copyright to. To be fair he did write a lot of the stuff himself as well.

JJ

unread,
Feb 3, 2022, 4:05:52 AM2/3/22
to
On Wed, 2 Feb 2022 18:05:59 +0100, Herbert Kleebauer wrote:
> On 02.02.2022 16:02, Chris Roberts wrote:
>> DOS Batch program to countdown days/year (countdown date)
>>
>> Hi,
>> Maybe someone can assist?
>> I am having trouble figuring out how to do this using a DOS/BATCH program.
>>
>> For instance.
>> $ echo %date%%time%
>> Wed 02/02/2022 9:54:30.16
>>
>> Would someone here know how I can subtract todays date from 11/8/22 to easily see how many days I still have to go?
>
> Below are two subroutines which convert a date to the
> numbers of days since 1. Jan. 1901 and reverse. Just call
> the subroutine :date2day for both dates and calculate
> the difference.
>
> @echo off
> setlocal disabledelayedexpansion
>
>:: extract the variables %y% %m% %d% from the %date% variable
>:: (this depends on the local date format)
[snip]

And to detect the current date format, it can be done like below (warning:
long text).

@echo off
setlocal enabledelayedexpansion

for /f "delims=" %%A in ('2^>nul wmic /namespace:\\root\default class stdregprov call getstringvalue hdefkey^="&h80000001" ssubkeyname^="control panel\international" svaluename^=sshortdate ^| find "sValue"') do (
for /f "tokens=3 delims=; " %%B in ("%%A") do set f=%%B
)
set f=%f:~1,-1%
echo date format = %f%

rem i=index (-1=none), l=length
set yi=-1
set yl=0
set mi=-1
set ml=0
set di=-1
set dl=0
for /l %%A in (0,1,9) do (
if "!f:~%%A,1!" == "y" (
if !yi! lss 0 set yi=%%A
set/a yl+=1
) else if "!f:~%%A,1!" == "M" (
if !mi! lss 0 set mi=%%A
set/a ml+=1
) else if "!f:~%%A,1!" == "d" (
if !di! lss 0 set di=%%A
set/a dl+=1
)
)
echo year: index=%yi%, length=%yl%
echo month: index=%mi%, length=%ml%
echo date: index=%di%, length=%dl%

Herbert Kleebauer

unread,
Feb 3, 2022, 5:35:04 AM2/3/22
to
On 03.02.2022 10:05, JJ wrote:

>>:: extract the variables %y% %m% %d% from the %date% variable
>>:: (this depends on the local date format)
> [snip]
>
> And to detect the current date format, it can be done like below (warning:
> long text).

> for /f "delims=" %%A in ('2^>nul wmic

If you use wmic anyhow, you can also use it to directly
get the date:

@echo off
for /f "tokens=*" %%i in ('wmic os get LocalDateTime /value^|find "l"') do set %%i
echo year=%localdatetime:~0,4%
echo month=%localdatetime:~4,2%
echo day=%localdatetime:~6,2%

JJ

unread,
Feb 4, 2022, 4:45:33 AM2/4/22
to
Good thinking.

Chris Roberts

unread,
Feb 4, 2022, 5:11:02 PM2/4/22
to
JJ, thanks for your input.

Herbert Kleebauer,
You are correct. "then do it yourself and show us your code"
I really didn't know how to get the output of "date"
and then... do math with it. (I am way behind you guys on this DOS stuff).
I have worked more with at bash and python, but now at a windows centric job so trying to learn to do it all again with DOS.. :-(

Here is what I have so far:
not worried about formatting.
and
No, It's not correct. There is NOT 30 days/month and NOT 365 days/year.
The examples you guys have provided in this thread has really helped me.
feel free to pick and refine any or all of it.

####
@ECHO off
setlocal EnableDelayedExpansion
set dd=%date:~10,4%-%date:~7,2%-%date:~4,2%
:: separate the present year into fields
for /f "tokens=1,2* delims=- " %%A in ('ECHO %dd%') do (
Set PresY=%%A
Set PresD=%%B
Set PresM=%%C
)
:: separate the ret year into fields
set ret=2029-06-8
for /f "tokens=1,2* delims=- " %%G in ('ECHO %ret%') do (
Set RetY=%%G
Set RetD=%%H
Set RetM=%%I
)
set /a diff_y=%RetY%-%PresY%
set /a diff_m=%RetM%-%PresM%
set /a diff_d=%RetD%-%PresD%
echo Present date is: %dd%
echo Retirement date is: %ret%
echo time to wait is:
ECHO Years %diff_y%
ECHO Months %diff_m%
ECHO Days %diff_d%
::calculat days until retirement.
set /a Days=%diff_y%*365+%diff_m%*30+%diff_d%
echo Days until retirement is %Days%


###(OUTPUT)###
$ retire
Present date is: 2022-04-02
Retirement date is: 2029-06-8
time to wait is:
Years 7
Months 6
Days 2
Days until retirement is 2737
###


Robert Roland

unread,
Feb 5, 2022, 11:13:24 AM2/5/22
to
On Fri, 4 Feb 2022 14:11:00 -0800 (PST), Chris Roberts
<thec...@gmail.com> wrote:

>windows centric job so trying to learn

There is a large difference between MS-DOS and Windows' Command
Prompt. The batch language in Windows is quite a bit more powerful.
Additionally, you can take advantage of built-in features like
VBScript and PowerShell.

For simple things, batch is still quite handy, but for anything
non-trivial (like date arithmetic), there are better options.

Date arithmetic is super simple in PowerShell. And if you need to, you
can also wrap PowerShell scripts in a batch script.

In PowerShell, your problem could be solved like this:

((Get-Date -Day 8 -Month 11 -Year 2022) - (Get-Date)).Days

If you want to wrap it in a batch script, do this (single line):

powershell -command "((Get-Date -Day 8 -Month 11 -Year 2022) -
(Get-Date)).Days"

Note that this formula will give you the time from now until the same
time of day on that other date. If you want to calculate the time
until the clock strikes midnight on that day, you will need to also
specify hours, minutes and seconds.
--
RoRo

Herbert Kleebauer

unread,
Feb 5, 2022, 12:24:16 PM2/5/22
to
On 04.02.2022 23:11, Chris Roberts wrote:

> I have worked more with at bash and python, but now at a windows centric job so trying to learn to do it all again with DOS.. :-(

Why not activate the "Windows Subsystem for Linux" and use bash?

https://docs.microsoft.com/en-us/windows/wsl/



> set ret=2029-06-8
> for /f "tokens=1,2* delims=- " %%G in ('ECHO %ret%') do (
> Set RetY=%%G
> Set RetD=%%H
> Set RetM=%%I
> )
> set /a diff_y=%RetY%-%PresY%
> set /a diff_m=%RetM%-%PresM%
> set /a diff_d=%RetD%-%PresD%
> echo Present date is: %dd%

Just a note: numbers staring with "0" are octal numbers.
So if RetD is "08", it can't be used in a "set /a" command
because 08 isn't a legal octal number.

Chris Roberts

unread,
Feb 7, 2022, 9:31:09 AM2/7/22
to
Thank you Herbert,
I see what you mean on the "numbers staring with "0" are octal" (That is why it wouldn't work with "08" in retirement date. See, I am learned something already... Thanks. )
Lets just hope we don't have any months beyond August. :-)
I have usually have both (via ConEmu) DOS and a "Ubuntu bash prompt" up on my PC.
I just want to know more about DOS batch.
Also, I like that I can easily open apps from DOS. (ie: DOS's "start EditPadLite8.exe %1" just works better than my ubuntu's alias bb='notepad++.exe' as the later won't just accept any path)
So if I wanted to fit retirement.bat or some other garbage into another batch program that also opened my schedule in an excel spreadsheet I could.
I cleaned it up a bit: (Below)

@ECHO off
:: setlocal EnableDelayedExpansion ::Doesn't seem to make any difference, why do people use this anyway?
:: Need to add logic to permit to or ommit leading 0's from the date. due to Octal
set retirement_date=6-8-2027
::set dd=%date:~10,4%-%date:~7,2%-%date:~4,2%
set dd=%date:~4,2%-%date:~7,2%-%date:~10,4%
:: separate the present year into fields
for /f "tokens=1,2* delims=- " %%A in ('ECHO %dd%') do (
Set PresM=%%A
Set PresD=%%B
Set PresY=%%C
)
:: separate the retirement_date.
for /f "tokens=1,2* delims=- " %%G in ('ECHO %retirement_date%') do (
Set RetM=%%G
Set RetD=%%H
Set RetY=%%I
)
set /a diff_y=%RetY%-%PresY%
set /a diff_m=%RetM%-%PresM%
set /a diff_d=%RetD%-%PresD%
::ECHO retirment month %RetM%
::ECHO Pres month %PresM%
::ECHO retirment DAY %RetD%
::ECHO Pres DAY %PresD%
::ECHO %RetD%
ECHO Present date is: %dd%
ECHO Retirement date is: %retirement_date%
ECHO:
ECHO %diff_y% Years
ECHO %diff_m% Months
ECHO %diff_d% Days
::calculate days until your retirement.
set /a Days=%diff_y%*365+%diff_m%*30+%diff_d%
ECHO TIME TO WAIT until retirement is %Days% Days.
###OUTPUT###
$ retire
Present date is: 02-07-2022
Retirement date is: 6-8-2027

5 Years
4 Months
1 Days
TIME TO WAIT until retirement is 1946 Days.
###

Herbert Kleebauer

unread,
Feb 7, 2022, 11:29:09 AM2/7/22
to
On 07.02.2022 15:31, Chris Roberts wrote:

> I see what you mean on the "numbers staring with "0" are octal" (That is why it wouldn't work with "08" in retirement date. See, I am learned something already... Thanks. )

set n=09
set /a m=1%n%-100
echo %n% - %m%


> set /a diff_y=%RetY%-%PresY%
> set /a diff_m=%RetM%-%PresM%

And if %PresM% is greater than %RetM%?

Chris Roberts

unread,
Feb 18, 2022, 2:37:36 PM2/18/22
to

#######
Keywords: DOS batch Code to Count Days until retirement or some future date.

Thank you to everyone who replied.
(Except J. Mudd, I never understood a single word he said in this thread).
I found that "Total_Days=%diff_y%*365+%diff_m%*30+%diff_d% "
Works even if the days/months become negative. Then, I can just use the count of days to calculate months/years.

My completed code below:
@ECHO off
:: setlocal EnableDelayedExpansion ::Doesn't make a difference, why do people use this anyway?
::NOTE: remove the leading zero with this little trick: "set /a dd1=(1%dd: =0%-100)-1"
::::::::::::::::
set retirement_date=06-08-2025
::::::::::::::::
set dd=%date:~4,2%-%date:~7,2%-%date:~10,4%
:: separate the present year into fields
for /f "tokens=1,2* delims=- " %%A in ('ECHO %dd%') do (
:: correct way 1%%A-100, because all 0x numbers are octal, so you have to remove the leading "0"
Set /a PresM=1%%A-100
:: echo %PresM%
Set /a PresD=1%%B-100
Set /a PresY=1%%C-100
)
:: separate the retirement_date.
for /f "tokens=1,2* delims=- " %%G in ('ECHO %retirement_date%') do (
::Set RetM=%%G
Set /a RetM=1%%G-100
:: echo %RetM%
Set /a RetD=1%%H-100
Set /a RetY=1%%I-100
)
set /a diff_y=%RetY%-%PresY%
set /a diff_m=%RetM%-%PresM%
set /a diff_d=%RetD%-%PresD%
set /a Total_Days=%diff_y%*365+%diff_m%*30+%diff_d%
set /a Total_Years=(Total_Days/365)
set /a Remainder_Days=(Total_Days%%365)
set /a Remainder_Months=(Remainder_Days/30)
set /a Remainder_Days2=Remainder_Days%%30

echo ----
ECHO TODAY's Date: %dd%
ECHO RETIREMENT Date: %retirement_date%
ECHO Retirement is just %Total_Days% days away!
echo That is: %Total_Years% Year(s), %Remainder_Months% Months and %Remainder_Days2% Days
echo ----
:::::::
::OUTPUT::
::$ retire
::----
::TODAY's Date: 02-18-2022
::RETIREMENT Date: 06-08-2025
::Retirement is just 1205 days away!
::That is: 3 Year(s), 3 Months and 20 Days
----
:::::::::::::
#######


0 new messages