I currently have the following code in a batch file Backup.bat on my desktop. it is used to back up an excel spreadsheet file each day and rename it by appending the current date and time. File.xlsx is copied and pasted to a new folder as File Sun-06-24-2012 23.21.46PM.xlsx
Currently the date and time is appended as Sun-06-24-2012 23.21.46PM.xlsx but i would like to have it append as Sun-06-24-2012 11.21.46PM.xlsx using the 12 hour clock rather than 24 hour clock format.
Below is the code i am currently using in Windows XP Professional. Would anyone know how to have the time appended in 12 hour clock format rather than 24 hour clock format as it is currently in the code below.
#For /F "tokens=1,2,3,4 delims=/ " %%A in ('Date /t') do #(
Set DayW=%%A
Set Day=%%B
Set Month=%%C
Set Year=%%D
Set All=%%A-%%B-%%C-%%D
)
#For /F "tokens=1,2,3 delims=:,. " %%A in ('echo %time%') do #(
Set Hour=%%A
Set Min=%%B
Set Sec=%%C
Set Allm=%%A.%%B.%%C
)
#For /F "tokens=3 delims=: " %%A in ('time /t ') do #(
Set AMPM=%%A
)
copy "C:\Temp\File.xlsx" "C:\Temp\DailyBackup\File %All% %Allm%%AMPM%.xlsx"
I agree with Joey's comment, I think you are better off with 24 hour format.
Also, your method for getting the date and time will break as soon as the code is transferred to another machine that uses a different date and/or time configuration.
But, here goes anyway...
You should get the entire time string from a single %TIME% expansion. Otherwise you run the risk of getting the hour:min:sec before midnight and the AMPM after midnight.
Put #ECHO OFF at the top, then you don't need to sprinkle # throughout your code.
#echo off
For /F "tokens=1,2,3,4 delims=/ " %%A in ('Date /t') do (
Set DayW=%%A
Set Day=%%B
Set Month=%%C
Set Year=%%D
Set All=%%A-%%B-%%C-%%D
)
For /F "tokens=1,2,3 delims=:,. " %%A in ('echo %time%') do (
set /a "Hour=100%%A%%100"
set Min=%%B
set Sec=%%C
)
if %Hour% geq 12 (
set AMPM=PM
set /a "Hour-=12"
) else set "AMPM=AM"
if %Hour% equ 0 set "Hour=12"
if %Hour% lss 10 set "Hour=0%Hour%"
set "Allm=%Hour%.%Min%.%Sec%%AMPM%"
echo on
copy "C:\Temp\File.xlsx" "C:\Temp\DailyBackup\File %All% %Allm%.xlsx"
Time /t is giving you the time in 24-hour format, presumably because that's the default for your computer's locale.
As time /t doesn't appear to offer any formatting options, probably the easiest thing to do is add an extra section to your batch file to convert the 24-hour clock to 12-hour.
Somewhere under Set Hour=%%A you just need to:
Subtract 12 from the hour if it's more than 12
Change '00' into '12'
For example:
If %Hour% gtr 12 (
Set /a Hour=%Hour%-12
)
If %Hour% == 00 (
Set Hour=12
)
The /a switch on Set tells it that the value to the right of the equals sign is a numerical expression to be evaluated.
This will leave you with no leading zero on the hour if it comes out from 1 to 9. You could get around this with another if statement to add a leading zero back in, or there might be a more elegant approach!
Related
I current run the below script to get the current day minus 1 and the current month. It works great for all days and month except for the 8th of every month and August of every year. I have to change the script to setting it manually for August. Does anyone know why and is there a fix.
SET m=%date:~4,2%
SET /A m -= 1
SET m=0%m%
REM ****** SET m=08 this was used because the date was not right ******
REM SET m=08
SET currMon=%date:~4,2%/%date:~10,4%
REM ****** SET PriorMon=12/2017 this was used for Year End because the date was not right ******
REM SET PriorMon=08/2018
SET PriorMon=%m:~-2%/%date:~10,4%
This is a hybrid vb/batch script. It is a proper way to get the date -1 or whatever amount of days you want:
#echo off
set day=-1
echo >"%temp%\%~n0.vbs" s=DateAdd("d",%day%,now) : d=weekday(s)
echo>>"%temp%\%~n0.vbs" WScript.Echo year(s)^& right(100+month(s),2)^& right(100+day(s),2)
for /f %%a in ('cscript /nologo "%temp%\%~n0.vbs"') do set "result=%%a"
del "%temp%\*%~n0.vbs"
set "yyyy=%result:~0,4%"
set "mm=%result:~4,2%"
set "dd=%result:~6,2%"
set "final=%dd%-%mm%-%yyyy%"
echo %final%
I simply echo the final result here which as far as today's date goes (for me as it is the 7th) should echo 06-09-2018
You can change the format of %final% as you please to suit your date..
Proper date calculatons in pure batch are possible but tedious.
Your approach relies on possibly unknown locale/user settings dependant date format.
From Win7 on Powershell is available as a tool:
On cmd line:
For /f "usebackq" %A in (`powershell -Nop -C "(Get-Date).AddDays(-1).ToString('MM\/yyyy')"`) Do Set Yesterday=%A
In a batch file:
For /f "usebackq" %%A in (`
powershell -Nop -C "(Get-Date).AddDays(-1).ToString('MM\/yyyy')"
`) Do Set Yesterday=%%A
Echo Yesterday=%Yesterday%
Modify the format string to your liking:
dd = day 2 places
MM = month 2 places
yyyy = year 4 places
Other characters have to be escaped with a backslash.
I'm new to batch scripting, so please be lenient with this question. When I'm subtracting 1 from 'TodayDay' variable, the value is not getting updated. Below is the line.
set /a "TodayDay=%TodayDay%-1"
My use case is to find if today's date is less than the 'lastOpenedDate' variable, I want to set the 'lastOpenedDate' to yesterday's
set lastOpenedDate=2017-12-22
IF %TodayYear%-%TodayMonth%-%TodayDay% LSS %lastOpenedDate% (
echo Before Subtraction TodayDay is %TodayDay%
set /a "TodayDay=%TodayDay%-1"
echo After Subtraction TodayDay is %TodayDay%
)
When I ran the above code, The output is:
Before Subtraction TodayDay is 20
After Subtraction TodayDay is 20
I got the other variable values from the below-mentioned code
for /F "skip=1 delims=" %%F in ('
wmic PATH Win32_LocalTime GET Day^,Month^,Year /FORMAT:TABLE
') do (
for /F "tokens=1-3" %%L in ("%%F") do (
set TodayDay=0%%L
set TodayMonth=0%%M
set TodayYear=%%N
)
)
set TodayDay=%TodayDay:~-2%
set TodayMonth=%TodayMonth:~-2%
What am I doing wrong?
You need to search SO using the top bar for delayed expansion. It's #1 FAQ.
change
set /a "TodayDay=%TodayDay%-1"
echo After Subtraction TodayDay is %TodayDay%
)
to
set /a "TodayDay=%TodayDay%-1"
)
echo After Subtraction TodayDay is %TodayDay%
which will make sense once you familiarise yourself with delayed expansion.
Now the next problem you'll run into (which won't show itself until the 8th or 9th of the month) is that in batch a leading 0 means "octal" so - you actually need
set /a "TodayDay=1%TodayDay%-1"
)
set "TodayDay=%TodayDay:~-2"
echo After Subtraction TodayDay is %TodayDay%
which adds 100 to the day number by stringing the 1 in front of the day number, then you need to get the last 2 characters.
I want to create a folder that uses TIME formatted in a specific way. I want the format to be in hh.mm.ss since you can't use a : in a folder name.
When I use set CurTime=%time:~0,2%.%time:~3,2%.%time:~6,2%, I get an output with a leading space before 10:00 AM and five trailing spaces as well (not sure why). I can remove the spaces by adding the line set CurTime=%CurTime: =%, but I want to add a leading zero if the time is earlier than 10:00 AM.
How can I do this?
Edit for clarification:
I have the time formatted the way I want it, but I want to replace the leading space with a 0 if the hh portion is less than 10. This is not a duplicate question of How to get current datetime on Windows command line, in a suitable format for using in a filename?.
If you have read this ==> Windows batch file redirect output to logfile with date/time
You can be able to do like this one :
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set datestamp=%dt:~0,8%
set timestamp=%dt:~8,6%
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%
echo stamp: "%stamp%"
pause
echo datestamp: "%datestamp%"
pause
echo timestamp: "%timestamp%"
pause
set MyVar=%HH%.%Min%.%Sec%
echo My desired Variable in this format hh.mm.ss to use is : %MyVar%
pause
mkdir "c:\%MyVar%"
pause
set "mytime=%time:~0,-8%"
set "mytime=%mytime: =0%"
set "mytime=%mytime::=.%"
echo "%mytime%"
should show the result you want. The first line removes the last 8 characters from time (which should be the 5 spaces + .dd) and the other two make the substitution of unwanted characters.
The reason for the 5 trailing spaces may be that some time formats allow " a.m." and the easy way is to simply replace the unwanted parts with spaces.
There are many ways to achieve your goal.
Here's a crazy untested one:
#ECHO OFF
SET "CurTime="
FOR /F "TOKENS=2-4 DELIMS=: " %%A IN ('ROBOCOPY/NJH /L "\|" NULL'
) DO IF NOT DEFINED CurTime SET "CurTime=%%A.%%B.%%C"
ECHO(%CurTime%
TIMEOUT -1
Hello I have batch code which zips my folder and removes the original copy. I run this as a task scheduler every month. There is one thing I been having problems with. My code is base on this on this variable on the top of my batch code call "set FILETOZIP" ... Is there a way where I can use another variable to look up the current month and year on my machine ? [ Rest of my batch code ] works find and I do not need any help with it.
Current :
set FILETOZIP=D:\Farm\201411
[Rest of code ]
Expected Code :
set FIND_YEAR_MONTH=" some date formula "
set FILETOZIP=D:\Farm\"A way to set FIND_YEAR_MONTH here "
[Rest of code ]
set FILETOZIP=D:\Farm\20%date:~10,2%%date:~4,2%
Is your basic structure - you don't tell us your date format which can be set on a user-by-user basis.
Assuming your format is Fri 11-21-14 then this picks the 10th character (start counting at character 0) for 2, then the 4th for 2. If your date-format differs, then adjust to suit.
Another way is
for /f "tokens=1-4 delims=/-. " %%a in ("%date%") do set /a filetozip=20%%d*100+1%%b-100
set "filetozip=D:\Farm\%filetozip%"
Again, the formula here depends on your date-format. Using your date elements and the delims set shown, then a date like Fri 11-21-14 would assign Fri to %%a, 11 to %%b, 21 to %%c and 14 to %%d. The mathematical gymnastics prefix the month and make it 100+the actual month number, so 100 needs to be subtracted. This is because batch treats numbers starting 0 as octal, so 08 and 09 are not valid. These become 108 and 109 - conveniently decimal.
Time settings independent:
#Echo Off
Call :GetDate.Init
Rem :GetDate.Init should be called one time in the code before call to :Getdate
Call :GetDate
set YEAR_MONTH=FINANCE%year%%month%
set file_to_zip=D:\Farm\%YEAR_MONTH%
[Rest of code ]
Goto :EOF
:GetDate.Init
Set /A "jan=1,feb=2,mar=3,apr=4,may=5,jun=6,jul=7,aug=8,sep=9,oct=10,nov=11,dec=12"
Set /A "mon=1,tue=2,wed=3,thu=4,fri=5,sat=6,sun=7"
(
Echo .Set InfHeader=""
Echo .Set InfSectionOrder=""
Echo .Set InfFooter="%%2"
Echo .Set InfFooter1=""
Echo .Set InfFooter2=""
Echo .Set InfFooter3=""
Echo .Set InfFooter4=""
Echo .Set Cabinet="OFF"
Echo .Set Compress="OFF"
Echo .Set DoNotCopyFiles="ON"
Echo .Set RptFileName="NUL"
) >"%Temp%\~foo.ddf"
Goto :Eof
:GetDate
Set "tf=%Temp%\~%random%"
Makecab /D InfFileName="%tf%" /F "%Temp%\~foo.ddf" >NUL
For /F "usebackq tokens=1-7 delims=: " %%a In ("%tf%") Do (
Set /A "year=%%g,month=%%b,day=1%%c-100,weekday=%%a"
Set /A "hour=1%%d-100,minute=1%%e-100,second=1%%f-100")
Del "%tf%" >NUL 2>&1
Goto :Eof
A solution independent of locale settings:
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
It will give you:
20141121175755.279000+060
( YYYYMMDDhhmmss.<fraction>+/-<timedifference to UTC> )
from here, it is easy:
set datetime=%datetime:~0,6%
gives you 201411
and finally to get you pathname:
set "FILETOZIP=D:\Farm\%datetime%"
I have made a character file in which my game pulls data and variables from. Looks like so:
playerName= Marche
playerRace= Elf
playerHP= 100
playerSPD= 200
playerATK= 120
playerDEF= 70
Final Fantasy reference anyone...? Anyway, when the character levels up, I need a batch script to find the string "playerHP= 100". playerHP is set as a variable within the script. Basically, it takes the current health, and multiplies it by 120%, increasing the number. How do I echo the result of that math to replace the current number?
For example if that didn't make any sense, I have 100 health. I level up, thus increasing my health stat by 120%, so now I have 120 health. I would want to find the string "playerHP= 100" and replace it with "playerHP= 120".
If it can be avoided I don't want to download any other commands (I've seen sed a few times). Thanks much
EDIT: Instead of searching for the string and replacing I took jeb's advice and just deleted the file and re-echoed all of the data. It ended up looking like this:
set /a LeveledUpPlayerHP=(%ppHP%* 12) / (10)
set /a LeveledUpPlayerSPD=(%ppSPD%* 12) / (10)
set /a LeveledUpPlayerATK=(%ppATK%* 12) / (10)
set /a LeveledUpPlayerDEF=(%ppDEF%* 12) / (10)
echo Updating stats...
del "C:\Users\%USERNAME%\Desktop\CMDRPG\player\playerData.dll
ping 1.1.1.1 -n 1 -w 500 > nul
echo playerName= %playerName%>playerData.dll
echo playerRace= %playerRace%>>playerData.dll
echo playerHP= %LeveledUpPlayerHP%>>playerData.dll
echo playerSPD= %LeveledUpPlayerSPD%>>playerData.dll
echo playerATK= %LeveledUpPlayerATK%>>playerData.dll
echo playerDEF= %LeveledUpPlayerDEF%>>playerData.dll
The playerName and playerRace are all loaded in prior to this section of the code. Ping is used just as a wait function to let the file delete before echoing new data. Seems to work okay. Thanks all
try this (output is in %inifile%.new):
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
SET "inifile=file"
FOR /f %%a IN ('^<"%inifile%" find /c /v ""') DO SET /a lines=%%a
< "%inifile%" (
FOR /l %%a IN (1,1,%lines%) DO (
SET "line="
SET /p "line="
IF NOT "!line:playerHP=!"=="!line!" (
FOR /f "tokens=2delims= " %%b IN ("!line!") DO SET /a HP=%%b*12/10
SET "line=playerHP= !HP!"
)
ECHO(!line!
))>"%inifile%.new"
Input/output:
>type file
playerName= Marche
playerRace= Elf
playerHP= 100
playerSPD= 200
playerATK= 120
playerDEF= 70
>test.bat
>type file.new
playerName= Marche
playerRace= Elf
playerHP= 120
playerSPD= 200
playerATK= 120
playerDEF= 70
Presumeably it does not matter what order the values appear in you file. If that is so, then the following will effectively "edit" your file.
It first uses FINDSTR to isolate the current playerHP value, and FOR /F to parse out the value from the string. SET /A increments the playerHP. Then a new file is created using FINDSTR to write all the current values except for playerHP, and then the new playerHP info is appended to the end.
#echo off
set "file=gameData.txt"
for /f "tokens=2 delims==" %%N in ('findstr /bl "playerHP=" "%file%"') do set /a "newHP=%%N*120/100"
>"%file%.mod" (
findstr /blv "playerHP=" "%file%"
echo playerHP=%newHP%
)
move /y "%file%.mod" "%file%" >nul
But why go to all that trouble. I should think you already have all your values in memory as environment variables. Simply make sure that all variables that are to be stored in a file start with a common unique prefix. In your example, they all start with "player", but you probably want something a little more generic - perhaps a symbol like #. So you could have #playerName, #playerRace, etc.
Simply update the values in memory as needed. When it comes time to save the current game state to a file, then all you need to do is
>"gameData.txt" set #
A brand new file will be created each time containing all the current values.
To load the values, you do exactly what jeb suggested:
for /f "usebackq delims=" %%A in ("gameData.txt") do set %%A
To save your data in a file, you could use a block like
(
echo playerName=%playerName%
echo playerRace=%playerRace%
echo playerHP=%playerHP%
) > player.ini
And to load it you could use
for /F "delims=" %%L in (player.ini) do set "%%L"