Is there a way to get the first and the last day of the previous week into two variables on the windows command line?
The date format I'd like to use is YYYY-MM-DD.
If you can use vbscript, you can try the following:
Create the file vbdate.vbs:
function YMD(d)
YMD = Year(d) & _
"-" & Right("00" & Month(d),2) & _
"-" & Right("00" & Day(d),2)
end function
set oArgs=WScript.Arguments
' Assuming first day of the week is Monday:
WScript.echo YMD(DateAdd("d", -((Weekday(Now()) + 7 - 2) Mod 7) + oArgs(0), Now()))
If you want Sunday to be first day of the week, replace the last line by:
WScript.echo YMD(DateAdd("d", -((Weekday(Now()) + 7 - 1) Mod 7) + oArgs(0), Now()))
This vbscript takes one argument, beware its sole purpose is to perform the date calculation you asked for:
6 will give you the last day of the current week
0 will give you the first day of the current week
-1 will give you the last day of the previous week
-7 will give you the first day of the previous week
To put requested values into two variables you can do the following:
#echo off
FOR /F "usebackq tokens=*" %%r in (`CSCRIPT //Nologo "vbdate.vbs" -7`) DO SET RESULT1=%%r
FOR /F "usebackq tokens=*" %%s in (`CSCRIPT //Nologo "vbdate.vbs" -1`) DO SET RESULT2=%%s
REM First day of previous week
ECHO %RESULT1%
REM Last day of previous week
ECHO %RESULT2%
I'm not sure how you define your week, but I will assume the week starts with Sunday.
Doing date/time computations in batch is a pain. But the problem can be solved easily if you use my getTimestamp.bat utility - a hybrid JScript/batch script that can be used to perform nearly any date/time computation and formatting task. The utility is pure script that runs natively on any Windows machine from XP onward.
#echo off
setlocal
call getTimestamp /f "{w}" /r dayOfWeekNum
call getTimestamp /od "-%dayOfWeekNum%-7" /f "{yyyy}-{mm}-{dd}" /r beginDate
call getTimestamp /od "-%dayOfWeekNum%-1" /f "{yyyy}-{mm}-{dd}" /r endDate
echo Last week begin date = %beginDate%
echo Last week end date = %endDate%
EDIT
The above can easily be generalized to support any day as the start of the week. Also, the script could give the wrong result if it is run a split second before midnight on the night it transitions from one week to the next. I solved that below by getting the current date only once, and then performing all computations relative to that date.
The script below assigns Monday as the start of the week.
#echo off
setlocal
set "weekStart=1" %= 0=Sunday, 1=Monday, 6=Saturday =%
call getTimestamp /f "{ums}" /r today
call getTimestamp /d %today% /f "{w}" /r dayOfWeekNum
set /a "dayOfWeekNum=(7+dayOfWeekNum-weekStart)%%7"
call getTimestamp /d %today% /od "-%dayOfWeekNum%-7" /f "{wkd} {yyyy}-{mm}-{dd}" /r beginDate
call getTimestamp /d %today% /od "-%dayOfWeekNum%-1" /f "{wkd} {yyyy}-{mm}-{dd}" /r endDate
echo Last week begin date = %beginDate%
echo Last week end date = %endDate%
Related
I need to program a batch that renames an Excel file with the date of the last day of the previous month in DDMMYYY format.
I have an example of code renaming using the current date.
ren example.xls example_%DATE:/=%.xls
Is there a method to do the same with the last day of the previous month?
Thank you in advance.
I don't see any reason to use a for loop if you're happy with using PowerShell. You could just do it in one line:
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile "Rename-Item -Path \".\example.xls\" -NewName \"$(((Get-Date -Day 1).AddDays(-1)).ToString('ddMMyyyy')).xls\""
This is really simple when you use the right formula:
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
set /A "M=1%%b-100,a=^!(M-1),Y=%%c-a,M+=12*a-1,D=30+((M+(M-8>>31)+1)&1)-^!(M-2)*(2-^!(Y%%4)),M+=100"
)
ren example.xls example_%D%%M:~1%%Y%.xls
If you are not using Delayed Expansion, remove the ^ caret from the three ! operators.
Tip: get the time this pure Batch solution takes and compare it vs. the PowerShell one...
You can also get some help from powershell:
#echo off
for /F "delims=" %%i IN ('powershell.exe -Command "(Get-Date -Day 1 -Hour 0 -Minute 0 -Second 0).AddSeconds(-1).ToString('yyyy-MM-dd')"') DO (
ren "example.xls" "%%i.xls"
)
The date format can be changed as per your needs at the end of the powershell string which is currently ("yyyy-MM-dd")
Obviously you have to calculate that date.
Start with the current date (20.12.2021)
change the current day to 1 (1.12.2021)
convert this date to a julian day (2459550)
subtract 1 day (2459549)
convert it back to a gregorian date (30.11.2021)
Third, and hopefully final revamp of question...
Batch file reading text file with for loop line by line into variable. Each line of said text file can be formatted completely different from the next. The only common delimiter would be a four-digit number (year) somewhere in each line. The goal is to return whatever text follows the aforementioned four-digit number for each line via echo.
Text file example:
Monday, January 1, 1900 there was an event-e6718
On this day in 1904 nothing occurred
Wednesday, March 3, 1908 an error occurred when attempting to access the log
Thursday, , 1911 - access denied
Friday, in whatever month, on whatever day, in 1938, nothing happened
Therefore, based on the above text file example, the return would be like...
there was an event-e6718
nothing occurred
an error occurred when attempting to access the log
- access denied
nothing happened
As of 1318 PST, I've tried every code snippet in the comments following, but none of them were able to return the data I need to return.
However, those comments were related to my initial question which has since been markedly improved.
I've even tried a regular expression of "^[1-9][0-9][0-9][0-9]$", however I'm new to regex, so I'm sure I have that wrong.
Is this even possible?
Thanks in advance.
Batch is a horrible task for this. REGEX is a good tool, but cmd doesn't support it (with the exception of a very crippled subset with findstr). If you are willing to use an external tool, it gets easy:
<old.txt call jrepl ".*(\d{4})\D\ *(.*$)" "$2" >new.txt
search for a four digit number \d{4}, followed by a non-digit \D and zero or more spaces, and take the rest until "EndOfLine" .*$. (Parentheses) mark matches, referenced by $x. Your desired strings are in $2.
Output with your example file:
there was an event-e6718
nothing occurred
an error occurred when attempting to access the log
- access denied
there was an event-dsfd318
nothing happened
Should you decide to include the year, you can find it in $1:
<old.txt call jrepl ".*(\d{4})\D\ *(.*$)" "$1: $2" >new.txt
gives:
1900: there was an event-e6718
1904: nothing occurred
1908: an error occurred when attempting to access the log
1911: - access denied
1910: there was an event-dsfd318
1938: nothing happened
The call is neccessary wihtin a batch file, because jrepl is a batch file and therefore wouldn't return without call.
(The REGEX pattern might be subject for improvement; I don't have much experience with it yet.)
jrepl.bat was programmed by dbenham.
Give this a go:
#echo off & setlocal enabledelayedexpansion
for /f "delims=" %%i in ('type "C:\textfile.txt" ^| findstr /IRC:"there was an event"') do (
set "event=%%i"
echo "!event:*there was an event=there was an event!"
)
textfile.txt
Monday, January 1, 1900 there was an event-e6718
On this day in 1904 nothing occurred
Wednesday, March 3, 1908 an error occurred when attempting to access the log
Thursday, , 1911 - access denied
Monday, January 1, 1910 there was an event-dsfd318
Friday, in whatever month, on whatever day, in 1938, nothing happened
Result:
If there truly is no common point in the string or consistency in token count, adjust the number of iterations in the below for loop to match the maximum possible tokens.
#Echo off & Setlocal EnableDelayedexpansion
Set "event=Monday, January 1, 1900 there was an event-e6718"
For /L %%i in (1 1 10) Do (
Set "event=!event:*, =!"
)& rem // arbitrary number of iterations that should be adjusted to match the maximum expected tokens
Set "event=%event:~5,100%"& rem // remove the year[space] from the string - final string maximum length is also arbitrary and may need adjusting.
Echo/%event%
** Update **
An example of a macro to get the last token within a for loop using a macro version of the above approach:
Note: you'll need to adjust the file path for yout input file.
#Echo off
(Set \n=^^^
%=Newline Var=%
)
Set Gettoken=For %%n in (1 2) Do if %%n==2 (%\n%
For /F "Delims=" %%G in ("!string!") Do (%\n%
Set "output=%%G"%\n%
For %%D in ("!Delim!") Do For /L %%i in (1 1 10) Do Set "output=!output:*%%~D=!"%\n%
Set "output=!output:~5,100!"%\n%
)%\n%
Set output%\n%
) Else Set string=
Setlocal EnableDelayedExpansion
Set "Delim=, "&& For /F "Delims=" %%I in (inputfile.txt) Do %GetToken%%%I
Edit:
single batch solution for the amended questions actual requirement.
#Echo off & CD "%~dp0"
Setlocal Enabledelayedexpansion
rem // replace inputfile.txt with your filepath
For /F "Delims=" %%L in (inputfile.txt) Do (
Call :sub "%%L"
rem // the below for loop will remove everything up to including the first year from the string
rem // as well as traling coma[space] / [space]
For %%E in (!Errorlevel!) Do (
If Not "%%E"=="0" (
Set "String=!String:*%%E=####!"
Set "String=!String:####, =!"
Set "String=!String:#### =!"
Set "String=!String:####=!"
)
)
rem // output only if a year "delimiter" was encountered
If not "%%~L"=="!String!" Echo/!String!
)
Exit /b
:sub
Set "String=%~1"
rem // adjust for loop %%I for valid year range and %%# for maximum expected string length
For /L %%I in (1899 1 2050) Do (For /L %%# in (0 1 100) Do (If "!String:~%%#,4!"=="%%I" (Exit /B %%I)))
Exit /B 0
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.
Hi couldnt find anything here to help out with this one.
My company has a set of client folders that require a set of subfolders to be created at the end of each financial year. This is required to be a 2 digit representation of the year (ie - 14 Folder1 [for 2014] and so on).
I have a batch file that creates the folders every year, but have to modify the year every time. I am looking to schedule an auto mated solution, but i am stuck trying to add 1 additional year to the date. (as the folders need to be created at the end of the financial year, not calender year).
I am looking for a way to add 1 year to the current date. Here is my batch file so far. Any ideas anyone?
set YEAR= %DATE:~-2% + %DATE:~-2%
for /f "delims=|" %%s in ('dir /ad/b') do md "%%s\%YEAR% Folder1"
for /f "delims=|" %%s in ('dir /ad/b') do md "%%s\%YEAR% Folder2"
for /f "delims=|" %%s in ('dir /ad/b') do md "%%s\%YEAR% Folder3"
Like this :
set /a YEAR=%DATE:~-2% + 1
set /a YEAR=1%DATE:~-2%+1
set YEAR= %DATE:~-2%%YEAR:~-2%
This is assuming that you want 1415 for the 2014-2015 financial year.
Are you aware that your construct will yield a Space before the string? Spaces are significant in string-assignments - on both sides of the =.
It's safer to use
set "YEAR=%DATE:~-2%%YEAR:~-2%"
for instance - the rabbit's ears in this format ensure that trailing spaces are omitted (that can cause chaos)
This question already has answers here:
How can I create a date stamp for yesterday
(2 answers)
Closed 8 years ago.
I am a novice at writing scripts but I know this can be done I just don't know how...
I have a file that need to have the file NAME changed to the current date less 1 workday (ex: Mondays date back Friday, Tuesdays to Monday with a prepend of the date a static "AD"
Filename example: AD140107.pos
(Tuesdays date changed to a Wednesday date, AD140108.pos)
The file is located at: R:\PortfolioCenter\Output\Manual Interface Files
I have a similar file in a different folder that has a different date format that needs the date changed as well
Filename example: PC010714.slb
(Tuesdays date changed to a Wednesday date, PC010814.pos)
This file is located at: R:\slwin\Recon adjustments
I would like both file names to change using the same script
I know DOS doesn't do weekdays well so I can use a separate file to process Monday files if neccesary
#ECHO OFF
SETLOCAL
SET "destdir=c:\destdir"
SET "targetdir=c:\destdir"
SET today=%date:~-2%%date:~3,2%%date:~0,2%
FOR /f "delims=" %%a IN (yesterday.txt) DO SET yesterday=%%a
IF %yesterday%==%today% GOTO :EOF
>yesterday.txt ECHO %today%
ECHO REN "%destdir%\AD%today%.pos" "AD%yesterday%.pos"
SET today=%today:~-4%%today:~0,2%
SET yesterday=%yesterday:~-4%%yesterday:~0,2%
ECHO REN "%targetdir%\PC%today%.slb" "PC%yesterday%.slb"
GOTO :EOF
I use a date format of dd/mm/yyyy. Yours may be different, so you'd need to reformat the date differently. The basic method is to string together the three elements using substrings of the form %date:startpos,length% where position 0 is the start of the (date) string.
I've nominaed the two directories as destdir and targetdir to suit my system.
There's some confusion in the question about what name gets changed to what. It would seem more sensible to change from the current date to the previous day's date, but that's not what the narrative describes.
I'm assuming that you are only going to run this once per day.
It's all based around keeping the massaged last-run date in yesterday.txt, which would need to be established first containing a single line140107` or whatever. If you have this run automagically at midnight+alittle, Mon-Fri only, it should rename the files appropriately.
The required commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files.
The Batch subroutine below get the midweek date of current date minus one day and show it in the format given by its parameter: if it is Y, output format is YYMMDD, otherwise it is MMDDYY. This routine solve the main part of your request.
#echo off
setlocal
rem If Format=Y, output is YYMMDD
rem If Format=M, output is MMDDYY
:OneMidweekDayLessCurrentDate format
rem Modify next line accordingly to your locale format (this one use DD/MM/YYYY)
for /F "tokens=1-3 delims=/" %%a in ("%date%") do set /A dd=1%%a-100, mm=1%%b-100, yyyy=%%c
rem Convert the Date minus one day to Julian Day Number, and get its Day Of Week (0=Sunday, ..., 6=Saturday)
set /A a=(mm-14)/12, jdn=(1461*(yyyy+4800+a))/4+(367*(mm-2-12*a))/12-(3*((yyyy+4900+a)/100))/4+dd-32076, dow=jdn%%7
rem If the dow is Sunday or Saturday, change it by the previous Monday
if %dow% equ 0 (
set /A jdn-=2
) else if %dow% equ 6 (
set /A jdn-=1
)
rem Convert the Julian Day Number back to date
set /A l=jdn+68569,n=(4*l)/146097,l=l-(146097*n+3)/4,i=(4000*(l+1))/1461001,l=l-(1461*i)/4+31,j=(80*l)/2447
set /A dd=l-(2447*j)/80,l=j/11,mm=j+2-(12*l),yyyy=100*(n-49)+i+l
if %dd% lss 10 set dd=0%dd%
if %mm% lss 10 set mm=0%mm%
rem Show the resulting date
if "%1" equ "Y" (
echo %yyyy:~-2%%mm%%dd%
) else (
echo %mm%%dd%%yyyy:~-2%
)
exit /B
On the other hand you have NOT specified which file is the one to be renamed: "I have a file that need to have the file NAME changed... Filename example: AD140107.pos". If you specify this point, we can complete the solution.