Batch Files

Parsing the Date and Time

Introduction

This page was written because on July 1, 2023, Google Analytics introduced G4 which I found overkill for what I want. I decided to try and stop using it and took a look at older web log analyzers such as Analog, AWStats, W3Perl, and Webalizer.

The way that some of these work, I need to create batch files that depend on the date, specifically the year and month to do things like make them run with the correct web log and create new folders for the files they produce

Note

Some of the scripts are country and system specific and will need editing depending on your settings.

Getting Date and Time

The commands are country and system specific so will not be the same eveywhere. The environment variable date and time can be used to retrieve the sytem date and time:

These are the lines in the batchfile:

@echo off
set dtg = dtg=%date% %time%
echo %dtg%

which ourputs:

Mon 11/06/2023 15:01:18.38

The string dtg can now be split to extract the various parts using the :~ operator with the start character position and length:

@echo off
set dtg=%date% %time%
echo dtg = %dtg%

set wkday=%dtg:~0,3%
set month=%dtg:~4,2%
set day=%dtg:~7,2%
set year=%dtg:~10,4%
set hour=%dtg:~15,2%
set min=%dtg:~18,2%
set sec=%dtg:~21,2%
set ms=%dtg:~24,2%

echo weekday = %day3%
echo month = %month%
echo day = %day%
echo year = %year%
echo hour = %hour%
echo minute = %min%
echo seconds = %sec%
echo milliseconds = %ms%

which gives:

dtg = Tue 11/07/2023 7:17:13.62
weekday = Tue
month = 11
day = 07
year = 2023
hour = 7
minute = 17
seconds = 13
milliseconds = 62

Manipulating the Date and Time Variables

Now we have the date and time variables we can now manipulate them. In the following code the same variables are used as above to save confusing anyone, especially me!

Month as Text

The month returned by the date environment variable provides the month as a number. This batch file uses that number to provide the full month text name.

As this involves using a loop, setlocal EnableDelayedExpansion needs to be used. This is to stop the batch file from evaluating the loop at the end of it, so it gives the wrong results. It also means that variables inside the loop are now referred to between ! characters - a common gotcha.

Here's the batch file:

@echo off
setlocal EnableDelayedExpansion
set dtg=%date% %time%
set month=%dtg:~4,2%
echo month = %month%

rem The line below was used for testing, set month to number from 01 to 12
rem set month=07
set monthnum=%month%
rem remove leading zero from monthnum
if "%monthnum:~0,1%"=="0" SET monthnum=%monthnum:~1%
set /a count=0
for %%a in (January February March April May June July August September October November December) do (
set /a "count=!count!+1"
if !count!==%monthnum% set fullmonth=%%a
)
echo The month as text is %fullmonth%

The output from this file is:

month = 11
The month as text is November

What the batch file does is:

Get the two digit month - the time here is not really necessary but kept for consistancy
Remove the leading 0, if any, from the month
Loop through a list of all the month names, increasing a counter as it does
If the counter is equal to the new month number then write the month text to a variable

It would be nice if the batch file could just choose the element from the list by just using the month number but batch files do not work like that, neither do they support arrays.

Get the full text of the day of the week

The day of the week returned by the date environment variable provides the day as a three character string. This batch file uses that string to provide the full text of the day of the week.

Here's the batch file:

@echo off
setlocal EnableDelayedExpansion
set dtg=%date% %time%
set wkday=%dtg:~0,3%
echo Weekday = %wkday%

rem The line below was used for testing, set wkday to short text from Mon to Sun
rem set wkday=Thu
for %%a in (Monday Tuesday Wednesday Thursday Friday Saturday Sunday) do (
rem the following intermediate step is necessary!
set x=%%a
set substr=!x:~0,3!
if !substr!==%wkday% set wkdaylong=%%a
)
echo The long weekday is %wkdaylong%

The output from this file is:

Weekday = Tue
The long weekday is Tuesday

What the batch file does is:

Get the three character day of the week - the time here is not really necessary but kept for consistancy
Loop through a list of all the long weekday names
Check that the first three characters of the long names matches the three character weekday, if it does, then write the long weekday text to a variable

As far as I know there is no way for a batch file to get a substring of the loop text directly into a variable, hence the intermediate step that is required.

Convert 24hr Time to 12hr

The day of the week returned by the time environment variable provides the time in 24hr format. This batch file converts it to 12hr format.

Here's the batch file:

@echo off
setlocal EnableDelayedExpansion
set dtg=%date% %time%
set hour=%dtg:~15,2%
set min=%dtg:~18,2%
echo The time is = %hour%:%min%

rem The line below was used for testing
rem set hour=23
if %hour% lss 12 (set timesfx=am) else (set timesfx=pm)
if %hour% gtr 12 (set /A "hour=!hour!-12")
if "%hour:~0,1%"==" " SET hour=%hour:~1%
echo The time is %hour%:%min%%timesfx%

The output from this file is:

The time is = 11:45
The time is 11:45am

What the batch file does is:

Get the time and split it into its component parts - the date here is not necessary but kept for consistency
Set the suffix, am for before midday pm for the afternoon.
If it is the afternoon, then take 12 from the number of hours to convert it to 12 hour time
As far as I know there is no way to easily do multiple commands in an IF statement, so two are used. One way around this is to se a CALL or GOTO with a LABEL

User-friendly Date and Time

This batch file does not use anything that has not already been used, but brings everything together to show what can be done.

Here's the batch file:

@echo off
setlocal EnableDelayedExpansion
set dtg=%date% %time%
echo dtg = %dtg%

set wkday=%dtg:~0,3%
set month=%dtg:~4,2%
set day=%dtg:~7,2%
set year=%dtg:~10,4%
set hour=%dtg:~15,2%
set min=%dtg:~18,2%
set sec=%dtg:~21,2%
set ms=%dtg:~24,2%

rem The line below was used for testing, set month to number from 01 to 12
rem set month=07
set monthnum=%month%
rem remove leading zero from monthnum
if "%monthnum:~0,1%"=="0" set monthnum=%monthnum:~1%
set /a count=0
for %%a in (January February March April May June July August September October November December) do (
set /a "count=!count!+1"
if !count!==%monthnum% set fullmonth=%%a
)

rem The line below was used for testing, set wkday to short text from Mon to Sun
rem set wkday=Thu
for %%a in (Monday Tuesday Wednesday Thursday Friday Saturday Sunday) do (
rem the following intermediate step is necessary!
set x=%%a
set substr=!x:~0,3!
if !substr!==%wkday% set wkdaylong=%%a
)

rem create the date string as it is usually written
rem remove the leading 0 from the day
if "%day:~0,1%"=="0" set day=%day:~1%
set datewrite=%wkdaylong%, %fullmonth% %day%, %year%

rem The line below was used for testing
rem set hour=23
if %hour% lss 12 (set timesfx=am) else (set timesfx=pm)
if %hour% gtr 12 (set /A "hour=!hour!-12")
if "%hour:~0,1%"==" " SET hour=%hour:~1%

echo.
echo It is %hour%:%min%%timesfx% on %datewrite%

The output from this file is:

dtg = Tue 11/07/2023 12:40:54.12

It is 12:40pm on Tuesday, November 7, 2023

Other Methods

Both the Windows Management Instrumentation (WMI) and PowerShell have methods of retieving the date and time from the computer system. In some ways these are better as they provide the date and time in ISO 8601 format which is not machine dependant. An example would be:

wmic os get localdatetime

which returns:

20231107225049.365000-300

Sources and Resources

Batch Script - Arrays (Tutorials Point)
Date (Microsoft Learn)
Date (SS64)
How to print month name in file name by using bat (Stack Overflow)
How-to: Create and use Arrays (pseudo-arrays) in Windows CMD (SS64)
MS-DOS and Windows command line date command (Computer Hope)
MS-DOS and Windows command line time command (Computer Hope)
MS-DOS Date and Time (Microsoft Learn)
Time (Microsoft Learn)
Time (SS64)