Link to home
Start Free TrialLog in
Avatar of TechGuyMike
TechGuyMike

asked on

XP batch script to determine yesterday's date works, except on one particular pc

I have been using a batch file to determine yesterday's date in yyyymmdd format, then copy a file from one location to another. It works everywhere I've used it, until now. At one particular site the batch file fails to completely execute, aborting after the SETLOCAL ENABLEEXTENSIONS line. When troubleshooting I removed the @echo off line and added a bunch of numbered pause/echo statements so I could see where it's failing, then executed the batch from inside a cmd window so it stays on screen, and it actually closes the cmd window. It appears to not like the "FOR /f ..." line since that's the line that seems to make it abort and close the window.

The system is Windows XP. The entire script is attached for your reference. Thanks in advance for your assistance!
@echo off
::  This section gets yesterday's date
::  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SETLOCAL ENABLEEXTENSIONS
 
::  Get current date in YYYYMMDD format   
FOR /f "tokens=1-4 delims=/-. " %%G IN ('date /t') DO (call :FIXDATE %%G %%H %%I %%J)
goto :GETDATE
   
:FIXDATE
  if "%1:~0,1%" GTR "9" shift
  FOR /f "skip=1 tokens=2-4 delims=(-)" %%G IN ('echo.^|date') DO (
      set %%G=%1&set %%H=%2&set %%I=%3)
  goto :EOF
 
:GETDATE
  ::  Convert to Modified Julian date
  if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%)
  set /a dd=100%dd%%%100,mm=100%mm%%%100
  set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,j=153*m+2
  set /a j=j/5+dd+y*365+y/4-y/100+y/400-2432046
  set MJD=%j%
     
  ::  Subtract a day
  set /a MJD=%MJD% - 1
     
  ::  Convert back to YYYYMMDD format
  set /a a=%MJD%+2432045,b=4*a+3,b/=146097,c=-b*146097,c/=4,c+=a
  set /a d=4*c+3,d/=1461,e=-1461*d,e/=4,e+=c,m=5*e+2,m/=153,dd=153*m+2,dd/=5
  set /a dd=-dd+e+1,mm=-m/10,mm*=12,mm+=m+3,yy=b*100+d-4800+m/10
  (if %mm% LSS 10 set mm=0%mm%)&(if %dd% LSS 10 set dd=0%dd%)
  endlocal&set datedsub=%yy%%mm%%dd%&set y=%yy%&set m=%mm%&set d=%dd%
 
:: Copy daily file from C to H drive
IF EXIST C:\Aloha_Export\%datedsub%AL000001000.TXT COPY C:\Aloha_Export\%datedsub%AL000001000.TXT H:\%datedsub%.TXT

Open in new window

Avatar of sirbounty
sirbounty
Flag of United States of America image

Check and compare the regional settings (in control panel) on both machines...
Avatar of TechGuyMike
TechGuyMike

ASKER

Thanks for the idea, but no go. I just checked and they're the same. And specifically to the point, the "date /t" command returns the exact same thing on both. Still looking for the cure...
If this helps, the "date /t" command returns "Tue 10/07/2008", but I tend to agree with the thought behind your first suggestion, that it's a difference in configuration on this system... somewhere.
The problem is on some systems echo %date% displays mm/dd/yyyy and on others it displays DAY mm/dd/yyyy, correct?

Either way, the last 10 characters should comprise mm/dd/yyyy.
Why not try something like:

set myDate=%date:~-10%
echo %myDate%

does that work on both systems?
No, I think you are misunderstanding (or maybe I am... please clarify if you think I am missing something in your solution). "DATE /T" returns "DAY MM/DD/YYYY" on all machines, so using an alternate method to generate the MM/DD/YYYY would be of no use, since I still have to use the FOR loop to parse out MM DD and YYYY.

What I am seeking is either an answer that will lead me to the reason this one machine is acting differently, or an answer that gives me completely different method of determining yesterday in YYYYMMDD format.

This is tougher than it looks - hence the 500 point payout. This script is working perfectly as-is on about 100 XP PCs, all in different locations throughout the southeast US. I've never had to modify it before this machine. What's different? It's got to be some obscure (to me) registry setting or something. Everybody, please keep trying!

More info: This is a desktop PC acting as a restaurant POS fileserver. It is not a domain member. The user logged on is an administrator. This script is normally launched by Windows Scheduled Tasks (but does not work at any time, launched by double-click, from a command line, or when scheduled).
you can get the date by using either date/t or %date%

Try
date/t
and
echo %date%
from a command prompt...

so, ordinarily, you would get the date in yyyymmdd format using date/t
you can also get it using (without a for loop)
echo %date:~-4%%date:~0,2%%date:~3,2%
which would translate to 20081007, except where your date is displaying the day name as well:
TUE 10/08/2008

What I'm suggesting is to just grab the last 10 characters using myDate=%date:~-10%, which should trim off the TUE from the one that has it and simply get the date on the one that doesn't...
If you'd rather stick to the for loop, check out this thread for how to parse it properly...http://www.robvanderwoude.com/datetiment.html
OK, I like "%date:~-4%%date:~0,2%%date:~3,2%" to retrieve today in YYYYMMDD format, but I had to modify it to "%date:~-4%%date:~4,2%%date:~7,2%" to get 20081007 (see attached snippet - this gives me 20081007). Your original code produces "2008Tu 1" here.

Now how do I subtract a day? And will my mod work no matter what day it is (are all days returned as 3 letter abbreviations)?
set datedsub=%date:~-4%%date:~4,2%%date:~7,2%
echo %datedsub%

Open in new window

remove "@echo off" from you batch file and run it from command prompt redirecting the output to a text file

batchfile > out.txt

then we can examine the output to find out why the batch file is failing

also check this out - a little enhanced date parser
http://groups.google.com/group/alt.msdos.batch.nt/msg/5805787c26992fd3
It's aborting exactly where I had determined. This is the entire output:
D:\>SETLOCAL ENABLEEXTENSIONS
D:\>FOR /F "tokens=1-4 delims=/-. " %G IN ('date /t') DO (call :FIXDATE %G %H %I %J )
Sorry, change this section:

::  Get current date in YYYYMMDD format  
FOR /f "tokens=1-4 delims=/-. " %%G IN ('date /t') DO (call :FIXDATE %%G %%H %%I %%J)
goto :GETDATE
   

::  Get current date in YYYYMMDD format   
FOR /f "tokens=1-3 delims=/-" %%G IN ("%date:~-10%") DO (call :FIXDATE %%G %%H %%I)
goto :GETDATE
   

Open in new window

Sorry, have to leave the office for a couple hours - system down across town needs a site visit. SirBounty, your latest is now making it to line 12 in the script above. I will check for messages and play with it more when I get back to see if I can get further. Thanks...
Here's where it aborts now (this is output):
D:\>SETLOCAL ENABLEEXTENSIONS
D:\>FOR /F "tokens=1-3 delims=/-" %G IN ("10/08/2008") DO (call :FIXDATE %G %H %I )
D:\>(call :FIXDATE 10 08 2008 )
D:\>if "10:~0,1" GTR "9" shift
D:\>FOR /F "tokens=1-3" %G IN ('echo.|date') DO (set %G=10  & set %H=08  & set %I=2008 )

Getting closer... Got an idea how to move further?
ASKER CERTIFIED SOLUTION
Avatar of sirbounty
sirbounty
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks so much for your work! You were very easy to work with, and patient too! I really appreciate your effort!
Very glad I could help - thanx for the grade! :^)