

InterviewSolution
1. |
Solve : Batch File For Complex Date Calculations? |
Answer» Hi, function getDateOfLastWeekday(weekday){ Thanks for you help. I know very basic batch commands but nothing of this level. ExistanceOh yeah sorry this is the usage info on that Jscript i pasted the code for above in my first post: Quote // It takes an integer between 0 and 6 as an argument (above 6 is accepted but might give incorrect results). Existanceyou can just run the javascript using cscript/wscript..no need to convert to batch...Thanks for your suggestion ghostdog74...i'm glad that someone replied. I currently run the jscript by itself but i would much prefer to make into a standalone batch file. The main reason is that jscript seems to run straight through its commands without waiting for any process or command to finish first, unlike a batch file where you can make it wait properly and then proceed or retry depending upon the outcome. Does anyone know how to call the date in "any" of the ways i need to call it? Even a nudge in the right direction is better than nothing... Thanks in advance, ExistanceI don't even think that the ancient LANGUAGE of BATCH is designed to do domething that complex. I'm thinking of a few ideas, but it wouldn't be able to do cross-month calculations and there's no way it could know which month has 30, 31 days, etc.. It'd just be foolin around with the "ECHO %date%" command. Wait just a minute... it might work...here's my line of thinking... maybe it CAN be done... I'm going to try an example that sets back a week from the current date... This would require a lot of calculating, and knowledge of the number of days in a month; there's no algorithm in BATCH (*censored*, that's the second time I accidentally typed "BATVH"...) to do that. So... here I go on this... The output of "ECHO %date%" sans the quote marks is similar to the following: Wed 07/05/2006 Dredging up my DOS tutorial, you can take only part of that with the "~" command and save it as a variable. Remembering that the "W" is character 0 on the line, you could set x as the day with the following: SET /A x=%date:~7,2% That would start at character 7 and end 2 characters later. Then, x would be the number 05. Then, you could do this: SET /A day=%x% - 7 NOTE: This only works on later operating systems. Test the /A switch by typing at a command prompt (minus the quotes): "SET /A x=7 - 2" and pressing [Enter]. If you get an error, my method won't work. If you see the number "2" then another prompt, it works and so will my method... I think. to go back a week. This can cause negative numbers, but you can use that to your advantage. Use this to get the month: IF %day% LEQ 0 SET /A month=%date:~4,2% - 1 IF %day% GEQ 1 SET /A month=%date:~4,2% This says: "If the value of variable "day" is less than or equal to 0, set month as two numbers starting at the 4th character in the date minus 1. If this value is equal to or greater than 1, just take the two characters with no subtraction." Then go through the process of doing this (I'm abbreviating the excruciating list): IF "%month%"=="0" SET month=Dec IF "%month%"=="01" SET month=Jan IF "%month%"=="02" SET month=Feb IF "%month%"=="03" SET month=Mar IF "%month%"=="04" SET month=Apr ... IF "%month%"=="12" SET month=Dec Yeah, you get to do all 13. This sets up your month. But what about the negative day (if you have it)? Well, this is where I'm trying to work this out. It seems possible up to this point, but I'm getting odd errors from DOS testing this part of the code. I'll need to get back to you on this... unless you say "never mind". This is so big, it may be my biggest challenge yet. EDTED: I think I got it, but it will require a lot more work. Let me keep going on this, I'll keep you posted! Except that I need to run out to Wal-Mart in about half an hour, so you may need to wait for the rest of this.OK. Now you'll need to use precisely the code below. It will direct the batch file to go to the subroutine that corresponds with the month: Code: [Select]GOTO %month% :Jan IF "%day%"=="0" set day=31 IF "%day%"=="-1" set day=30 IF "%day%"=="-2" set day=29 IF "%day%"=="-3" set day=28 IF "%day%"=="-4" set day=27 IF "%day%"=="-5" set day=26 IF "%day%"=="-6" set day=25 GOTO AfterDayChange :Feb IF "%day%"=="0" set day=28 IF "%day%"=="-1" set day=27 IF "%day%"=="-2" set day=26 IF "%day%"=="-3" set day=25 IF "%day%"=="-4" set day=24 IF "%day%"=="-5" set day=23 IF "%day%"=="-6" set day=22 GOTO AfterDayChange :Mar IF "%day%"=="0" set day=31 IF "%day%"=="-1" set day=30 IF "%day%"=="-2" set day=29 IF "%day%"=="-3" set day=28 IF "%day%"=="-4" set day=27 IF "%day%"=="-5" set day=26 IF "%day%"=="-6" set day=25 GOTO AfterDayChange :Apr IF "%day%"=="0" set day=30 IF "%day%"=="-1" set day=29 IF "%day%"=="-2" set day=28 IF "%day%"=="-3" set day=27 IF "%day%"=="-4" set day=26 IF "%day%"=="-5" set day=25 IF "%day%"=="-6" set day=24 GOTO AfterDayChange :May IF "%day%"=="0" set day=31 IF "%day%"=="-1" set day=30 IF "%day%"=="-2" set day=29 IF "%day%"=="-3" set day=28 IF "%day%"=="-4" set day=27 IF "%day%"=="-5" set day=26 IF "%day%"=="-6" set day=25 GOTO AfterDayChange :Jun IF "%day%"=="0" set day=30 IF "%day%"=="-1" set day=29 IF "%day%"=="-2" set day=28 IF "%day%"=="-3" set day=27 IF "%day%"=="-4" set day=26 IF "%day%"=="-5" set day=25 IF "%day%"=="-6" set day=24 GOTO AfterDayChange :Jul IF "%day%"=="0" set day=31 IF "%day%"=="-1" set day=30 IF "%day%"=="-2" set day=29 IF "%day%"=="-3" set day=28 IF "%day%"=="-4" set day=27 IF "%day%"=="-5" set day=26 IF "%day%"=="-6" set day=25 GOTO AfterDayChange :Aug IF "%day%"=="0" set day=31 IF "%day%"=="-1" set day=30 IF "%day%"=="-2" set day=29 IF "%day%"=="-3" set day=28 IF "%day%"=="-4" set day=27 IF "%day%"=="-5" set day=26 IF "%day%"=="-6" set day=25 GOTO AfterDayChange :Sep IF "%day%"=="0" set day=30 IF "%day%"=="-1" set day=29 IF "%day%"=="-2" set day=28 IF "%day%"=="-3" set day=27 IF "%day%"=="-4" set day=26 IF "%day%"=="-5" set day=25 IF "%day%"=="-6" set day=24 GOTO AfterDayChange :Oct IF "%day%"=="0" set day=31 IF "%day%"=="-1" set day=30 IF "%day%"=="-2" set day=29 IF "%day%"=="-3" set day=28 IF "%day%"=="-4" set day=27 IF "%day%"=="-5" set day=26 IF "%day%"=="-6" set day=25 GOTO AfterDayChange :Nov IF "%day%"=="0" set day=30 IF "%day%"=="-1" set day=29 IF "%day%"=="-2" set day=28 IF "%day%"=="-3" set day=27 IF "%day%"=="-4" set day=26 IF "%day%"=="-5" set day=25 IF "%day%"=="-6" set day=24 GOTO AfterDayChange :Dec IF "%day%"=="0" set day=31 IF "%day%"=="-1" set day=30 IF "%day%"=="-2" set day=29 IF "%day%"=="-3" set day=28 IF "%day%"=="-4" set day=27 IF "%day%"=="-5" set day=26 IF "%day%"=="-6" set day=25 GOTO AfterDayChange :AfterDayChange Two things should be noted: One. This doesn't account for the LEAP year. My response: Shut up. I really don't care at this point. The other is that it was intentional that Jul and Aug have 31 days. This is a blinding flash of the obvious, but I've had people argue that that is impossible. Now, we have the month and day of a week ago. The year is easily gotten: SET year=%date:~10% Finally, at the bottom, you can do this: ECHO A week ago, it was day %day% of %month%, %year%. One final note: I haven't figured out a way to make this work cross-years. Just don't run it between January 1 and January 7 and you'll be fine. EDIT AGAIN: Hold on, I'm not getting a good month result. Let me debug this... ...got it. Piece of cake.Turns out, I made a human error: I forgot to fill in the other months! *smacks forehead* Attached is a zipped version of the completed sample you just read. Extract to C:\, then go to the command prompt, type "cd \" bar the quotes, then type "one_week_ago" minus the quotes to see the results of my work. Open the batch file in Notepad to view the source. It isn't exactly what you asked for, but it does show how it is possible (although hard) to do something like this. *pats self on back* EDIT AGAIN: Hold it, another fatal error noticed. Give me a minute... EDIT ONE LAST TIME: Fixed.Thanks for all the work you have done Dilbert. It's much appreciated. I tested the script and it came back with :A week ago, it was day 31 of May, 2006." I'm in Australia so the date today is Thursday 06/07/2006. I think a little reworking of the batch file would FIX that though. But at least now i can see how it is done. I wasn't aware it was so hard to get a batch file to do what i wanted. What is even harder is that i had hoped to display the date not in terms of from "X" days ago but from say the last "Tuesday" or "Monday" (or other days) from within the last week, displayed in the format DDMMYY (or others) and used within a command to get a file like: http://www/somesite.com/file"date_of_last_past_Monday".wmv etc. I'm thinking i might have been a little unrealistic to expect to achieve this with just a batch file. The work that would be involved just to do that (including with leap years) is just unbelievable. I would assume you would have to calculate the date say from 1-6 days ago individually, then associate that with the day name (like Monday, Tuesday etc) which fell on that date, then figure out a way to get the format i need (DDMMYY or MMDDYY or DDMMYYYY etc).....WOW. Erm.... What do you think? Am i expecting too much to be able to achieve all this from a humble little batch file? ExistanceQuote Thanks for all the work you have done Dilbert. It's much appreciated. Does May not have 31 days? Or is it different in Australia? I'm in the USA so I have no idea. But, in the USA, on the 7th of any day, going back 7 days would bring the day counter to "0", so it would roll back to the previous month, or June. June has 30 days, so a day value of "0" would be reset to the last June day possible, or "June 30". By my calender, it is the 5th of July, and the result on my PC is the following: Quote A week ago, it was day 28 of Jun, 2006. According to the standard USA calendar, this would be a correct answer and the file is functioning as intended. Again, if our calenders are different (Like I said, it's 7/5/2006 here, though it'll be 7/6/2006 in 2 hours), that would explain it. IF they're not different, something went wrong somewhere between finishing debugging and the final upload. And not much happened between those two points in time. BATCH is extremely limited; it's an antique method of "programming". If I knew how, I'd use scripts for everything instead of BATCH. But I'll need to learn the stuff, then I'll have to get Norton to accept my VBS files, etc... it's a project for later. I'm not 100% sure I understand what you want. Just so I don't run off making a seemingly impossible batch file you don't need (that was 4 KB -- pretty large for a BATCH), Let me see if I get what you're saying: 1. User inputs a day of the week, such as "Tuesday". 2. Display all files in the current directory that were made this week, from that date to today. 3. Do something with these files. If that's what you're looking for, the job will be considerably easier than you'd think. It would be a simple matter of a few commands interpereted the correct way, then a simple DIR based on those parameters will be simple enough to show it, then any commands after that are coder's discretion. The reason that the batch file you just saw was so darn complicated is evidence that BATCH is very limited: DOS has no real way of sobtracting dates. It isn't intelligent in that way. It just remembers the date in that format, and refreshes it every 24 hours. The BATCH file I wrote isn't as complicated as those files can get; the main reason it's so large is because it needs to send an innocent number through the wringer, as my code interperets that number to get the month and day of 7 days ago -- no small feat in DOS.if your only concern is Quote "jscript seems to run straight through its commands without waiting for any process or command to finish first"i am sure jscript has some timer functions to stop for a period of time before processing continues right? why not use that...? |
|