Fdate 16a
2003-07-26 02:18:41
Project Home Page
1 | INTRODUCTION 1 - What Is Fdate? |
2 | INTRODUCTION 2 - Author Information |
3 | INTRODUCTION 2a - Running FDATE under NT, Windows2000, XP |
4 | INTRODUCTION 3 - What To Do If This Documentation Seems Too Overwhelming |
5 | INTRODUCTION 4 - The 3-Minute Introduction to Fdate |
6 | INTRODUCTION Revision History |
7 | FAQ How can I rename a log file or a directory to a name containing today's date? |
8 | FAQ How do I put FDATE's output into an environment variable? |
9 | OVERVIEW Examples |
10 | OVERVIEW Functions |
11 | OVERVIEW Parameters |
12 | PARAMETER /C - Custom Output Date Formats |
13 | PARAMETER /F - The Function Parm -- Fdate's Most Important Parm |
14 | PARAMETER /I - Input Date Formats |
15 | PARAMETER /J - Justifying Output |
16 | PARAMETER /L - Output Language |
17 | PARAMETER /O - Output Date Formats (pre-defined) |
18 | PARAMETER /Oxxx - Extended Hex Output Date Format |
19 | PARAMETER /P - Output prefix |
20 | PARAMETER /S - Output suffix |
21 | PARAMETER /T - Time Override Parameter |
22 | FUNCTION #2Xx - Convert An Integer To Extended Hex Notation |
23 | FUNCTION #Add - Add Two Numbers |
24 | FUNCTION #Comp - Compare Numbers |
25 | FUNCTION #Dif - Calculate The Difference Between Two Integers |
26 | FUNCTION #Div - Divide Two Numbers |
27 | FUNCTION #Idiv - Integer Division Of Two Numbers |
28 | FUNCTION #Mod - Modulus, Division Remainder |
29 | FUNCTION #Mult - Multiply Two Numbers |
30 | FUNCTION #Random - Produce A Random Number |
31 | FUNCTION ADD a number of days to a date |
32 | FUNCTION Comp - Compare Dates |
33 | FUNCTION DIF - find the number of days between two dates |
34 | FUNCTION Echo - Output A String |
35 | FUNCTION F - Output A Formatted Date |
36 | FUNCTION Get And Getu - Get User Input Functions |
37 | FUNCTION Getk (Get Keypress) Function |
38 | FUNCTION Len (Length) Function |
39 | FUNCTION M - Month Date Arithmetic |
40 | FUNCTION Substr (Substring) Function |
41 | FUNCTION Tcomp - Compare Times |
42 | FUNCTION Upper - Put A String Into Upper Case |
43 | FUNCTION V - Date Validation |
44 | FUNCTION W - Weekday Date Arithmetic |
45 | TOPIC Fdate's Century-Assumption Algorithm |
46 | TOPIC Fdate's Leap Year Algorithm |
47 | TOPIC Fdate's Support For Long Filenames |
48 | TOPIC How Fdate Thinks About Dates |
49 | TOPIC How To Put Fdate Output Into An Environment Variable |
50 | TOPIC Problem - /V Does Not Work Under NT, Windows2000, XP |
51 | TOPIC Problem - /V Does Not Work Under Win3X Or Win9X |
52 | TOPIC Xset - A Utility For Creating Environment Variables Under NT, Win2k, XP |
53 | TOPIC Y2K - Is Fdate Y2K Compliant |
54 | APPENDIX Another Utility Named "Fdate" |
55 | APPENDIX Contents Of The Fdate.Zip Distribution File |
56 | APPENDIX Fdate's Error Handling |
57 | APPENDIX Fdate's Implementation Limits |
58 | APPENDIX Revision History |
59 | APPENDIX Symbols used in Date Formats |
60 | APPENDIX Technical Support For Fdate |
61 | APPENDIX Uploading Fdate To Electronic Bulletin Boards |
62 | APPENDIX Use, Registration, And Distribution Of Fdate |
63 | APPENDIX Where To Find The Most Current Version Of Fdate |
64 | EXAMPLE 01 Display Fdate output on screen |
65 | EXAMPLE 02 Redirect FDATE output to a file |
66 | EXAMPLE 03 Put FDATE output in an environment variable using a batch file |
67 | EXAMPLE 04 Put FDATE output in an environment variable using /V parm |
68 | EXAMPLE 05 Put FDATE output in an environment variable using STRINGS |
69 | EXAMPLE 06 Put FDATE output in an environment variable using GET |
70 | EXAMPLE 07 Get user input |
71 | EXAMPLE 08 Get a user menu selection |
72 | EXAMPLE 09 Change a date from one format into another |
73 | EXAMPLE 10 Find the difference in days between two dates |
74 | EXAMPLE 11 Find the elapsed days/hours/minutes between two date/times. |
75 | EXAMPLE 13 Find the elapsed years/months/days between two dates. |
76 | EXAMPLE 14 Determine how long it took a program to run |
77 | EXAMPLE 15 Find years when a given date fell on a given day of the week |
78 | EXAMPLE 16 Find calendar date corresponding to a "business Julian" date |
79 | EXAMPLE 17 Set your PC's date to a business Julian date |
80 | EXAMPLE 18 Determine if parm %1 contains a valid date |
81 | EXAMPLE 19 "Roll your own" date format |
82 | EXAMPLE 20 Find the 4th Thursday in November (Thanksgiving) |
83 | EXAMPLE 22 On a date, show what anniversary it is for some event |
84 | EXAMPLE 23 Show a list of holidays in a given year |
85 | EXAMPLE 24 Show a list of Federal holidays in a given year |
86 | EXAMPLE 25 Determine if a year is valid, and evenly divisible by 4 |
87 | EXAMPLE 30 Find the date 1 month, 3 months, 1 year from today |
88 | EXAMPLE 33 MIN_MATH.BAT -- "time arithmetic" in minutes |
89 | EXAMPLE 34 TIME_SET.BAT -- "time arithmetic" -- set TIME |
90 | EXAMPLE 42 Get date to tell PKZIP to compress files older than 30 days |
91 | EXAMPLE 43 Loop through an array of environment variables |
92 | EXAMPLE 44 Do something on the last day (or last Friday) of the month |
93 | EXAMPLE 45 Get information about the month prior to the current month |
94 | EXAMPLE 46 Show the last Monday (or any other weekday) in this month |
95 | EXAMPLE 47 Show the last Monday in the month, for a series of months |
96 | EXAMPLE 50 Represent a date in 3 bytes of "extended hex" notation |
97 | EXAMPLE 51 Represent a date in a short (4-byte) format (technique #1) |
98 | EXAMPLE 52 Represent a date in a short (4-byte) format (technique #2) |
99 | EXAMPLE 53 Convert numbers to "extended hex" (XX) format |
100 | EXAMPLE 54 Customize Fdate for a language of your choice |
101 | EXAMPLE 55 Fergian.BAT (used in the previous example) |
102 | EXAMPLE 61 DO-ONCE: Run apps when booting for the first time of the day |
103 | EXAMPLE 62 Run specific software, depending on the day of the week |
104 | EXAMPLE 63 Run a program at a specified time later in the day |
105 | EXAMPLE 71 Extract the rightmost n characters of a string |
106 | EXAMPLE 72 Left-pad a number with zeroes, or a string with spaces |
107 | EXAMPLE 80 --- SECTION: CHECKING/MANIPULATING A FILE'S DATE/TIMESTAMP |
108 | EXAMPLE 81 Rename a file name to a name that contains today's date |
109 | EXAMPLE 82 Rename a file to a name that contains today's time |
110 | EXAMPLE 83 Rename a file to a name that contains today's date in only 3 bytes |
111 | EXAMPLE 85 Compare a file's date to today's date |
112 | EXAMPLE 86 Compare two files' date/time using COMPARE-FUNCTION ERRORLEVELS |
113 | EXAMPLE 87 Take action if a file has not been updated recently |
114 | EXAMPLE 88 Display a list of all files that were created/updated today. |
115 | EXAMPLE 89 Delete files more than X days old (use a batch-file subroutine) |
Entry number 1 Table of Contents
.INTRODUCTION: 1 - What Is Fdate?
.DISCUSSION..:
The Fdate motto is "Everything you'd ever want to do with dates in batch files."
Fdate is a utility for doing date formatting and date arithmetic in DOS batch
files. There are a number of different ways to put Fdate's output into
environment variables. Once this has been done, the environment variables
can be used and manipulated in many ways in the batch file.
Fdate is freeware, or what is technically known as "zero-cost shareware".
There is no requirement to register Fdate in any way. For more details,
see APPENDIX Use, Registration, And Distribution Of Fdate
Here are some of the things you can do with Fdate.
- accept user input from the keyboard
- retrieve today's date in a variety of formats
- place today's date into a file name
- reformat dates
- Output formats include common American and European
formats, or you can "roll your own" by manipulating
environment variables. Month and weekday names can be
produced in several languages (English, French, German,
Danish, Spanish).
- calculate when certain holidays occur in a given year
- do date arithmetic
- determine the date N days before/after a given date
- compare two dates to determine which is earlier
- compare two dates to determine how many days apart they are
- determine if a year is a leap year
- determine whether a year is evenly divisible by some number
- determine what day of the week a date falls on
- run certain software only on certain days of the week
- retrieve the date/time from the date/timestamp of a file
- do simple integer arithmetic (add, subtract, modulus)
- calculate the time a piece of software takes to run
- convert a calendar date to/from a "business Julian" date
- extract a substring from an environment variable
- right, left, or center justify a string
Entry number 2 Table of Contents
.INTRODUCTION: 2 - Author Information
.DISCUSSION..:
The author of Fdate is:
Stephen Ferg
608 N. Harrison Street
Arlington, VA 22203-1416
USA
Internet : steve@ferg.org
telephone (voice, not FAX): (703) 525-2241
Also, you can see Steve Ferg's home page
www.ferg.org
which has the latest version of Fdate.
Entry number 3 Table of Contents
.INTRODUCTION: 2a - Running FDATE under NT, Windows2000, XP
.DISCUSSION..:
NOTE that the /V parameter WILL NOT WORK under Windows NT and its derivatives
such as Windows 2000 and Windows XP.
For more information,
see TOPIC Problem - /V Does Not Work Under NT, Windows2000, XP
Entry number 4 Table of Contents
.INTRODUCTION: 3 - What To Do If This Documentation Seems Too Overwhelming
.DISCUSSION..:
As Fdate has grown in functionality over the years, its documentation
has also grown. Folks who encounter Fdate for the first time sometimes
feel that Fdate's documentation is so massive that it is overwhelming:
they have no idea where to start, or how to use the documentation to
help them figure out how to make Fdate do what they need to do.
If that is the situation you're in right now, take heart! There is
hope!
see Introduction 4 - The 3-Minute Introduction to Fdate
Entry number 5 Table of Contents
.INTRODUCTION: 4 - The 3-Minute Introduction to Fdate
.DISCUSSION..:
This is a "quick start" introduction to using Fdate.
INTRODUCTION: WHAT IS FDATE?
Fdate is a utility for doing date formatting and date arithmetic in DOS
batch files. At least, that was its original purpose. Over the years,
functions were added to Fdate to support activities that people often
need to do in conjunction with working with dates.
To help you get started using Fdate, I've created this short
introduction which shows how to use Fdate to do the things most
users want to do. When you've finished, you may still have a
question: "Can I do such-and- such with Fdate?" If it involves
dates, it probably CAN be done with Fdate, although tricky things
are of course tricky to do, even with Fdate. A good next step
would be to look at the list of examples. With luck, you will
find an example that shows Fdate doing just what you want to do.
To understand how Fdate is working in a particular example, look
up the parameters used in the example.
see OVERVIEW Examples
THE 3-MINUTE INTRODUCTION TO FDATE
By far the most popular use of Fdate is to put today's date-- in a
particular format-- into an environment variable. Once this has been done,
the environment variable can be used and manipulated in many ways in a
batch file. Here are a few short exercises that will help you to learn how
to use Fdate's most basic features to do that.
1.
At the DOS prompt, type:
FDATE
This will show you Fdate's HELP screens. Press ENTER to page through
the HELP screens.
The information on these HELP screens is very dense. It won't teach you
how to use Fdate, but it is useful for jogging your memory as you become
familiar with Fdate's various features.
2.
At the DOS prompt, type:
FDATE /Ff
I've used lowercase "f" here to distinguish the value of the parameter
from the parameter-letter itself, but it really doesn't matter whether
the parameter or its value is in upper or lower case. Except for the /K
parameter (one of Fdate's advanced features), Fdate's parameters are not
case sensitive.
Here, the value of the "/F" (function) parameter is "f" (format a date).
The "/Ff" parameter tells Fdate that the function you want it to perform
is to format a date. Since the default date is "today", this command
will cause Fdate to display today's date on your screen in Fdate's
default output format.
3.
At the DOS prompt, type:
FDATE /Ff /P"Today is "
This command is just like the one in the previous example, except that
we've specified the "prefix parameter" (/P), which tells Fdate to add a
string to the beginning of its output. (There is also a "suffix
parameter" that tells Fdate to add a string to the end of its output.)
Note that the value of the /P parameter is enclosed in quotes. (Either
single quotes or double quotes will work.) We've had to enclose the
value in quotes because it contains embedded blanks (one blank after the
word "today" and another after the word "is").
4.
At the DOS prompt, type:
FDATE /Ff /Occyymmdd
(Or you can put the same statement in a batch file.)
Here, you are telling Fdate to put out today's date in a specific
format. On the "output format" parm (/O) you are specifying that you
want the day in "ccyymmdd" format: two digits each for century, year-
within-century, month, day-of-month.
Note that the /O parm is a predefined, fixed, format. Fdate supports many
such pre-defined output formats. If you want more flexibility, then you can
"roll your own" date format using the /C (custom output) parameter.
5.
At the DOS prompt, type:
FDATE /Ff /C"$Today is $N $d, $Y"
Here, you are telling Fdate to put out a string that you have
formatted. The /C parm tells Fdate that the output will be a
customized format. The string after the /C is enclosed in
quotes, because it contains blanks. The first character inside
the string is a $ -- this tells Fdate that you will be using the
$ as the escape character. The symbols $M, $d, and $Y have
special meaning. (Note that, unlike most of Fdate's parameters,
these special symbols ARE case-sensitive.) For more
information,
see PARAMETER /C - Custom Output Date Formats
6.
At the DOS prompt, type:
FDATE /Ff /Occyymmdd /p"@set date1=" >junk.bat
(Or you can put the same statement in a batch file.)
Here, you are telling Fdate to put out today's date in "ccyymmdd"
format. Because you are specifying the redirection symbol (>) and
a batch file name, Fdate's output is being redirected to the batch file.
You can look at the batch file by using the DOS "type" command:
TYPE JUNK.BAT
Now you can run the batch file by typing
JUNK.BAT
at the DOS command prompt.
This will cause JUNK.BAT to run and to put today's date in the DATE1
environment variable. If you type "SET" at the DOS prompt, and if
today is February 1, 1995, you will see as the last line of the SET
output:
DATE1=19950201
7.
Use your favorite text editor to create a batch file called TEST.BAT.
In TEST.BAT, put the following lines:
@echo off
FDATE /Ff /p"@set date1=" >junk.bat
call junk.bat
del junk.bat
echo Today's date is: %date1%
set date1=
Note that in this example we have not specified an output format at all, so
Fdate will use its default format.
Here is the same batch file, with some commentary:
@echo off *** turn ECHO off, so the batch file executes quietly
FDATE /Ff /p"@set date1=" >junk.bat *** you know what this does
call junk.bat *** call junk.bat to set the date1 environment variable
del junk.bat *** cleanup -- delete junk.bat
echo Today's date is: %date1% *** use the environment variable
set date1= *** cleanup -- delete date1
8.
At this point, you know everything you need to know to put today's date
into an environment variable, which you can then use for whatever you
want. As the last step in this introduction, here's an example in which
you are copying a file (BACKUP.LOG, which is put out by a backup
program) to a file whose name contains today's date.
FDATE /Ff /Occyymmdd /Vdate1
copy BACKUP.LOG %date1%.LOG
WHAT TO DO NEXT?
Now that you know the basics, you may have everything you need to know in
order to use FDATE to satisfy your basic date-handling needs. If you need
more information, or are feeling adventurous, your next step should be to
explore the Fdate documentation, which discusses many more features of FDATE.
One of the most useful parts of the documentation is the list of
examples. Browse through the titles of the examples, to get a feel for
what is there.
see OVERVIEW Examples
Then look at the examples themselves. Many are quite elaborate (which
is natural, since they are there to show you how to do Hard Stuff).
Most of the examples are self-contained and ready-to-run -- if you copy the
text of the example into a batch file, the example code will run and do
what the title says it will do. I suggest you try one or two
of the examples that seem most interesting to you.
After the examples, the most useful parts of the Fdate documentation are
the sections documenting Fdate's various functions (the functions that
you can specify on the function parm, /F) and its various output
formats. I suggest you scan those sections, just to get a quick feel
for what's available to you.
Good Luck!
Steve Ferg
Entry number 6 Table of Contents
.INTRODUCTION: Revision History
.DISCUSSION..:
For a listing of the FDATE revision history,
goto APPENDIX Revision History
Entry number 7 Table of Contents
.FAQ.........: How can I rename a log file or a directory to a name containing today's date?
.DISCUSSION..:
This is certainly the most frequently asked question regarding Fdate.
Here are several examples of renaming a file and a directory, to a
date that contains a 2-digit or 4-digit year.
Note that in the custom output format, lower-case "y" indicates a 2-digit
year, and upper-case "Y" indicates a 4-digit year.
Note that the rename operation will fail if a file/directory with the
old name cannot be found, or if a file/directory with the new name
already exists. That means that if you attempt to run the same command
more than once a day, it will fail on the second attempt to run it
because a file (or directory) with the new name will already have been
created when you ran it the first time.
Note that we TYPE (echo to the screen) junk.bat before calling it. That
way, if it fails, we will be able to see the text of the command that
failed.
For more information on the custom output format, see the entry for the
"/C" parameter.
.EXAMPLE.....: @echo off
:: rename file BACKUP.LOG to yymmdd.LOG (ex. 950508.LOG on May 8, 1995)
FDATE /Ff /C"~@rename backup.log ~y~M~D.log"> junk.bat
type junk.bat
call junk.bat
del junk.bat
.EXAMPLE.....: @echo off
:: rename file BACKUP.LOG to ccyymmdd.LOG (ex. 19950508.LOG on May 8, 1995)
FDATE /Ff /C"~@rename backup.log ~Y~M~D.log"> junk.bat
type junk.bat
call junk.bat
del junk.bat
.EXAMPLE.....: @echo off
:: rename directory BACKUP to yymmdd (ex. 950508 on May 8, 1995)
FDATE /Ff /C"~@rename backup ~y~M~D"> junk.bat
type junk.bat
call junk.bat
del junk.bat
.EXAMPLE.....: @echo off
:: rename directory BACKUP to ccyymmdd (ex. 19950508 on May 8, 1995)
FDATE /Ff /C"~@rename backup ~Y~M~D"> junk.bat
type junk.bat
call junk.bat
del junk.bat
Entry number 8 Table of Contents
.FAQ.........: How do I put FDATE's output into an environment variable?
.DISCUSSION..:
There are two methods. One uses a temporary batch file. The other uses
enhanced features of the FOR command.
Method 1 should work on all versions of Windows. But note that it will
not work if the person running your batch file does not have WRITE
permissions on the directory where you want to put junk.bat. If this
is a problem, then you can work around it by creating the temporary
batch file in a directory where you are sure that the user does have
WRITE permissions -- for example, in the root directory of the C:
drive: c:\junk.bat.
.EXAMPLE.....: @echo off
:: put Fdate output into an environment variable called "date1"
:: ------------------------------------------------------------
:: METHOD #1 -- Use a temporary batch file
:: ------------------------------------------------------------
FDATE /Ff /ofull /p"set date1=" >junk.bat
call junk.bat
echo It is now %date1%
:: cleanup
del junk.bat
set date1=
.DISCUSSION..:
An alternative work-around is to use Method 2, if you are using a
version of Windows that supports it.
Method 2 uses enhanced features of the FOR command that should be
available on Windows NT, Windows 2000, XP, and later versions of
Windows. Note that the parameter "tokens=*" is required is the
Fdate output contains multiple words -- as a general practice, you
should always specify it. In using Method 2, you may have to
watch carefully to make sure that any strings in quote-marks are
closed by matching quote-marks of the correct type.
.EXAMPLE.....: @echo off
:: put Fdate output into an environment variable called "date1"
:: ------------------------------------------------------------
:: METHOD #2 -- use the enhanced FOR command features
:: This method should work on Windows NT, Windows 2000, and XP
:: ------------------------------------------------------------
for /f "tokens=*" %%v in ('FDATE /Ff /C"~~Y-~M-~D (~W)"') do set date1=%%v
echo Today is %date1%
:: cleanup
set date1=
Entry number 9 Table of Contents
.OVERVIEW....: Examples
.DISCUSSION..:
The examples in this file are listed here as Backward References.
Entry number 10 Table of Contents
.OVERVIEW....: Functions
.DISCUSSION..:
Fdate's functions are listed here as Backward References.
.DISCUSSION..:
In this section, we present an overview of the functions that can
specified on the /F (function) parameter.
Fdate's most important parameter is the function parameter, /F. Here is
a brief summary of the functions that may be specified on the /F parm,
for example: /Fadd. Detailed descriptions of each of the functions can
be found in other sections of this documentation.
If the /F parameter is omitted, it defaults to the null string, which
causes Fdate to display its HELP screens.
The general format of an Fdate statement is:
with a variety of parameters following the /F.
For example:
- Fdate /Ff
- Fdate /Fadd /A5 /B6 [adds 5 and 6]
- Fdate /Flen /Q"this is a test" [produces the length of "this is a test"]
GENERAL DATE FUNCTIONS
- F
Format the date in the /A parm into format specified in /O parm
- ADD
Add the number of days in the /N parm to the date in the /A parm
- SUB
Subtract the number of days in the /N parm from the date in the /A parm
- DIF
Return the number of days between dates in the /A and /B parms
- W
Do date arithmetic in terms of weeks rather than days. Using
the date in the /A parm, a number specified in the /N parm, and
a day-of-the-week number specified in the /D parm, return the
date of the /Nth /Day-of-the-week before (or after) /Adate.
- M
Do date arithmetic in terms of months rather than days. Add the
number of months in the /N parm to the date in the /A parm. /N
may be a negative number.
STRING-HANDLING FUNCTIONS
- GET
get user input from the keyboard, and produce it as output.
Optionally, display a prompt string.
- GETU
same as get, but produce output converted to upper case
- GETK
get a keypress and produce it (converted to upper case)
- LEN
produce the length of a string in the Q parm
- UPPER
convert the string in the Q parm to upper case
- E
Echo the strings on the P and S parameters.
- SUBSTR
Extract a substring from the Q parm, starting in column specified
on A parm, for a length specified on B parm.
DATE/TIME COMPARISON FUNCTIONS
- COMP
Compare the dates in the /A and /B parms. Return LT, EQ, or GT.
- TCOMP
Compare the times specified on the /A and /B parms.
MATH FUNCTIONS
Note that these are NOT date math functions; they are NUMBER math functions.
Functions whose names begin with "#" do ordinary arithmetic, i.e.
arithmetic on numbers rather than dates.
- #ADD
Add the integers specified on the /A and /B parms. To do
subtraction, add a negative number to a positive number.
- #DIF
returns the difference between the integers specified on the /A
and /B parms.
- #COMP
Compare the integers specified on the /A and /B parms. Return
LT, EQ, or GT.
- #MOD
Modulus. Divide the integer on the /A parm by the integer on
the /B parm, and return the remainder.
- #RANDOM
Returns a random number between a lowerbound (specified on the /B
parm) and an upperbound (specified on the /A parm).
- #MULT
Multiply the integer on the /A parm by the integer on the /B
parm, and return the result.
- #DIV
Divide the integer on the /A parm by the integer on the /B
parm, and return the result as a decimal number with two
decimal places.
- #IDIV
Integer division. Divide the integer on the /A parm by the
integer on the /B parm, and return the result as an integer.
- #2XX
Convert an integer in the range of 0-35 to "extended hex" (XX)
notation.
Note that all of Fdate's arithmetic functions operate on integers. A decimal
number on an input parameter will be rejected, and an error message will be
displayed.
- #ADD
returns the sum of the integers specified
on the /A and /B parms. Can be used to calculate the
"absolute" minute(second, date) in the future from a given
"absolute" minute(second, date). Also useful in generating
sequences of numbers and looping (see EXAMPLES).
- #SUB (NOT SUPPORTED)
Fdate does not provide a numeric subtraction operation as such.
To do subtraction, add two numbers, one of which is a negative
number. For example, to subtract 3 from 2:
Fdate /F#add /A2 /B-3 [ returns: -1 ]
- #DIF
returns the difference between the integers specified on the /A
and /B parms. #dif is the same as subtraction in which the
smaller number is subtracted from the larger number; it will
never return a negative number. It can be used to calculate the
number of minutes(seconds, days) between two "Absolute"
minutes(seconds, dates).
- #COMP
compares the integers specified on the /A and /B parms.
- returns LT /A is less than /B
- returns EQ /A is equal to /B
- returns GT /A is greater than /B
In addition, the errorlevel is set to a special value:
- LT = 101
- EQ = 102
- GT = 103
- #MOD
divides the integer on the /A parm by the integer on the /B parm,
and returns the remainder.
This is useful for determining whether a number is evenly
divisible by some other number. If the remainder is 0, then /A
is evenly divisible by /B. If a year is evenly divisible by 4,
for example, then it is an American election year. If it is
evenly divisible by 100, then it is a century year, etc.
- #MULT
multiplies the integer on the /A parm by the integer on the /B
parm, and returns the result.
- #DIV
(division) divides the integer on the /A parm by the integer on
the /B parm, and returns the result as a decimal number, with two
digits to the right of the decimal.
This is useful for dividing a number (representing the number of
minutes in some period) by 60 to get the length of the period
expressed in terms of hours, or by 1440 to get the length of the
period expressed in terms of days. Or you could divide a number
of days by 7 to get the number of weeks, etc.
- #IDIV
(integer division) divides the integer on the /A parm by the
integer on the /B parm, and returns the result as an integer.
This is useful, especially in conjunction with the #mod function,
for converting a number of minutes into a number of hours and
minutes, or days and hours and minutes. See the EXAMPLES file.
- #2XX
Convert number to "extended hex" format.
Entry number 11 Table of Contents
.OVERVIEW....: Parameters
.DISCUSSION..:
Fdate's parameters are listed here as Backward References.
.DISCUSSION..:
Fdate accepts the following parameters:
/F /A /B /C /I /O /P /S /N /D /L /V /T /Q /J /K /X /Y
If the /F parameter is not present, Fdate displays a help screen.
If you get Fdate's help screen when you don't expect it, you probably
forgot to specify the /F parameter or mistyped it.
Parameters can be in any order and upper or lower case.
- Note that although function and format parms are not case sensitive,
they are "text sensitive". If any characters are missing, added, or
mistyped, the parameter will be rejected.
What parameters are required (other than /F) depends on the function
requested with the /F parameter. Unnecessary parameters are simply ignored.
SUMMARY OF PARAMETERS
- /F
Requests a particular Fdate function. This is Fdate's most important
parameter.
- /A and /B
For date functions, these two parameters are used to specify dates.
For the ordinary arithmetic functions, these parameters are used to
specify numbers. For date functions, if either of these parameters is
omitted, it defaults to today's date.
- /C specifies a "custom" output date format
If the /C parameter is omitted, it is assumed that the
output format will be specified on the /O parameter.
- /D day-of-week number (used only with W function)
- /I specifies format of input date(s)
If the /I parameter is omitted, /Imm-dd-ccyy is assumed.
- /J specifies justification, length, and pad character(s)
If the /J parameter is omitted, no justification formatting is done.
- /K The GETK function takes a /K "keymask" parameter that tells it which
keys to accept.
- /W The GETK function takes a /W "seconds to wait" parameter that tells
it how many seconds to wait before returning the first key in the
/K "keymask" parameter. Valid values are in the range of 1..36000
(10 hours). Default value of /W is 36000 (10 hours).
- /L specifies language of output.
- /Lus US (American) English-language output
- /Lfr French-language output
- /Lgr German-language output
- /Lsp Spanish-language output
- /Ldk Danish-language output (requires codepage 850 to display correctly)
If the /L parameter is omitted, /Lus [American English] is assumed.
- /N number of days (always a number)
- /O specifies format of output date
If the /O parameter is omitted, /Od1 is assumed.
- /Q specifies a prompt string for a GET, GETU, or GETK function, or the
input string for a string-handling function (SUBSTR, LEN, UPPER).
- /P specifies a prefix string for the output
- /S specifies a suffix string for the output
These optional parameters may always be specified or omitted.
They must be enclosed in single quotes, double quotes, or
square brackets
Note that "whitespace" will be removed from these strings, so
formatting of /P and /S strings cannot be controlled using spaces. To
format strings, use periods or ASCII 255 (hex'ff') as filler.
.EXAMPLES....: Fdate /Ff /P"Today is "
Fdate /Fdif /B12-25-TTTT /P"It is " /S" days until Christmas"
.DISCUSSION..:
- /T For date functions, /T overrides the time portion of the date on the
/A parm. (Note that it does NOT override the time portion of the date
on the /B parm.)
- /V specifies that output is to be placed in an environment variable
rather than written to standard output.
If /V is specified but not followed by the name of an environment
variable, then /VFdate is assumed, and output is placed in the Fdate
environment variable.
- /X Used only with the weekday arithmetic function (/Fw). By default,
if the date specified on the /A parm falls on the day of the week
specified on the /D parm, then the /A date is considered to be the
first date meeting the day-of-week criterion. If the /X parm is
specified, then the /A date will NOT be considered to meet the
day-of-week criterion.
see function W - Weekday Date Arithmetic
- /Y Years to look back when converting a 2-digit year to a 4-digit
year. Valid values are in range 0..99. Default is 80.
Entry number 12 Table of Contents
.PARAMETER...: /C - Custom Output Date Formats
.CATEGORY....: parameters
.DISCUSSION..:
The CUSTOM OUTPUT FORMAT parameter (/C) is designed to be more flexible than
Fdate's original OUTPUT DATE FORMAT parameter (/O). You may
specify the /C parameter in conjunction with any Fdate function that produces
a date or time as its output. The /C parm allows you to specify any desired
output string, with components of the date and time inserted into the string
in any place where they are desired.
The first character of the /C parm is taken to be the character that you want
to use as the ESCAPE CHARACTER. Starting with character 2, the string
specified on the /C parm is processed.
When an escape character is found, the next character will be processed
as an INSERT CODE -- a character that indicates that a special value is
to be inserted into the output string. If the INSERT CODE is the same as
the escape character, the escape character is inserted. Otherwise, one
of the following values is inserted. Note that these values for the
insert code are case-sensitive. Upper-case and lower-case codes are
related, with the lower-case code inserting a string that is generally
shorter than the one inserted by the upper-case code.
DEBUGGING TIP
If you are having problems with your custom output format, make sure that
the first character in the /C parm is the escape character. If the first
thing in your output string is an insert code, then the string should
start with TWO escape characters, one to define the escape character, and
one to identify the insert code. For instance, to produce the current
4-digit year, you would code:
fdate /ff /c"~~Y"
- J - JJJ Business Julian date with leading zeros (1999/009)
- j - zzJ Business Julian date without leading zeros (1999/9)
- Y - 4-digit year (1999)
- y - 2-digit year (99)
- A - time in AM/PM format with a space between the minute and am/pm (09:04 am)
- a - time in AM/PM format with no space preceding the am/pm (09:04am)
- D - Day of month with leading zeros (09)
- d - Day of month without leading zeros (9)
- M - Month number with leading zeros (09)
- m - Month number without leading zeros (9)
- I - Long ISO date (ccyy-mm-dd) (1999-09-09)
- i - Short ISO date (ccyymmdd) (19990909)
- T - Long ISO time (hh:mm:ss) (09:09:09)
- t - Short ISO time (hhmmss) (090909)
- H - Hour with leading zeros (09)
- h - Hour without leading zeros (9)
- R - am/pm hour with leading zeroes
- r - am/pm hour without leading zeroes
- Q - "am" or "pm", depending on the time
- U - minUte with leading zeros (09)
- u - minUte without leading zeros (9)
- S - Second with leading zeros (09)
- s - Second without leading zeros (9)
- C - Hundredth of second with leading zeros (09)
- c - Hundredth of second without leading zeros (9)
Values for hundredths of a second are not available in a
file timestamp, so this value will always be zero when
displaying information from a file timestamp.
- N - Name of month (January)
- n - Name of month, left 3 characters (Jan)
- W - Name of day-of-week (Wednesday)
- w - Name of day-of-week, left 3 characters (Wed)
- # - Day-of-week number
- L - Leapyear flag (1=leapyear, 0= non-leapyear)
The results of an escape character followed by any other character are
undefined. (This is to allow for the addition of future insert codes.)
.EXAMPLE.....: (The tilde "~" is used as the escape character)
On April 4, 1999, the following statement:
Fdate /Ff /c"~Today is ~W, ~N ~d, ~Y (ISO date ~Y-~M-~D)"
produces: "Today is Sunday, April 4, 1999 (ISO date 1999-04-04)"
.NOTE........:
The names of the days and the months are controlled by the language parameter
(/L), and will vary with the language. For examples, run CUSTOM.BAT.
Entry number 13 Table of Contents
.PARAMETER...: /F - The Function Parm -- Fdate's Most Important Parm
.CATEGORY....: parameters
.DISCUSSION..:
The /F parameter specifies the function that you want Fdate to perform.
It is the most important of Fdate's parms. For more information,
see overview functions
Entry number 14 Table of Contents
.PARAMETER...: /I - Input Date Formats
.CATEGORY....: parameters
.DISCUSSION..:
For a list of the symbols used in specifying fixed date formats,
see APPENDIX Symbols used in Date Formats
ABSOLUTE DATE -- day#
Returns the "absolute date", that is, the date expressed as the number
of days since the beginning of the calendar.
- returns 1 for January 1, 0001
- returns 2 for January 2, 0001
- etc.
ABSOLUTE TIME -- minute#
Returns the "absolute minute", that is, the time expressed as the number
of minutes since midnight, January 1, 1990.
FILE DATE/TIME STAMP -- /IF
Input format F (file) tells Fdate that /A and /B will specify filenames,
and that Fdate should pick up the input date and time from the date/time
stamp on a file.
Fdate /Ff /If /Afilex.txt /P"FILEX.TXT last updated: " /Ofull
Note that if you specify /If, then both /A and /B will be interpreted as
filenames.
Because the input format applies to both /A and /B parms, it is not possible
to put a filename in /A and a date literal in /B, and then (say) use the
"comp" or "dif" function to compare them. You must first extract the file's
date into an environment variable, and then compare that environment variable
to the date literal.
The only exception to this rule is the pseudodate "t" (i.e. /At or /Bt) which
will pick up the current date and time from the system clock. This feature
will allow you, for example, to compare the date of a file to today's date
(see EXAMPLES).
A filename may (but need not) be fully qualified: i.e. "FooBar.1" and
"C:\DBASE\WORKDIR\FooBar.1" are both acceptable.
A filename may contain wildcards, but only if there is only one file that
matches the wildcard. If Fdate finds more than one file that matches the
filespec, it will return an error message.
CALENDAR DATE INPUT FORMATS
FORMAT EXAMPLES DISCUSSION
------ --------------------------------------
ccyymmdd 19922002
yymmdd 922002 Century will be assumed.
see Topic Fdate's Century-Assumption Algorithm
On the /I (input format) parm, the separator character of the following input
formats must be a dash. This simply tells Fdate that the input date will
contain SOME separator character. The separator character that actually
occurs in dates in the /A and /B parms is ignored, and may be any non-numeric
character: a slash "/", a dash "-", a dot ".", etc.
In specifications that begin with "mm-dd" or "dd-mm", leading zeros need not
be present in the "mm" and "dd" part of the date.
ccyy-mm-dd 1992-02-20 Leading zeros MUST be present, since the
1992/02/20 date does not begin with dd-mm or mm-dd.
1992.02.20
yy-mm-dd 92-02-20 Leading zeros MUST be present, since the
92/02/20 date does not begin with dd-mm or mm-dd.
92.02.20 century is assumed
:see Topic Fdate's Century-Assumption Algorithm
mm-dd-ccyy 02-20-1992
02/20/1992 The dash represents ANY non-numeric character.
2-5-1992 Leading zeros need not be present.
2/5/1992
mm-dd-yy 02-05-92 February 5, 1992.
2/5/92 century is assumed.
:see Topic Fdate's Century-Assumption Algorithm
---------------------------------------
In the following formats, days
precede months (European style)
---------------------------------------
dd-mm-ccyy 05-02-1992
05/02/1992
5-2-1992 Leading zeros need not be present.
5/2/1992
dd-mm-yy 05-02-92 February 5, 1992.
5/2/92 century is assumed.
see Topic Fdate's Century-Assumption Algorithm
BUSINESS JULIAN DATE INPUT FORMATS
These are formats for "business Julian" dates: dates expressed as the number
of days from the beginning of the year, when January 1 is day 1.
.EXAMPLES....: date BUSINESS JULIAN DATE
----------- --------------------
Jan 5, 1992 92005
Jan 5, 1993 93005
Dec 31, 1993 93365 [Dec 31 is 365th day of year 1993]
Dec 31, 1996 96366 [Dec 31 is 366th day, because 1996 is a leap year]
-----------------------------------------------------------------------
NOTE:
* JJJ can be 1 - 5 digits
* may include a prefix of a plus or minus ( + or - ) sign
-----------------------------------------------------------------------
FORMAT EXAMPLES DISCUSSION
------ --------- -----------------------------
ccyyjjj 1992003 Third day of 1992,
i.e. Jan 3, 1992
19923 Third day of 1992
tttt003 Third day of this year
tttt3 Third day of this year
yyjjj 92003 Third day of 1992
923 Third day of 1992
tt003 Third day of this year
tt3 Third day of this year
01003 Third day of 2001
see Topic Fdate's Century-Assumption Algorithm
NOTE THAT Fdate WILL ACCEPT "JJJ" OF LESS THAN 1 & MORE THAN 366.
-----------------------------------------------------------------
yyjjj tt1000 the 1000th day from beginning of this year
tt0 last day of last year
tt-1 next-to-last day of last year
Fdate /Ff /Iccyyjjj /Od1 /A1992-1 produces... Monday December 30, 1991
Fdate /Ff /Iccyyjjj /Od1 /A19920 produces... Tuesday December 31, 1991
Fdate /Ff /Iccyyjjj /Od1 /A1992+1 produces... Wednesday January 1, 1992
Fdate /Ff /Iccyyjjj /Od1 /A1992366 produces... Thursday December 31, 1992
Fdate /Ff /Iccyyjjj /Od1 /A1992367 produces... Friday January 1, 1993
This feature allows limited date arithmetic with ordinary business Julian
days. For example, 90 days from tt300 can be shown by:
Fdate /Ff /Iyyjjj /Att390
Entry number 15 Table of Contents
.PARAMETER...: /J - Justifying Output
.CATEGORY....: parameters
.DISCUSSION..:
Using the /J (justify) parameter, it is possible to right, center, or left-
justify Fdate's output, truncate it, or pad it with a certain character or
character string.
Note that /J is not a function, but a parameter. The /J parameter may be
used in conjunction with any of Fdate's functions. (It is discussed here,
with the string-handling functions, because that's where it seemed most at
home.)
Justification takes place BEFORE the strings specified on the /P (prefix) and
/S (suffix) parms are added to the output.
The format of the /J parm is:
/J"TP##"
In this example:
- T is a single character indicating the type of justification desired:
- R right
- L left
- C centered
- P is one or more characters specifying the string to be used to
pad the output to the desired length.
- The most common values for this character will be the period
(".") and the blank. In order for a blank to be recognized
as a pad character (and not to be taken as the terminator of
the /J-parm value), the /J-parm value must be enclosed in
single or double quotes, e.g.: /J"C 79"
- The first character of the pad string may be a number, but
no numeric character after the first will be recognized as a
pad character.
- Any numeric character after the first pad character is
assumed to begin the length specification.
- ## is a number that specifies the length of the field within
which justification should take place. This must be a number
between 1 and 240.
- If ## is less than the length of the un-justified output
string, then the un-justified output string will be truncated
to ## characters, starting at the point specified by the
justification type (i.e. at the right, left, or center of the
un-justified output string).
- /J"R08" will right-justify the output, padded
to the left with leading zeroes to a length of 8 characters.
- /J"C- 40" will center-justify the output in a field 40
characters long, with the justification being supplied of the
two characters "- ". Output will look something like this:
- - - - - - my output string - - - - - -
- /J"C-*-40" will center-justify the output in a field 40
characters long, with the justification being supplied of the
3 characters "-*-". Output will look something like this:
-*--*--*--*- my output string -*--*--*--*-
Note that when the pad string is more than one character, output
will be slightly unpredictable, as it will depend on the length of
the pad string, the length of the field in which the output is to
be justified, and the length of the (pre-justification) output
string.
SOME USES FOR THE /J PARM
(Most of these uses are illustrated in HOLIDAYS.BAT, which is included
in the Fdate distribution ZIP file.)
In conjunction with the "echo" function (/Fe), the /J parm can be used
to justify any value that you wish, not just output dates created by
Fdate. Put the value to be justified in the /Q parm. Put a title, for
example, as the value of the /Q parm, and specify center justification,
padded with spaces, to a length of 79 characters (/J"c 79"). This will
display the title, centered on the screen.
If you use the "echo" function and the /J parm, and specify the /Q parm
but do not specify a value for it, then only the pad character will be
displayed. (That is, the null string will be padded with the pad
character to the desired length.)
.EXAMPLE.....: This is a handy way to draw horizontal lines of dashes,
dots, or any other desired character.
Fdate /FE /Q /JC-79
The /J parm can be used to left-pad a number with zeroes.
.EXAMPLE.....: Many of Fdate's input formats require the year to be in
complete 4-digit CCYY format. If your batch file obtains a
value for YEAR from the user, the user might enter a YEAR
that is less than 1000. You can add leading zeroes to YEAR
by right justifying it, padded it with '0' to a length of 4.
Fdate /Fe /Q%year% /JR04 /vyear
Because /J can be used to truncate a string to a specified length, it
can be used to extract the rightmost, leftmost, or centermost ##
characters of a string.
.EXAMPLE.....: Fdate /Fe /J"C 79" /Q"SCREEN TITLE"
Fdate's output is not put into an environment variable, so it will be
displayed on the screen. This command will echo the string "SCREEN
TITLE" to the screen, centered in a field 79 characters long (that is,
centered on the screen), and padded to the left and right with blanks.
.EXAMPLE.....: Fdate /Fe /J"L.40" /Q"Next report due date" /Vtitle
Fdate /fadd /N60 /Od1 /Q"%title% "
The first command left-justifies "Next report due date" in a
string 40 characters wide, padded to the right with periods, and
puts it into the TITLE environment variable.
In the second step, the TITLE environment variable is used as
the label for a date 60 days in the future. In the second step,
note the space between the end of %title% and the trailing
double-quote. This leaves a nice space between the dot leader
and the date.
.EXAMPLE.....: For more examples, see HOLIDAYS.BAT.
Entry number 16 Table of Contents
.PARAMETER...: /L - Output Language
.CATEGORY....: parameters
.DISCUSSION..:
Fdate supports output in several different languages. The /L parm
specifies the language of output.
- /Lus US (American) English-language output [the default]
- /Lfr French-language output
- /Lgr German-language output
- /Lsp Spanish-language output
- /Ldk Danish-language output (requires codepage 850 to display correctly)
The /L parm affects the following predefined outputs. These
language-specific output formats produce the date/time in whatever is
the most common expression in the given language. The formats will vary
from language to language.
- full -- the full date and time, including the weekday
- 9:05 pm on Wednesday February 5, 1992
- 9:05 pm, mercredi le 5 fevrier 1992 [/Lfr specified]
- 9:05 pm, mircoles el 5 de febrero de 1992 [/Lsp specified]
- Mittwoch, 5. Februar 1992, 21:05 [/Lgr specified]
- d1 -- the full date, including the weekday
- Saturday, February 5, 1992
- samedi le 5 fevrier 1992 [/Lfr specified]
- Mittwoch, 5. Februar 1992 [/Lgr specified]
- t1 -- the time
- 9:05 am [/Lus specified]
- 21:05 [/Lgr specified]
The /L parm also affects components of custom output formats such
as the name of the weekday, and of the month.
Entry number 17 Table of Contents
.PARAMETER...: /O - Output Date Formats (pre-defined)
.CATEGORY....: parameters
.DISCUSSION..:
This set of fixed formats has been largely been replaced by the /C format
introduced in Fdate version 10. It is documented here for backward
compatibility, and some of the "canned" formats (e.g. /Ofull) that may still
be useful.
see PARAMETER /C - Custom Output Date Formats
For a list of the symbols used in specifying fixed date formats,
see APPENDIX Symbols used in Date Formats
.EXAMPLES....: FORMAT EXAMPLES COMMENTS
------ --------- -----------------------------
dd-mn3-yy 08-Feb-92 CompuServe-style date
yy 93 2-digit year number
ccyy 1993 4-digit year number (includes century)
ccyymm 199302 useful for triggering monthly processing
ccyymmdd 19930208 useful for putting current date in filename
yymmdd 930208 PKZIP's Japanese date format
mmdd 0208
mmddyy 020892 PKZIP's American date format
mmddccyy 02081992
mm 02 2-digit month number
zm 2 month number, no leading zeros
dd 08 2-digit day-of-month number
zd 8 day-of-month number, no leading zeros
IN THE FOLLOWING FORMATS, MONTHS PRECEDE DAYS (AMERICAN STYLE)
==================================================================
mm/dd/ccyy 02/08/1993
mm-dd-ccyy 02-08-1993
mm.dd.ccyy 02.08.1993 dot-separated format
zm/zd/ccyy 2/8/1993 no leading zeros in day or month
zm-zd-ccyy 2-8-1993 no leading zeros in day or month
zm.zd.ccyy 2.8.1993 dot-separated format
mm/dd/yy 02/08/92
mm-dd-yy 02-08-92
mm.dd.yy 02.08.92 dot-separated format
zm/zd/yy 2/8/92 no leading zeros in day or month
zm-zd-yy 2-8-92 no leading zeros in day or month
zm.zd.yy 2.8.92 no leading zeros in day or month
IN THE FOLLOWING FORMATS, DAYS PRECEDE MONTHS (EUROPEAN STYLE)
==================================================================
ddmmccyy 02081993
ddmmyy 020893PKZIP's European date format
dd/mm/ccyy 02/08/1993
dd-mm-ccyy 02-08-1993
dd.mm.ccyy 02.08.1993 dot-separated format
zd/zm/ccyy 2/8/1993 no leading zeros in day or month
zd-zm-ccyy 2-8-1993 no leading zeros in day or month
zd.zm.ccyy 2.8.1993 dot-separated format
dd/mm/yy 02/08/93
dd-mm-yy 02-08-93
dd.mm.yy 02.08.93 dot-separated format
zd/zm/yy 2/8/93 no leading zeros in day or month
zd-zm-yy 2-8-93 no leading zeros in day or month
zd.zm.yy 2.8.93 dot-separated format
DAY-OF-WEEK AND MONTH OUTPUT FORMATS
====================================
dow# 5 Sunday=1, Monday=2 .... Saturday=7.
dow Thursday name of day of week
jeudi if /Lfr specified
Donnerstag if /Lgr specified
dow3 Thu first 3 characters of name of day of week
jeu if /Lfr specified
Don if /Lgr specified
mn February name of month
fevrier if /Lfr specified
Februar if /Lgr specified
mn3 Feb first 3 characters of name of month
fev if /Lfr specified
Feb if /Lgr specified
LANGUAGE-SPECIFIC OUTPUT FORMATS
===============================================
These language-specific output formats produce the date/time in whatever is the most
common expression in the given language. The formats will vary from language to language.
full -- the full date and time, including the weekday
9:05 pm on Wednesday February 5, 1992
9:05 pm, mercredi le 5 fevrier 1992 [/Lfr specified]
9:05 pm, mircoles el 5 de febrero de 1992 [/Lsp specified]
Mittwoch, 5. Februar 1992, 21:05 [/Lgr specified]
d1 -- the full date, including the weekday
Saturday, February 5, 1992
samedi le 5 fevrier 1992 [/Lfr specified]
Mittwoch, 5. Februar 1992 [/Lgr specified]
t1 -- the time
9:05 am [/Lus specified]
21:05 [/Lgr specified]
MISCELLANEOUS OUTPUT FORMATS
============================
ddmn3yy 05Feb92
Also:
see PARAMETER /Oxxx - Extended Hex Output Date Format
-----------------------------------------------------------------------
NOTE that the following formats contain embedded spaces. Consequently
they must be enclosed in double quotes. EXAMPLE: /O"mn zd, ccyy".
-----------------------------------------------------------------------
"zd mn ccyy" 5 February 1992
"zd mn, ccyy" 5 February, 1992
"zd. mn ccyy" 5. February 1992 [German-style date format]
"zd. mn3 ccyy" 5. Feb 1992 [German-style date format]
"mn3 dd ccyy" Feb 05 1992
"mn3 dd, ccyy" Feb 05, 1992
"mn zd, ccyy" February 5, 1992
LEAP-YEAR FLAG OUTPUT FORMAT
============================
LY 0 "1" if date occurs in a leapyear, otherwise "0".
365 + this number gives total number of days in the year.
28 + this number gives total number of days in February.
TIME OUTPUT FORMATS
===================
For related information,
see PARAMETER /T - Time Override Parameter
tdos 9:05:10:10a format used in DOS's TIME command (in the United States)
9:05:10:10p
HH:MM 09:05 24-hour time, hours:minutes
21:05
HHMM 0905
2105
HH:MM:SS 21:05:30 24-hour time, hours:minutes:seconds
HHMMSS 210530
HH:MM:SS:CC 21:05:30:09 24-hour time, in
HHMMSSCC 21053009 hours:minutes:seconds:hundredths of seconds
BUSINESS JULIAN DATE OUTPUT FORMATS
===================================
These are formats for "business Julian" dates: dates expressed as the
number of days from the beginning of the year, when January 1 is day 1.
EXAMPLES:
DATE BUSINESS JULIAN DATE
----------- --------------------
Jan 5, 1993 93005
Dec 31, 1993 93365 [Dec 31 is 365th day of year 1993]
Dec 31, 1996 96366 [Dec 31 is 366th day, because 1996 is a leap year]
FORMAT EXAMPLES DISCUSSION
------ --------- -----------------------------
ccyyjjj 1992027 Jan 27, 1992
yyjjj 92027 "Business Julian" date expressed as number
jjj 027 of days since January 1 of the same year.
zzj 27 Note leading zero suppression in "zzj".
ABSOLUTE DATE/TIME OUTPUT FORMATS
=================================
For related information,
see PARAMETER /T - Time Override Parameter
month# 23927 "Absolute month": date expressed as number of
months since the beginning of the calendar.
Returns "1" for any date in January, 0001, "2"
for any date in February, 0001, etc.
day# 727198 "Absolute date": date expressed as number of
days since the beginning of the calendar.
Returns "1" for January 1, 0001, "2" for
January 2, 0001, etc.
minute# 33088 "Absolute minutes": time expressed as number
of minutes since midnight, January 1, 1990.
second# 633088 "Absolute seconds": time expressed as number
of seconds since midnight, January 1, 1990.
Running Fdate with /O parameter for an "absolute time" produces a
number based on the current time of day and the date in the /A parm.
If, on January 10, 1992 at 2 pm, you run Fdate this way:
Fdate /Ff /Atoday /Ominute#
it will produce the absolute minute for January 10, 1992 at 2 pm.
If, on January 10, 1992 at 2 pm, you run Fdate this way:
Fdate /Ff /A01-15-1992 /Imm-dd-ccyy /Ominute#
it will produce the absolute minute for January 15, 1992 at 2 pm.
Entry number 18 Table of Contents
.PARAMETER...: /Oxxx - Extended Hex Output Date Format
.CATEGORY....: parameters
.DISCUSSION..:
The "extended hex" output format is a pre-defined output format, represented as:
/Oxxx
This format represents dates for the years 1990-2024 in 3
characters of "extended hex" ("XX") notation. For more on XX
notation,
see FUNCTION #2Xx - Convert An Integer To Extended Hex Notation
The first character is the XX representation of the number of
years since 1990 (1990 = 0, 1991 = 1, etc.). If you attempt to
output a date outside of the 1990-2024 range in XXX format, Fdate
will report an error (i.e. return "ERROR" and errorlevel of 1).
The second and third characters contain the XX representation of
the month-number and day-of-month-number, respectively.
.EXAMPLES....: "1993 Feb 1" is represented as "321"
"2000 Dec 25" is represented as "ACP"
Entry number 19 Table of Contents
.PARAMETER...: /P - Output prefix
.CATEGORY....: parameters
.DISCUSSION..:
Supplying a value for the /P parameter prepends the value to the
Fdate output:
Example: On July 4, 2003
fdate /ff /oCCYY-MM-DD /p"Today is: "
produces
Today is: 2003-07-04
A common use for this feature is to help create a batch file that
sets an environment variable containing the Fdate output.
Fdate /ff /oCCYY-MM-DD /p"set date1" >junk1.bat
call junk1.bat
del junk1.bat
This feature was needed before the introduction of the /C (custom
output format). Since then, there is less need for it, although it
is still convenient for many purposes.
This is a companion parameter to the /S parameter.
Entry number 20 Table of Contents
.PARAMETER...: /S - Output suffix
.CATEGORY....: parameters
.DISCUSSION..:
Supplying a value for the /S parameter appends the value to the
Fdate output:
Example: On July 4, 2003
set num=3
fdate /ff /oCCYY-MM-DD /s" -- %num% backup files were generated today"
produces
2003-07-04 -- 3 backup files were generated today
This feature was needed before the introduction of the /C (custom
output format). Since then, there is less need for it, although it
is still convenient for many purposes.
This is a companion parameter to the /P parameter.
Entry number 21 Table of Contents
.PARAMETER...: /T - Time Override Parameter
.CATEGORY....: parameters
.DISCUSSION..:
You may override Fdate's use of the current time -- for the /A parameter only
-- by using the /T parameter. The /T parameter specifies a time of day in
the 24-hour format hh:mm:ss (hours:minutes:seconds). Leading zeros in each
of the three fields (hh, mm, ss) may be omitted. The seconds field may be
omitted; if omitted, it defaults to "00".
Note that the /T parm overrides the time portion of the /A date, but it does
NOT override the time portion of the /B date.
If, on January 10, 1992 at 2 pm, you run Fdate this way:
- Fdate /Ff /A01-15-1992 /Imm-dd-ccyy /Ominute# /T5:12
it will produce the absolute minute for January 15, 1992 at 5:12 am.
The most frequent and important use of the /T parm is with the format
function (/Ff) to obtain the "absolute" minute of a specific date and time.
Once we have the absolute minutes of two different date/times, we can easily
obtain the time between them (expressed in days, hours, and minutes) by using
Fdate's #dif, #idiv, and #mod functions. (In the EXAMPLES section, see the
example that contains FORATIME.BAT.)
It is also possible to use /T in conjunction with the time compare function
(/Ftcomp).
.EXAMPLE.....: @echo ON
cls
rem Since both /A and /B default to the current date and time,
rem and since /T parm overrides the time only for the /A parm ...
rem ... during daytime hours, this will always return LT
Fdate /Ftcomp /T00:00:00
rem ... during daytime hours, this will always return GT
Fdate /Ftcomp /T23:59:59
Entry number 22 Table of Contents
.FUNCTION....: #2Xx - Convert An Integer To Extended Hex Notation
.CATEGORY....: functions
.DISCUSSION..:
This function takes an integer supplied on parameter /A, and
returns a single character in extended hex (XX) notation.
- The input number must be an integer in the range of 0-35. A
number of less than 0 or larger than 35 is rejected as an error.
ABOUT EXTENDED HEX NOTATION
"Extended hexadecimal" (XX) notation uses all of the digits and
all of the letters of the alphabet to express numbers in the
range of 0 to 35 as a single character.
With extended hex, even the 31st day of a month can be expressed
as a single character (31 = V). So a monthly date can be expressed
as just two characters. October 31 is "AV".
.EXAMPLE.....: :: returns the letter "Z"
Fdate /F#2xx /A35
.TABLE.......: number: in XX is:
0 0
1 1
9 9
10 A
15 F
16 G
17 H
30 U
31 V
35 Z
Entry number 23 Table of Contents
.FUNCTION....: #Add - Add Two Numbers
.CATEGORY....: functions
.DISCUSSION..:
Add the integers specified on the /A and /B parms. To do
subtraction, add a negative number to a positive number.
Entry number 24 Table of Contents
.FUNCTION....: #Comp - Compare Numbers
.CATEGORY....: functions
.DISCUSSION..:
Fdate /F#comp /Anum /Bnum
#comp compares the integers specified on the /A and /B parms.
- returns "LT" when /A is less than (earlier than) /B
- returns "EQ" when /A is equal to (same as) /B
- returns "GT" when /A is greater than (later than) /B
In addition, the errorlevel is set to a special value:
- LT = 101
- EQ = 102
- GT = 103
Entry number 25 Table of Contents
.FUNCTION....: #Dif - Calculate The Difference Between Two Integers
.CATEGORY....: functions
.DISCUSSION..:
Returns the difference between the integers specified on the /A
and /B parms.
Entry number 26 Table of Contents
.FUNCTION....: #Div - Divide Two Numbers
.CATEGORY....: functions
.DISCUSSION..:
Divide the integer on the /A parm by the integer on the /B parm,
and return the result as a decimal number with two decimal
places.
Entry number 27 Table of Contents
.FUNCTION....: #Idiv - Integer Division Of Two Numbers
.CATEGORY....: functions
.DISCUSSION..:
Integer division. Divide the integer on the /A parm by the
integer on the /B parm, and return the result as an integer.
Entry number 28 Table of Contents
.FUNCTION....: #Mod - Modulus, Division Remainder
.CATEGORY....: functions
.DISCUSSION..:
Modulus. Divide the integer on the /A parm by the integer on the
/B parm, and return the remainder.
Entry number 29 Table of Contents
.FUNCTION....: #Mult - Multiply Two Numbers
.CATEGORY....: functions
.DISCUSSION..:
#mult
Multiply the integer on the /A parm by the integer on the /B
parm, and return the result.
Entry number 30 Table of Contents
.FUNCTION....: #Random - Produce A Random Number
.CATEGORY....: functions
.DISCUSSION..:
#RANDOM returns a random number between a lowerbound number and an
upperbound number.
More precisely, it returns a number X, where:
- lowerbound <= X <= upperbound
That is:
- if lowerbound is 3, and upperbound is 5, then #RANDOM will
randomly return 3, 4, or 5.
- if lowerbound is 999999997 and upperbound is 999999999, then #RANDOM will
randomly return 999999997, 999999998, and 999999999.
RESTRICTIONS
- The upperbound number is specified on the /A parm, and is required.
- The lowerbound number is specified on the /B parm, and is optional.
If omitted, it defaults to zero.
- Both upperbound and lowerbound numbers must be integers
- The lower bound cannot be less than zero.
- The upper bound must be greater than the lower bound.
- The upper bound cannot be greater than 999999999 (9 digits).
- The difference between the lower bound and the
upper bound cannot be more than 99999 (5 digits).
.EXAMPLE.....: @echo off
:: a batch file to demonstrate generation of a
:: random number between 3 and 10, and putting
:: it into an environment variable named RAND
Fdate /f#random /A10 /B3 /p"@set RAND=">junk.bat
call junk.bat
del junk.bat
echo Random number is %RAND%
:: use the RAND environment variable as you wish, here.
:: cleanup
set RAND=
Entry number 31 Table of Contents
.FUNCTION....: ADD a number of days to a date
.CATEGORY....: functions
.DISCUSSION..:
This function can be used to add N days to a date. Supplying a negative number for N
will subtract N days from the date.
The number of days should be specified on the /N parm. For example N90 for 90 days.
Numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
which means that Fdate can accept numbers up to 9 digits long.
.FORMAT......: Fdate /Fadd /Nnumdays /Adate /Iformat /Oformat
adds numdays to the date specified on the /A parm
and produces date in /Oformat format
.EXAMPLES....: Fdate /Fadd /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
Fdate /Fsub /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
Fdate /Fadd /N90 /Atoday /Od1
Entry number 32 Table of Contents
.FUNCTION....: Comp - Compare Dates
.CATEGORY....: functions
.DISCUSSION..:
Fdate /Fcomp /Adate /Bdate /Iformat
COMP compares the dates specified on the /A and /B parms (time
granularity = 1 day).
- returns "LT" when /A is less than (earlier than) /B
- returns "EQ" when /A is equal to (same as) /B
- returns "GT" when /A is greater than (later than) /B
In addition, the errorlevel is set to a special value:
- LT = 101
- EQ = 102
- GT = 103
Entry number 33 Table of Contents
.FUNCTION....: DIF - find the number of days between two dates
.CATEGORY....: functions
.DISCUSSION..:
Returns number of days between /Adate and /Bdate
The order of the two dates is not significant.
NOTE THAT
For DIF, both dates must be in the SAME format, the input format
specified in /Iformat. If the two dates are not in the same
format, you must first reformat one of the dates using the /Ff
function, then use DIF to get their difference.
.FORMAT......: Fdate /Fdif /Adate /Bdate /Iformat
.EXAMPLES....: Fdate /Fdif /A01-01-1992 /B11-11-1992 /Imm-dd-ccyy
Fdate /Fdif /A11-11-1992 /B01-01-1992 /Imm-dd-ccyy
Fdate /Fdif /Atoday /B01-01-1992 /Imm-dd-ccyy
Entry number 34 Table of Contents
.FUNCTION....: Echo - Output A String
.CATEGORY....: functions
.DISCUSSION..:
EXAMPLE: Fdate /Fe /P"My name" /q" is " /S"Sonny-boy Slim"
The ECHO function (/Fe) produces only the strings specified using the
/Q, /P, and /S parameters.
The /Fe function is mostly useful in conjunction with the /J (justify)
parm. Justification, if specified using the /J parm, is applied only to
the string, if any, supplied on the /Q parm.
see PARAMETER /J - Justifying Output
One nifty feature of /Fe (although one that will be of interest only to
extreme batch-file power users) is its ability, when used in conjunction
with /V, to put a character into an environment variable that the SET
command would not accept: characters such as an equal-sign "=" , the
redirection symbol ">", and the pipe symbol "|". However, as we move
into more advanced Windows environments (that is, NT and its
derivatives, Win2000 and XP), the /V parm will no longer work, and this nifty feature
will no longer be available.
Entry number 35 Table of Contents
.FUNCTION....: F - Output A Formatted Date
.CATEGORY....: functions
.DISCUSSION..:
FUNCTION Fdate /Ffunc /Adate /Iformat /Oformat
Since /Aformat and /Oformat can be different, the FORMAT
function is used to change a date from one format to another.
The date formatting function "f" (invoked as "/Ff")
returns /Adate in format specified by /Oformat
Because of the wide variety of output formats, the FORMAT
function can also be used to determine the day of week of the
ate, whether the date is in a normal or leap year, etc.
"format" is an obsolete, deprecated, synonym for this function.
.EXAMPLES....: Fdate /Ff /A19920101 /Iccyymmdd /O"mn zd, ccyy"
Fdate /Ff /Atoday /Od1
Fdate /Fformat /Atoday /Od1
Fdate /Ff /If /AFdate.exe /P"Fdate.EXE last updated: " /Ofull
Entry number 36 Table of Contents
.FUNCTION....: Get And Getu - Get User Input Functions
.CATEGORY....: functions
.DISCUSSION..:
These functions wait for the user to enter an input string, terminated
by a press of the ENTER key. Then Fdate simply produces that same
input string (or in the case of GETU, that input string in all upper
case) as its output.
GET == get user input (case is unchanged from what was entered)
GETU == get user input (uppercase)
- If the /Q prompt-string parameter is specified, then the prompt string
is displayed, but a NEWLINE is not written to the screen before
waiting for the user's input.
As with Fdate's other forms of output, this output can be displayed,
redirected to a file, or (if your environment supports Fdate's /V
parameter) placed into an environment variable.
FILTERING OF INPUT -- A FEATURE THAT Fdate DOES NOT PROVIDE
This "get" function provides no edit mask for input -- Fdate will
accept anything. The situation is helped by the fact that Fdate also
provides a validate function (/Fv) which can be used to validate the
user input, so that one can:
1. use /Fget to get user input and place it in an environment
variable
2. use /Fv to validate the date in the Evar
3. use the rest of the batch file to process the user input
See examples: "Get user input" and FORATIM2.BAT
For a program that provides more sophisticated functions for getting
user input in batch files (type checking, edit masks, etc.), I
recommend Bob Stephan's shareware program GET, which is described
elsewhere in this documentation.
Entry number 37 Table of Contents
.FUNCTION....: Getk (Get Keypress) Function
.CATEGORY....: functions
.DISCUSSION..:
The GETK function waits for the user to press an acceptable key, then
produces the key as its output. If the key pressed is a letter, then
the letter is returned IN UPPER CASE. This feature is designed to
support simple "pick a menu selection" processing in batch files.
The GETK function takes a /K "keymask" parameter that tells it which
keys to accept. If the user presses an unacceptable key (i.e. one
that is not in the keymask), the keypress is ignored.
If no /K parm is specified, the default keymask is:
ABCDEFGHIJKLMNOPQRSTUVWXYZx
That is, the default keymask will accept letters and the ESCAPE key.
SPECIFYING THE KEYMASK
NOTE THAT THE VALUES SPECIFIED ON THE /K PARM ARE CASE-SENSITIVE.
The keymask may contain numbers, uppercase letters, and any of the
other printable characters on the keyboard.
There is no way to tell Fdate to accept "special" keypresses such as
function keys, ALT or CONTROL keys, arrow keys, etc.
If the keymask contains an uppercase letter (e.g. "A"), and the user
presses the corresponding unshifted letter (e.g. "a"), then the
keypress will be accepted and the uppercase letter will be returned.
The keymask may contain the following lowercase letters, which have
special meanings:
- x represents the ESCAPE key
- e represents the ENTER (RETURN) key
- z [a place-holder character]
Lowercase "z" will be ignored when Fdate decides which
keypresses are acceptable. Its presence in the keymask will
affect the positions of other characters in the keymask, and
hence the ERRORLEVEL that Fdate returns when the user presses
an acceptable key. (For the uses of "z", see "GetK Results
also in ERRORLEVEL" and "Modifying the Keymask", below.)
All other lowercase letters are reserved for possible future use.
In the current release of Fdate, they are treated like lowercase
"z".
For example:
If a keymask of "/kXx" was specified, then if the user pressed the
(shifted or unshifted) "X" key, then uppercase "X" would be returned.
If he pressed the ESCAPE key, then lowercase "x" would be returned.
SPECIFYING HOW MANY SECONDS TO WAIT FOR A KEYPRESS
Starting with version 10, GETK takes a /W "seconds to wait" parameter
that tells it how many seconds to wait before returning the first key in
the /K "keymask" parameter. Valid values are in the range of 1..36000
(10 hours). Default value of /W is 36000 (10 hours).
GETK RESULTS ALSO IN ERRORLEVEL
When the GETK function returns a key, it sets the DOS errorlevel to a
value corresponding to the position of that key in the keymask. For
example, with keymask of "/kABx", if the user presses:
"A": value returned will be "A", errorlevel will be 1
"B": value returned will be "B", errorlevel will be 2
ESCAPE: value returned will be "x", errorlevel will be 3
If the user presses CONTROL+BREAK, Fdate will abort and return
errorlevel 255.
.EXAMPLE.....: @echo off
cls
echo Demonstration of Fdate's GETK (get keypress) function
echo Press CONTROL+BREAK to end
:top
echo.
Fdate /fGetK /P"You pressed: " /Q"Press a key: " /K"12ABxe "
if errorlevel 1 if not errorlevel 2 echo errorlevel : 1
if errorlevel 2 if not errorlevel 3 echo errorlevel : 2
if errorlevel 3 if not errorlevel 4 echo errorlevel : 3
if errorlevel 4 if not errorlevel 5 echo errorlevel : 4
if errorlevel 5 if not errorlevel 6 echo errorlevel : 5
if errorlevel 6 if not errorlevel 7 echo errorlevel : 6
if errorlevel 7 if not errorlevel 8 echo errorlevel : 7
if errorlevel 255 echo ERRORLEVEL 255
if errorlevel 255 goto endit
goto top
:endit
.DISCUSSION..:
Note that the keymask may contain blanks if the keymask is enclosed in
quotes (as in this example batch file). But remember that Fdate
eliminates redundant spaces when obtaining its parameter input, so you
should never include more than one blank in your keymask.
Modifying the Keymask
It is often necessary to make program modifications during the life of
a batch file. If you are using the GETK function and testing the
errorlevel rather than the environment, then the insertion or deletion
of characters into the existing keymask will change the errorlevels
returned by the following characters in the keymask. This will force
you to re-write the errorlevel tests, which may be a big job if the
keymask is long.
Here are some tips on how to avoid this work:
- When ADDING a character to the keymask, always add it at the END
of the keymask.
- When DELETING a character from the keymask, do not actually
delete it. Instead, replace it by a lowercase "z".
Displaying a User Prompt With GETK
The /Q (user prompt) parameter is especially handy when used in
conjunction with the GETK function. If the /Q prompt-string parameter
is specified (as in the example batch file, above), then the prompt
string is displayed, but a NEWLINE is not written to the screen before
waiting for the user's keypress.
For a program that provides more sophisticated "get key" functions for
batch files, I recommend Bob Stephan's shareware program GET, which is
described elsewhere in this documentation.
Entry number 38 Table of Contents
.FUNCTION....: Len (Length) Function
.CATEGORY....: functions
.DISCUSSION..:
The "len" function produces a number that is the length of the string on the /Q
parm.
For example:
Fdate /Flen /Q"this is a test"
returns 14
Entry number 39 Table of Contents
.FUNCTION....: M - Month Date Arithmetic
.CATEGORY....: functions
.DISCUSSION..:
Function name is "m" for "month arithmetic".
Here is an example:
Fdate /Fm /Nnumdays /Adate /Iformat /Oformat
This function adds /N months to /Adate, and produces a date in
/Oformat format. It can be used to do monthly subtraction by
making the number in the /N parameter a negative number.
.EXAMPLES....: Fdate /Fm /N1 /A03-15-1992 /Imm-dd-ccyy /Omm-dd-ccyy
produces: 04-15-1992
Fdate /Fm /N-1 /A03-30-1991 /Imm-dd-ccyy /Omm-dd-ccyy
produces: 02-28-1991
Fdate /Fm /N-1 /A03-30-1992 /Imm-dd-ccyy /Omm-dd-ccyy
produces: 02-29-1992
.DISCUSSION..:
Fdate's MONTH DATE ARITHMETIC IS SMART!
Month arithmetic that is done just by subtracting a certain number of
months can produce non-existent dates. For example, subtracting one
month from March 30, 1991 (as in the second example) could produce a
result of February 30, 1991, a date which cannot exist.
Fdate's month arithmetic is smarter than that. If Fdate finds that a
simple month-arithmetic operation produces an invalid date, it subtracts
the minimum number of days required to produce a valid date.
- In the second example, it produces February 28, 1991,
the last date in February, 1991.
- In the third example, it produces February 29, 1992
because 1992 is a leap year.
- Telling Fdate to add 12 months to February 29, 1992 produces a
result of February 28, 1993, since 1993 is not a leap year.
Problems with overly-simple date arithmetic are not merely academic.
Here is a passage from Peter G. Neumann's INSIDE RISKS column in
COMMUNICATIONS OF THE ACM, June 1992 (Vol. 35, No. 6). The column
title was "Leap-Year Problems":
- Prime Computer's MAGSAV failed at midnight [on Feb 29, 1992]... G. M.
Lack noted that MAGSAV probably failed on leap-day because it tried to
increment the year by one to set a tape label expiration date, and the
resulting nonexistent date of Feb 29, 1993 threw it for a loop.
Entry number 40 Table of Contents
.FUNCTION....: Substr (Substring) Function
.CATEGORY....: functions
.DISCUSSION..:
This function returns a substring of the string supplied in the /Q parm,
starting in the column supplied in the /A parm, for a length supplied in the
/B parm.
The start column specified in the /A parm may be a negative number; if it is,
then the start column is calculated from the end of the string rather than
from the beginning. This feature makes it easy to extract the rightmost
characters of a string.
Specifically, when the ParmA is negative, the start position is calculated
using the following formula:
- StartColumn = length(ParmQ) + 1 + ParmA
EXAMPLE....: Fdate /Fsubstr /A-2 /Qabcd
CALCULATION: StartColumn = length(ParmQ) + 1 + ParmA
StartColumn = 4 + 1 + (-2) = 3
- If /Q is omitted, Fdate reports an error.
- If /A is zero, Fdate reports an error.
- If /A is omitted, it defaults to 1 (that is, the start of the string).
- If /A is negative, and longer than the length of the string, then the
start column is 1 (the start of the string)
- If /B (length) is so great that it exceed the length of the /Q input
string, then only the remainder of the string is returned.
- If /B is zero, Fdate returns a null string.
- If /B is omitted, it defaults to 999.
.EXAMPLES....: Fdate /Fsubstr /A7 /B2 /Q"STEVE FERG" ===> "FE"
Fdate /Fsubstr /A7 /Q"STEVE FERG" ===> "FERG"
Fdate /Fsubstr /B5 /Q"STEVE FERG" ===> "STEVE"
.EXAMPLES....: using a negative start position Fdate /Fsubstr /a-6 /B3 /Q"1994 Jun 03" ===> "Jun
rem extract the rightmost 6 characters of a string
Fdate /Fsubstr /a-6 /Q"1994 Jun 03" ===> "Jun 03"
rem pad YEAR environment variable to the left with zeroes,
rem to make sure it is 4 bytes long
Fdate /Fsubstr /A-4 /q0000%year% /vyear
.DISCUSSION..:
REMEMBER that Fdate eliminates redundant spaces when obtaining its
parameter input:
Fdate /Fsubstr /A7 /Q"STEVE FERG" ===> "FERG"
Fdate /Fsubstr /A7 /Q"STEVE FERG" ===> "FERG"
Fdate /Fsubstr /A7 /Q"STEVE FERG" ===> "FERG"
Entry number 41 Table of Contents
.FUNCTION....: Tcomp - Compare Times
.CATEGORY....: functions
.DISCUSSION..:
Fdate /Ftcomp /Adate /Bdate /Iformat
TCOMP compares the times (time granularity = 1 second)
specified on the /A and /B parms.
This is useful when input format /If (file) is specified.
It can be used to compare the timestamps of two files and
determine which is older.
EXAMPLE
Fdate /Ftcomp /If /AFooBar.1 /Bfilezzz.1
- returns "LT" when /A is less than (earlier than) /B
- returns "EQ" when /A is equal to (same as) /B
- returns "GT" when /A is greater than (later than) /B
In addition, the errorlevel is set to a special value:
- LT = 101
- EQ = 102
- GT = 103
Entry number 42 Table of Contents
.FUNCTION....: Upper - Put A String Into Upper Case
.CATEGORY....: functions
.DISCUSSION..:
The UPPER function produces the string on the /Q parm, converted to upper case.
Entry number 43 Table of Contents
.FUNCTION....: V - Date Validation
.CATEGORY....: functions
.DISCUSSION..:
The date validation function is "V". It can be used by specify
that the function is to be validation: "/Fv".
If the date specified on the /A parm is valid, produces "" (the null
string). Otherwise, produces "ERROR" and a non-zero errorlevel by
triggering Fdate's error-handling function. (See the section on
Fdate's ERROR HANDLING, later in this documentation.)
When using the /Fv parameter, you will almost always want to check
success of the date validation by checking the errorlevel, and to
redirect Fdate's output to NUL (so that when it writes the null
string, it does not produce a blank line on your screen).
When processing an input date, Fdate does not reject all invalid
dates: specifically, it is very forgiving about the number in the day-
of-the-month part of input dates. It will accept, for example,
19931144 (November 44, 1993 in CCYYMMDD format) and process it quite
happily (as December 14, 1993). This is not a bug, it is a feature.
This feature provides one way (admittedly a crude one) of doing date
arithmetic. The date part (JJJ) of a Business Julian input date can
be used in the same way.
This feature can be a drawback, however, if you want to be sure that
some date (say a date that a user entered as an input parameter) is
valid. The /Fv function provides a way of completely checking a date
for validity. It will, for example, reject November 44, 1993 as
invalid.
Entry number 44 Table of Contents
.FUNCTION....: W - Weekday Date Arithmetic
.CATEGORY....: functions
.DISCUSSION..:
This function provides a way of doing date arithmetic in terms of
weeks rather than days.
Function name is "w" for "week arithmetic".
EXAMPLE: Fdate /Fw /Nnumdays /Adate /Iformat /Oformat
This function accepts a date specification in parm /A and
returns the date of the /Nth /Day-of-the-week
before or after /Adate. For example, if...
- /A specifies November 14, 1992
- /D specifies the number for Thursday (i.e., 5)
- /N specifies a week count of 3
then /Fw returns the date of the third Thursday after
November 14, 1992. (See full example, below)
NEGATIVE VALUES FOR /N
Note that /N may be negative. If, in the above example, /N
is specified as -3, then Fdate returns the date of the third
Thursday BEFORE November 14, 1992.
The acceptable values for /N (number of weeks) is in
the range of 99..-99. A value of zero (i.e. /N0) is invalid.
A BIT OF TRICKINESS WITH WEEKDAY ARITHMETIC
There is a small dilemma inherent in the notion of weekday arithmetic.
If the date specified on the /A parm falls on the same day of the week
(say, Thursday) as the day of the week that was specified on the /D
parm, should (or should not) the /A date be considered the first date
that meets the day-of-week criterion? For example, if day X is a
Thursday, and we specify that we want the first Thursday ("/N1 /D5")
from day X, should we get day X itself, or the Thursday that is 7 days
after day X?
Depending on what you're trying to do, one or the other kind of
behavior will be preferable. Starting with version 9.2, Fdate
supports both kind of processing. When using the weekday arithmetic
function (/Fw), you can determine the kind of processing that takes
place by specifying (or omitting) the /X (exclude) parm. That is, if
the date specified on the /A parm falls on the day of the week
specified on the /D parm, then...
IF THE /X PARM IS NOT PRESENT ...
- then the /A date will be considered to be the first date meeting the
day-of-week criterion. For example, suppose that /D specified
Thursday and /A specified Thursday, November 14, 1992. If /N was 1 or
-1, then the output date would be the same as the input date, i.e.
Thursday November 14, 1992.
IF THE /X PARM IS PRESENT ...
- then the /A date will be EXCLUDED from consideration when looking for
the first day to meet the day-of-week criterion. For example, suppose
that /D specified Thursday and /A specified Thursday November 14,
1992. If /N was 1, then the output date would be the following
Thursday, November 21, 1992. If /N was -1, then the output date would
be the preceding Thursday, November 7, 1992.
.EXAMPLES....: find date of Thanksgiving (4th Thursday in November) in 1992
Fdate /Fw /A11-01-1992 /Imm-dd-ccyy /D5 /N4 /Od1
returns: Thursday November 26, 1992
find the beginning of the work-week (Monday, 2nd day of week)
AFTER Thanksgiving, 1992
Fdate /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N1 /Od1
find the beginning of the work-week (Monday, 2nd day of week)
BEFORE Thanksgiving, 1992
Fdate /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N-1 /Od1
find last Friday's date (even if today is Friday)
Fdate /Fw /At /D6 /N-1 /X /P"Last Friday was: "
Entry number 45 Table of Contents
.TOPIC.......: Fdate's Century-Assumption Algorithm
.DISCUSSION..:
If an input date is supplied in a format in which the year is specified
without a century -- that is, as YY rather than CCYY -- then Fdate must
estimate which century the year is in.
Starting with version 9.8, Fdate does the following:
First, Fdate obtains the current year from the system clock. Then it looks
inside a 100-year window (which floats, based on the current year) to find a
two-digit year that matches the input year. When it finds it, it uses the
century of the year that it has found.
The boundaries of the window are calculated in the following way.
Let Y stand for the number of years that Fdate looks backward.
- The lower bound of the window is: current_year - Y
- The upper bound of the window is: lower_bound + 99
EXAMPLES
==========================================
If Y is 80, and the current year is 1999,
then the window extends from 1919 to 2018.
If Y is 80, and the current year is 2050,
then the window extends from 1970 to 2069.
If Y is 10, and the current year is 2000,
then the window extends from 1990 to 2089.
The default value of Y is 80. This value can be over-ridden by the /Y
parameter. /Y40, for example, would set Y to 40.
If specified, the /Y parameter must be an integer between 0 and 99.
Specifying /Y99 will cause Fdate to look only into the past. Specifying /Y0
will cause Fdate to look only into the future.
Note that this date-windowing algorithm is not "fixed". That is, it is not
tied to any particular year, and specifically it is not tied to the year
2000. The date window floats along with the current year. And because it
floats, it will produce reasonable results in the year 2000, 2050, 2100, and
even 3000.
Entry number 46 Table of Contents
.TOPIC.......: Fdate's Leap Year Algorithm
.DISCUSSION..:
Here is how Fdate decides whether or not a year is a leap year.
- Every year evenly divisible by 4 IS a leap year
- EXCEPT THAT
- Every year evenly divisible by 100 IS NOT a leap year
- EXCEPT THAT
- Every year evenly divisible by 400 IS a leap year.
Using this algorithm:
- 1983 is not a leap year
- 1984 is a leap year
- 1900 is not a leap year
- 2000 is a leap year
See "A Machine Algorithm for Processing Calendar Dates", by Henry F. Fliegel
(Georgetown University Observatory) and Thomas C. Van Flandern (U.S. Naval
Observatory) COMMUNICATIONS OF THE ACM, Volume 11, Number 10, October 1968
Entry number 47 Table of Contents
.TOPIC.......: Fdate's Support For Long Filenames
.DISCUSSION..:
Fdate, because it is a 16-bit application, does not support long filenames.
Entry number 48 Table of Contents
.TOPIC.......: How Fdate Thinks About Dates
.DISCUSSION..:
Also,
see Topic Fdate's Century-Assumption Algorithm
see Topic Fdate's Leap Year Algorithm
Fdate's BUSINESS VIEW OF THE CALENDAR
Fdate is intended for business applications, not historical ones.
Fdate does not take into account historical changes in the calendar such as
the eleven days that were dropped from the British calendar when Britain moved
from the Julian to the Gregorian calendar in the 18th century, or the 13 days
that were dropped from the Russian calendar when Russia made the same move in
the early 20th century.
As far as Fdate is concerned, the calendar has followed the same pattern,
unchanged, since January 1, 0001.
Fdate's BASE DATE
Internally, Fdate's date manipulations are based on translating a calendar
date into an "absolute" date: a date expressed as the
number of days from some day in the distant past.
- Fdate's base date is January 1, 0001 (i.e. day 1 of month 1 of year 1)
- Fdate's absolute date for January 1, 0001 is 1.
- Fdate's absolute date for January 1, 1992 is 727198.
Entry number 49 Table of Contents
.TOPIC.......: How To Put Fdate Output Into An Environment Variable
.DISCUSSION..:
CALL A BATCH FILE
The most basic way to put Fdate's output into an environment variable,
although not the most convenient, is to:
- use the /P (prefix string) feature to create a DOS "SET" statement,
- redirect the output to a batch file, and then
- CALL the batch file.
Fdate /Ff /Atoday /O"mn zd, ccyy" /P"@SET Fdate=" >JUNKTEMP.BAT
call JUNKTEMP.BAT
del JUNKTEMP.BAT
USE AN ENVIRONMENT-MANIPULATION UTILITY
There are shareware and freeware utilities that are written specifically
to manipulate environment variables. Fdate's output can be put into an
environment variable by piping it to one of these utilities.
For older, DOS-based systems, Bob Stephan's GET and PC Magazine's
STRINGS are excellent choices.
If you are running Windows NT, Windows 2000, or Windows XP,
see TOPIC Xset - A Utility For Creating Environment Variables Under NT, Win2k, XP
Fdate's /V PARAMETER
Starting with version 6.1, Fdate supports a /V (environment variable)
parameter. A user can use /V to tell Fdate to put its output directly
into an environment variable in the parent environment. For example:
Fdate /Ff /VDATE1
will set the environment variable DATE1 to the current date. If you type SET
at the DOS prompt, you should see something like:
DATE1=Friday February 14, 1992
If you specify /V without an evar name, the evar name defaults to Fdate.
Example : Fdate /Ff /V
produces: Fdate=Friday February 14, 1992
Fdate's /V PARAMETER CAN NOT ALWAYS BE USED
NOTE HOWEVER that the /V parameter WILL NOT WORK under Windows NT, Win2k, or XP.
see TOPIC Problem - /V Does Not Work Under NT, Windows2000, XP
There may be times when the /V parameter does not work under Win3x or Win9x.
Sometimes it is possible to correct these problem situations.
see TOPIC Problem - /V Does Not Work Under Win3X Or Win9X
In addition, due to the complexities of manipulating the environment,
there may be other circumstances on older machines where /V doesn't
work. These include running Fdate when you have shelled out to DOS from
another program, have put the command processor in upper memory (UMB),
are running under Carousel, etc. In such cases, you must use one of the
more basic techniques described above.
Entry number 50 Table of Contents
.TOPIC.......: Problem - /V Does Not Work Under NT, Windows2000, XP
.DISCUSSION..:
There are two problems that people commonly report when attempting
to run Fdate under Windows NT (and its derivatives, Win2000 and
Windows XP). One is that they run out of environment space. The
other is that the /V parm does not work, and Fdate's output is not
being put into an environment variable. These problems will apply
to all versions of NT, including NT 4.0, Window2000, and XP.
/V DOES NOT WORK
The bottom line is that Fdate's /V feature doesn't work under Windows
NT, 2k, or XP. Microsoft never made it easy to access the environment
programmatically, and the situation became worse in Windows NT, to the
point where TurboPower Software, which markets add-on utilities,
withdrew support for utilities that change environment variables. Since
Fdate uses these utilities, Fdate's /V feature will not work under NT, 2k, or XP.
This does not mean, however, that Fdate can't be used with those
operating systems. What it means is that we have to fall back on a
more basic method of setting an environment variable. This
involves creating a temporary batch file that sets the variable,
then running and deleting the batch file.
CALL A BATCH FILE
The most basic way to put Fdate's output into an environment variable,
is to:
- use the /P (prefix string) feature to create a DOS "SET" statement,
- redirect the output to a batch file, and then
- call the batch file.
Fdate /Ff /At /Occyymmdd /P"@SET Fdate=" >JUNKTEMP.BAT
call JUNKTEMP.BAT
del JUNKTEMP.BAT
In this example, the result will be that the Fdate environment variable
is set to today's date, in ccyymmdd format.
You might also want to investigate a utility called XSET.
see TOPIC Xset - A Utility For Creating Environment Variables Under NT, Win2k, XP
Entry number 51 Table of Contents
.TOPIC.......: Problem - /V Does Not Work Under Win3X Or Win9X
.DISCUSSION..:
"OUT OF ENVIRONMENT SPACE"
When you shell out to a DOS box under Windows, the size of the DOS
environment is normally limited to the amount actually in use by DOS at
the time when you first started Windows (rounded up to multiples of 16).
This does not give a subprocess any free space that it can use for its
own purposes, so when it tries to set an environment variable, you get
the "out of environment space" message. This is a problem that may
affect any process that runs in a "DOS box" under Windows, and sets an
environment variable.
The trick is to tell Windows that when it starts the
"DOS box" (COMMAND.COM), it should allocate a certain minimum
amount of memory for the environment, regardless of the amount
that is currently being used.
How to do it under NT, Windows2000, XP
/V will not work under NT, Windows2000, or XP.
see TOPIC Problem - /V Does Not Work Under NT, Windows2000, XP
How to do it under Win95
Select the shortcut icon that you use to start MS-DOS.
Rhex ight-click on it. When the pop-up menu appears, click on
PROPERTIES. When the properties for the shortcut come up, click
on the MEMORY tab. When the tab sheet is displayed, set a value
for INTITIAL ENVIRONMENT. I usually set it to 2048 (that is, 2K)
bytes. This will ensure that when DOS (COMMAND.COM) is started,
2K bytes are allocated to the environment.
Windows 3.1
The trick to giving yourself a decent amount of environment space in a
Windows DOS box, is to edit SYSTEM.INI and put the following line in the
[NonWindowsApp] section:
[NonWindowsApp]
CommandEnvSize=1024
This tip is from Brian Livingston's "Windows 3.1 Secrets", p. 225. According
to Livingston, "This command allocates 1,024 bytes of conventional memory to
the environment space of each DOS session you start. (You can choose any
value you want, but it should probably be a multiple of 16 bytes...)"
It's a good idea to be generous here, because the default prompt for a
Windows DOS box (the one with the highlighted bar across the top of the
screen) consumes a lot more environment space than the simple "$p$g" of the
conventional DOS prompt.
DOS or Windows 3.0 and earlier
An alternative technique, if you're running Windows 3.0 or earlier, is always
to start Windows from a batch file that contains the following line, executed
BEFORE you start Windows:
SET DUMMY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
This will reserve a chunk of environment space that will be copied into the
environment in the Windows DOS box. Then, as one of the first statements in
any batch file that you run under Windows, put
SET DUMMY=
This will free up the environment space used by all those "X"s.
For a good treatment of running DOS apps under Windows, including a
discussion of the environment, I recommend Brian Livingston's WINDOWS 3.1
SECRETS, chapter 7.
Using 4Dos, NDOS, And UMB
Aran Spence has reported circumstances in which Fdate /V will not set a
variable in the master environment. This report leads me to believe that
Fdate /V may also fail to work with MS-DOS if you put the command
processor or the environment in Upper Memory.
There are options with 4DOS and NDOS to load the environment and part of the
command processor into upper memory blocks. When one of these options is
used, Fdate /V can't find the environment and produces the message:
ERROR
@echo ERROR: Master environment not found
@pause
If you have a 4DOS.INI file, it has to contain these lines for Fdate /V to
work:
UMBEnvironment = No
UMBLoad = No
If you have NDOS, the SHELL statement in CONFIG.SYS cannot contain any
reference to UMB loading via /U (which puts NDOS.COM in UMB), nor can it
contain a statement of the form:
/E:xxxU
(which puts xxx bytes of the environment in UMB via the "U" parameter).
Also, NSTART.BTM or 4START.BTM cannot contain
SET NDSHELL=/e+xxxU /U
in which both U's represent UMB loading of the command processor and the
environment during secondary shells.
Entry number 52 Table of Contents
.TOPIC.......: Xset - A Utility For Creating Environment Variables Under NT, Win2k, XP
.DISCUSSION..:
XSET 5.29 : Extended SET Instruction
(C) 1991-1998 Stern Marc
Everything you always wanted to put in an environment variable
but were afraid to ask DOS, NT or OS/2 for . . .
XSET: The easy way to write efficient batch files.
XSET allows you to put EVERYTHING you want in a variable of
the current environment and use it as if you had assigned it the
value with the standard DOS command 'SET'. You will be able to
write very efficient batch files including string manipulation,
calculation, ...
XSET is the most powerful environment variable manipulation
program you have ever seen. It also has a very easy and intuitive
user interface (very close to the 'SET' command). It is not a
resident program; so it will not interfere with any of your
other applications.
XSET is fully compatible with MS-DOS (from 3.30), DR-DOS, NDOS,
4DOS, OS/2, Windows 95/98 and Windows NT.
XSET has seven major features:
- XSET permits you to catch the output of any command (internal or
external) or program and put it into an environment variable.
- XSET has built-in commands to modify the output of a program or a
string given on the command-line (extract a part of a string, ...)
- XSET has a built-in full floating-point calculation functionality:
You can program incremental loops, input a calculation string and
output the resulting number, ...
- XSET can manage variable contents of more than 128 characters (your
path can now be as long as you want).
- XSET has other built-in commands to give you access to some system
data (date, time, ...)
- XSET has built-in commands to clear the whole environment or restore
a previously saved one.
- XSET gives you access to high-level input/output user interface
(line-editing, colors, windows, boxes, ...).
WEB CONTACT INFO
xset.tripod.com
Entry number 53 Table of Contents
.TOPIC.......: Y2K - Is Fdate Y2K Compliant
.DISCUSSION..:
Starting in 1998, I began receiving frequent enquiries as to whether
Fdate is Y2K-compliant.
The short answer is:
- Yes. Fdate is Y2K compliant.
The long answer is:
- Fdate's whole purpose in life, from the very beginning, was to do
date handling and date arithmetic CORRECTLY. So Fdate has been Y2K
compliant from the very first version.
Note, however, that some of Fdate's functions (e.g. retrieving the
current date from the system clock, retrieving a file's
modification date) are dependent on the underlying platform
(hardware and operating system), which may or may not be Y2K
compliant. Fdate can be relied upon to behave in a Y2K-compliant
manner only if its underlying platform is Y2K compliant.
Fdate's YEAR-ASSUMPTION ALGORITHM, AND Y2K
Prior to version 9.8 Fdate used a "fixed" date-windowing algorithm
for dealing with 2-digit years.
if YY is greater than 20, then CC (the century) = 19
if YY is less than or equal 20, then CC = 20
This algorithm (like most Y2K date-windowing algorithms) is
date-dependent on the turn of the century that will occur in 2000.
I have developed a new algorithm that is independent of that date,
and it is the primary reason for the release of Fdate version 9.8
in March 1999. Starting with version 9.8 Fdate uses a "floating"
date-windowing algorithm for dealing with 2-digit years. This
algorithm will NEVER expire.
see TOPIC Fdate's Century-Assumption Algorithm
Entry number 54 Table of Contents
.APPENDIX....: Another Utility Named "Fdate"
.DISCUSSION..:
There is another shareware utility named Fdate in circulation, written by
Garrett A. Wollman. Mr. Wollman's Fdate is a kind of "touch" utility that
can be used to change a file's NAME (rather than its date/time stamp) to a
certain date. The Public Software Library in Houston distributes it under
the name Fdate.ZIP. PSL distributes my [Ferg's] Fdate under the name
FdateSF.ZIP.
As of April 1997, you can reach PSL by telephone (voice) at (713) 524-6394,
by Compuserve at 74777,3465, or by the Web at www.pslweb.com.
The most recent information I have is that Garrett Wollman can be reached at:
Garrett A. Wollman
7 Worcester Street
South Burlington, VT 05403
USA
...uunet!mimsy!aplcen!jhunix!gwollman
...uunet!uvm-gen!tnl!gwollman (summer)
gwollman@jhunix.hcf.jhu.edu
Both Fdates have been in circulation under the name Fdate.ZIP for too long to
make it practical to change the name of either one. All that can be done is
to warn you of a potentially confusing situation. If you see a file named
Fdate.ZIP, read the description of the file to determine which Fdate it is.
Checking the version numbers may also help-- as of April 1996, Ferg's Fdate
is in version 9.3; Mr. Wollman's Fdate is in version 1.2.
Entry number 55 Table of Contents
.APPENDIX....: Contents Of The Fdate.Zip Distribution File
.DISCUSSION..:
The current distribution package (Fdate.ZIP) contains the following:
- Fdate.EXE [the Fdate program]
- Fdate.TXT [this file, documentation for Fdate]
- EXAMPLES.TXT [examples of how to use Fdate]
- Fdate_NT.TXT [info about running Fdate under NT]
- !WARNING.TXT [Warning about a version 9.6 feature that
would break any existing Fdate statements
that used both /j and (/p or /s).]
[demonstration batch files]
- LANGUAGE.BAT [demonstrates formats in different languages]
- LANGTEST.BAT [used by LANGAUGE.BAT]
- CUSTOM.BAT [demonstrates custom output formats]
- HOLIDAYS.BAT
- HOLIFEDS.BAT and HOLIFEDS.TXT
[documentation files for use in BBS distribution]
Entry number 56 Table of Contents
.APPENDIX....: Fdate's Error Handling
.DISCUSSION..:
If Fdate detects an error:
(1) it will return an errorlevel of 1 (rather than 0), and
(2) its output will be 3 lines:
- the word ERROR
- a DOS batch-file ECHO statement that displays an error message
- a DOS batch-file PAUSE statement
If Fdate output is displayed directly, or redirected to NUL, you can detect
an error by testing the errorlevel for a value of 1.
If Fdate output is piped to an environment manipulation utility such as
STRINGS or GET, the environment variable will be set to ERROR. Errorlevel
will be set by STRINGS/GET, and will probably be 0. In such a case, the only
way to detect an error is to test the environment variable for the value
ERROR.
If Fdate output is redirected to a batch file, which is then CALLed to set an
environment variable, the batch file will:
- set the environment variable to ERROR,
- ECHO the error message, and
- pause.
You can detect an error by testing errorlevel for the value 1 either before
or after you CALL the batch file, or by testing the environment variable for
the value ERROR, AFTER you have CALLed the batch file.
.EXAMPLE.....: rem use Fdate to check validity of year in parm %1
Fdate /Fv /Imm-dd-ccyy /ATT-TT-%1 > nul
if errorlevel 1 echo Year parm [%1] is not valid.
if errorlevel 1 goto endit
.EXAMPLE.....: rem use GET with Fdate, to put Fdate output into %year%
Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy | GET ZE /V%year% >nul
if (%year%)==(ERROR) echo Year parm [%1] is not valid.
if (%year%)==(ERROR) goto endit
.EXAMPLE.....: rem use a batch file with Fdate, to put Fdate output into %year%
Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy /P"@set year=">junktemp.bat
call junktemp.bat
del junktemp.bat
if errorlevel 1 echo Year parm [%1] is not valid.
if errorlevel 1 goto endit
Entry number 57 Table of Contents
.APPENDIX....: Fdate's Implementation Limits
.DISCUSSION..:
Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
which means that Fdate can accept numbers up to 9 digits long.
Fdate is a 16-bit MS-DOS program, which means that it cannot handle long filenames.
Entry number 58 Table of Contents
.APPENDIX....: Revision History
.DISCUSSION..:
Letters appended to version numbers indicate modifications to
the doc files, without any modification to the Fdate.EXE software.
16a 2003 July 04
- Fixed a deficiency in Fdate's /C format: it provided no way to
obtain the 12-hour hour, or the the am/pm flag.
15a 2001 September 11
- BUG FIX -- The hour after midnight in AmPm format
was incorrectly displaying as "012" rather than as "12".
- BUG FIX -- Corrected the "t1" Danish and German output
format, so that the time shows the same way in the "t1"
output format as it does in the "full" output format -- as
24-hour time rather than am/pm time.
- BUG FIX -- The aa-fdate_documentation.html file was
accidentally omitted from the zip file containing the
html.documentation. Thanks to Harald Beck for reporting
this problem.
- DOCUMENTATION -- the "full", "d1" and "t1" output formats
are now clearly described as being language-specific.
- DOCUMENTATION -- Added an entry for the /L (language parm)
- DOCUMENTATION -- Updated the documentation for Example 63
(Run a program at a specified time later in the day)
so that it no longer uses STRINGS, which I think is not much
used any more. Thanks to Jason Filz for reporting this problem.
14d 2001 July 26
- In the documentation: grouped the examples involving files
together in examples 80+.
- Added the example developed for Steve Komosa.
14c 2001 Jun 21
- A few minor improvements in the formatting of the documentation.
14b 2001 Mar 21
- A few minor improvements in the formatting of the documentation.
14a 2000 Aug 28
- Fdate's documentation was converted to a dictionary format,
which can automatically be processed into HTML!
- Added the ability to specify a lower bound for the #random
function, on parm /B. If not specified, the lower-bound
defaults to zero. This preserves compatibility with earlier
versions of Fdate. Thanks to Mike Holley for pointing out
this limitation in Fdate.
- Corrected a bug in the #random function. It was returning
random numbers up to BUT NOT INCLUDING the upper-bound
specified on parm /A.
- Removed the HISTORY.TXT file from the distribution, because
it has been incorporated into the main documentation file.
- Removed the FDATEY2K.TXT file from the distribution, because
it has been incorporated into the main documentation file,
and nobody is interested in Y2K now that it has passed.
- Removed the FDATEBEG.TXT file from the distribution, because
it was obsolete. An updated version has been
incorporated into the main documentation file.
13a 2000 Aug 15
- Corrected a bug in the command-line parser, which was treating
parm-like strings -- even when they were enclosed in quotes --
as real parameters. Thanks to David Rothman for reporting
this bug.
- Corrected a bug in which the value for hundredths of a second
for a file timestamp was displaying as garbage characters
when using the custom output date.
Thanks to Knud Henrik Stromming for reporting this bug.
12a 1999 May 9
- Added support for UPPER for Danish (DK) language
- Support for multi-character pad string when using /J
- Various fixes to the documentation.
- Thanks (and a "/" through the "o" ) to Knud Henrik Stromming of
DSB Informatik in Copenhagen (Kopenhavn) for information
and help with these last two versions.
11a 1999 May 4
- added Danish (DK) language support. Note that this
requires use of codepage 850 to work properly.
10a 1999 Mar 27
- Added /C to provide free-form output, an improvement on /O
- Added /W (wait seconds) option for the GETK function
- The examples have been put into their own file: EXAMPLES.TXT
- Fdate revision history was moved to its own file: HISTORY.TXT
- Added CUSTOM.BAT and LANGUAGE.BAT to the distribution package
9.9a 1999 Mar 23
- When retrieving the date of a file, it is possible to specify a
filespec that contains wildcards. In earlier versions, if Fdate
found multiple files that matched the filespec it would return
the date/time information from the first file that it found that
met the filespec. Now, if Fdate finds more than one file that
matches the filespec, it will return an error message.
9.8a 1999 Mar 07
- Switched to a "floating" century-assumption algorithm
Added YYMMDD and YY-MM-DD input formats
9.7a 1997 Dec 01
- Corrected some minor bugs in the way error messages were formatted
- Updated my e-mail address to steve@ferg.org
9.6a 1997 April 22
- Fixed design flaw, in which justification was being applied to the
entire output string, including prefix string and suffix string.
Now, justification is applied BEFORE prefix and suffix strings are
added to output.
- This essentially broke the "ECHO" function /FE. So a /Q parm was
added to the echo function that permits it to still be used with
justification (the /J parm). Modified all of the /FE examples that
us justification, to show them working with the /Q parm rather than
with /P. Modified HOLIDAYS.BAT, which was affected by this change.
- Renamed all .DOC files to .TXT
- Added contact info for Garrett Wollman and PSL.
9.5a 1997 March 17
- Added #random function
- Added HHMMSSCC and HH:MM:SS:CC output formats
9.4b 1996 Jun 24
- Corrected minor bug in TIME_SET.BAT example.
9.4a 1996 Jun 10
- Added input formats DAY# and MINUTE#. This should enable a person
to use Fdate to produce an absolute date or minute (using the DAY#
or MINUTE# output format), manipulate it as he wishes (possibly in
ways not supported by Fdate), and then convert the result back into
a more readable format. Specifically, this should allow a person
to do "minute arithmetic" as well as "date arithmetic". Thanks to
Kevin Jackson, of the New York State Executive Chamber, who
reported the need to do time arithmetic.
- Added the MIN_MATH.BAT and TIME_SET.BAT examples.
- Added news about TurboPower's withdrawal of support for
environment-manipulating routines to documentation of /V parm under
Windows NT.
9.3a 1996 Apr 19
- Added output format mmddccyy.
- Added information on using Fdate with Windows NT.
- Added specific information on Garrett Wolman's Fdate.
9.2b 1996 Feb 1
- Rectified a minor documentation omission; I'd forgot to add /X to
the overview list of Fdate parms.
- Expanded FdateBEG.TXT by adding the overview of things you can do
with Fdate.
9.2a 1996 Jan 28
- Added /X (exclude) parm to /Fw (weekday arithmetic function).
- Added appropriate documentation, and examples :46 and :47. Thanks
to Richard Rogers for a real-life application that required this
feature.
9.1d 1995 Dec 08
- Added comments to example :67 (putting date into filename) and
changed output format to ccyymmdd. Hopefully, these changes will
make this popular example more useful and easier to understand.
9.1c 1995 Oct 22
- Added a usage example to the discussion of the "file" input format
(/If). Thanks to Bob Stephan for the suggestion.
9.1b 1995 June 12
- Corrected example of Japanese date format in this DOC file. Thanks
to Christopher Clark for pointing out the typo.
9.1a 1995 May 15
- Corrected bug that gave runtime error when function was #mult and
/A parm was 0.
9.0a 1995 Feb 20
- prefixed "@" to the "echo ERROR ... " and "pause" that are
generated when Fdate detects an error. This should make error
messages a bit easier to decipher.
8.9a 1995 Feb 15
- Added "absolute month" output format (/Omonth#)
- Added example YMD_DIF.BAT, which uses new /Omonth# facility
- Added FdateBEG.TXT to the distribution .ZIP file
8.8a November 06, 1994
- Changed error action in cases in which the prefix parm /P was
specified. In case of an error, the first line generated will
always be "ERROR". If prefix parm was specified, then a second
line will be generated with the prefix followed by "ERROR". Thus,
if output is being routed to a batch file, and the prefix is
something like "@set Fdate=", then that will continue to work.
- Removed the example of using /Fe to put equal-signs and redirection
symbols into the environment. I doubt if anyone found this example
useful.
- Added ability to break out of HELP using the ESC key
- Added justify parm (/J)
- Re-wrote HOLIDAYS.BAT to illustrate uses for /J.
8.7a October 27, 1994
- Added output format TDOS, which mimics the format used in the DOS
"time" command in the U.S. Added an example using it to the "roll your own"
date format example (:19) as example (a). Thanks for the request
for this common time format from Roy Zider.
8.6a October 27, 1994
- Corrected a bug in output format T1: HOUR value was being prefixed
by a leading zero if MINUTE value was less than 10.
8.5a September 28, 1994
- Added output date format "mmddyy" (PKZIP's "American" date format),
and an example showing how to use Fdate to get a date for use with
PKZIP for archiving files. Thanks for the tip on PKZIP's input
formats from Dick Jensen.
8.4c September 6, 1994
- Revised HOLIDAYS.BAT so it would not go into an infinite loop if
run on a system where Fdate cannot manipulate the environment, and
to pad the year to the left with zeroes, so years before 1000 will
be accepted.
- Added example showing how to left-pad a number with zeroes.
- Rewrote example showing how to time execution of a program.
- Updated my home mailing address after moving.
- Corrected information on how to make sure you have enough
environment space in a Windows DOS box. Thanks for the feedback
and on this issue from Ronny Richardson.
- Added WHATDAY.BAT (example :14). Thanks for the request from Cal
Pryluck, Radio-Television-Film, Temple University, Philadelphia
8.4b April 2, 1994
- Revised example :08, to use /fGetK rather than /fgetU
- Fixed formatting of #dif function
- Reformatted examples to reduce number of printed pages
- Duplicate example :07 was renumbered
- FORATIME.BAT (original version) removed as no longer interesting
- Modified JDATE.BAT to use new /Fget function
8.4a March 20, 1994
- Added GETK (get keypress) function
- Added ability to use /V when running in a Windows DOS box, thanks
to a Turbo Pascal routine from the Turbo Professional library
provided by Kim Kokkonen of TurboPower Software.
- Fixed a bug in which the prompt string (/Q) for the GET and GETU
functions was being written to redirectable output (StdOut). The
prompt string is now written directly to the screen, and will not
appear in Fdate's output when the output is redirected to a file.
- Removed ALARM.BAT, ALARM.DOC, TIC.BAT and TIC.DOC from distribution
package. They were too esoteric to be generally helpful.
- Added FILE_ID.DIZ and DESC.SDI to distribution package.
- Corrected algorithm for Mardi Gras in HOLIDAYS.BAT. Modified
HOLIDAYS.BAT and HOLIFEDS.BAT to make them more interactive, using
Fdate's new abilities to get user input.
- Started ZIPing Fdate.ZIP with PKZIP 2.04g rather than version 1.1
8.3a Feb 24, 1994
- Added the following string-handling functions:
- get (get user input)
- getu (get uppercase user input)
- upper (uppercase a string)
- len (length of a string)
- substr (substring)
- Added /F#2xx (convert number to extended hex format) function.
Deleted SETXX.BAT, which has been made obsolete with the addition
of this new function. Modified second example of storing a 4-digit
date to use #2xx instead of SETXX.BAT.
- Added output formats "ddmmccyy" and "ddmmyy" at the request of
several users.
- Added output format "xxx" after several requests for advice on how
to represent a large range of dates in a minimum number of bytes
(usually for constructing filenames from today's date).
- At the request of several users, enhanced the "compare" functions
(comp, tcomp, #comp) so they set distinctive errorlevels for their
different results. See the table of contents ("COMPARE-FUNCTION
ERRORLEVELS") and EXAMPLES.
- To discussion of /Fv parameter, added note about almost always
redirecting output to NUL when using /Fv.
- Revised FORATIME.BAT example batch file to make error-correction a
bit more robust and to add better documentation on how to use it.
- Added example batch files to use new functions, especially
FORATIM2.BAT which uses new "get" function
- Removed FdateX.BAT demonstration batch file from distribution
package, to reduce its size. The examples in this DOC file should
make the examples in FdateX.BAT unnecessary
8.2 August, 1993
- Removed FILEDATE.BAT from the distribution .ZIP file.
- Corrected the Spanish and French "full" and "d1" output formats.
Thanks for the information on Spanish and French date formats to
Gene J. Raymond, of GJR Software Products.
8.1 July 27, 1993 BUG FIX
- An error-trapping routine that was added to version 7.9 contained a
bug that caused Fdate's numeric math functions (#add, #dif, #mult,
#div, #idiv, #mod, #comp, etc.) to return incorrect results.
8.0 July, 1993
- Added "V" (validate) and "m" (month addition/subtraction) functions
- Added math functions: #mult #div #idiv
- Added /T (time) parameter
- Added FORATIME.BAT example, which Walter Ledge (assistant sysop of
CompuServe's CRFORUM) and I developed. A big thanks to Walt for
his feedback and help.
7.1a Apr 15, 1993
- Added German language support. Thanks for the request, and the
necessary information, from Patrick Schmucki, via the Active-Net
BBS in Rapperswil, Switzerland.
7.0a Nov 14, 1992
- Added #mod function
- Major reformatting of documentation to make it more user-friendly
Entry number 59 Table of Contents
.APPENDIX....: Symbols used in Date Formats
.DISCUSSION..:
The following symbols are used in specifying input (/I) and output
(/O) date formats:
SYMBOL EXAMPLE MEANING
------ ------- -------------------------------------
cc 19 century
yy 93 year
mm 02 month
zm 2 month without leading zero
dd 08 day
zd 8 day without leading zero
mn February month name
mn3 Feb month name, first 3 characters only
dow Tuesday day of week
dow3 Tue day of week, first 3 characters only
dow# 3 day of week as a number (Sunday=1, Monday = 2, etc.)
today is a "pseudodate" representing the current date
t is an alias for the "today" pseudodate
hh:mm 09:05 hours and minutes
hhmm 0905 hours and minutes
ss 13 seconds
PSEUDODATES
t (or today)
can be used with either /A or /B, e.g. /Atoday or /At.
This is the default for both /A and /B. That is, if /A is not
specified, /At is assumed, and the same for /B.
NOTE THAT "Today" as a date specification operates independently of any
input format. You need to specify an input format (either explicitly
via the /I parameter, or implicitly by accepting the default value of
/I) only for input dates that are supplied to Fdate in some other way
than via the "today" pseudodate: as a date literal, a filename, etc.
.EXAMPLES....: rem Get the date that is 90 days from today
Fdate /Fadd /N90 /Atoday /Omm-dd-ccyy
Fdate /Fadd /N90 /At /Omm-dd-ccyy
rem determine if this year is a leapyear
Fdate /Ff /At /OLY
tttt When used in place of a 4-digit CCYY string, "tttt"
will cause Fdate to use today's 4-digit year (CCYY).
tt When used in place of a 2-digit DD, MM, or YY string,
"tt" will cause Fdate to use today's day-of-the-month,
month, or 2-digit year, respectively.
Note that "tt" can NOT be used for the YY portion of a CCYY
input year. The following, for example, is NOT valid:
Fdate /Ff /Imm-dd-ccyy /A01-01-19tt /Od1
.EXAMPLES....: Fdate /Ff /Imm-dd-ccyy /A01-01-tttt
Fdate /Ff /Imm-dd-yy /A01-01-tt
rem report the 15th day of this month, this year
Fdate /Ff /Imm-dd-ccyy /Att-15-tttt
rem Show the first Monday in the second quarter of this year
Fdate /Fw /Iccyymmdd /Atttt0401 /D2 /N1 /P"First Monday in QTR#2: "
rem Show the last Friday on/before the 15th of this month.
Fdate /Fw /Iccyymmdd /Atttttt15 /D6 /N-1 /P"Friday before the 15th: "
Entry number 60 Table of Contents
.APPENDIX....: Technical Support For Fdate
.DISCUSSION..:
Send e-mail message to Stephen Ferg at
steve@ferg.org
When sending your message, please let me know what
version of Fdate you're using.
Entry number 61 Table of Contents
.APPENDIX....: Uploading Fdate To Electronic Bulletin Boards
.DISCUSSION..:
Feel free to post copies of the Fdate distribution file to any BBS that you wish.
Entry number 62 Table of Contents
.APPENDIX....: Use, Registration, And Distribution Of Fdate
.DISCUSSION..:
Fdate is freeware, or what is known as "zero-cost shareware". Fdate is not
what is technically called "public domain" software because the author
retains the copyright. Fdate can, however, be copied, used, and distributed
freely as long as Fdate.EXE and its associated documentation files
(Fdate.TXT, HISTORY.TXT, EXAMPLES.TXT) and demonstration batch files and doc
files (HOLIDAYS.BAT, HOLIFEDS.BAT, HOLIFEDS.TXT) are not altered and are
distributed together.
There is no requirement to register Fdate in any way.
Fdate can be included in shareware packages as long as both Fdate and its
related files are included in the shareware package.
If you have received Fdate as part of some larger shareware package, please
be aware that you may freely use, copy, and distribute Fdate without paying a
fee for, or registering, the larger package.
The author explicitly disavows any claim whatsoever about the correctness or
functionality of Fdate, its documentation, and its demonstration batch files,
and disclaims liability for anything and everything bad that might happen in
connection with, before, during, or after using it. I have tried to make
Fdate work right, but everybody makes mistakes, so you use Fdate at your own
risk.
Entry number 63 Table of Contents
.APPENDIX....: Where To Find The Most Current Version Of Fdate
.DISCUSSION..:
For many years, up until 1999, one was always be able to find the
most recent version of Fdate on CompuServe. The filename was
Fdate.ZIP, and it was available in the CIS:IBMSYS forum (library
1, the "DOS Utilities" library).
However, more recently, the best way to find the most recent version
of Fdate is on Steve Ferg's home page
www.ferg.org
If this doesn't work, you can contact me directly via e-mail at
steve@ferg.org
Entry number 64 Table of Contents
.EXAMPLE.....: 01 Display Fdate output on screen
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: FDATE /Ff /At /Od1 /P"Today is "
Entry number 65 Table of Contents
.EXAMPLE.....: 02 Redirect FDATE output to a file
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: FDATE /Ff /At /Od1 /P"Today is " >FDATE.OUT
Entry number 66 Table of Contents
.EXAMPLE.....: 03 Put FDATE output in an environment variable using a batch file
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET DATE1=" >JUNKTEMP.BAT
call JUNKTEMP.BAT
del JUNKTEMP.BAT
Entry number 67 Table of Contents
.EXAMPLE.....: 04 Put FDATE output in an environment variable using /V parm
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: FDATE /Ff /Atoday /O"mn zd, ccyy" /Vdate1
Entry number 68 Table of Contents
.EXAMPLE.....: 05 Put FDATE output in an environment variable using STRINGS
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: FDATE /Ff /Atoday /O"mn zd, ccyy" |STRINGS date1= ASK >NUL
Entry number 69 Table of Contents
.EXAMPLE.....: 06 Put FDATE output in an environment variable using GET
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: FDATE /Ff /Atoday /O"mn zd, ccyy" |GET ZE /Vdate1 >NUL
Entry number 70 Table of Contents
.EXAMPLE.....: 07 Get user input
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
cls
echo Enter a date in mm-dd-ccyy format for validation
:: get user input
Fdate /fget /vUserDate1
:: validate user input using /Fv (validate function)
Fdate /fv /A%UserDate1% >nul
if errorlevel 1 echo Invalid date: %UserDate1%
if errorlevel 1 goto endit
:: put your batch file processing here ...
echo Processing date: %UserDate1%
:endit
:: cleanup
set UserDate1=
Entry number 71 Table of Contents
.EXAMPLE.....: 08 Get a user menu selection
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
:START
cls
echo ===========================================================
echo MAKE A MENU SELECTION
echo ===========================================================
echo A DIR *.*
echo B DIR *.BAT
echo.
echo Press ESC to exit
echo.
echo ===========================================================
FDATE /FgetK /Q"Press letter of your choice> " /KABx /V
if (%FDATE%)==(A) goto Choice_%FDATE%
if (%FDATE%)==(B) goto Choice_%FDATE%
if (%FDATE%)==(x) goto endit
echo Program logic error. Invalid choice [%FDATE%]
pause
goto Start
:CHOICE_A
cls
echo Processing choice %FDATE% ...
DIR *.* /W /P
pause
goto Start
:CHOICE_B
echo Processing choice %FDATE% ...
DIR *.BAT /W /P
pause
goto Start
:endit
set choice=
cls
Entry number 72 Table of Contents
.EXAMPLE.....: 09 Change a date from one format into another
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: :: change date from mm-dd-yy format to ccyymmdd format
FDATE /Ff /Imm-dd-yy /A05-08-92 /Occyymmdd
Entry number 73 Table of Contents
.EXAMPLE.....: 10 Find the difference in days between two dates
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: FDATE /Fdif /Imm-dd-ccyy /A%date1% /B%date2% /vdif
echo The difference is %dif% days.
Entry number 74 Table of Contents
.EXAMPLE.....: 11 Find the elapsed days/hours/minutes between two date/times.
.CATEGORY....: examples
.DISCUSSION..:
This batch file was developed in cooperation with Walter Ledge, a sysop for
CompuServe's CRFORUM. In addition to being a good example of how to use
Fdate's /T parm and "#idiv" function, it should be useful for other
CompuServe sysops who need to submit the same reports that Walt does.
Here's Walt's message that started the whole thing.
- As an assistant sysop on the CRFORUM, I have to submit reports to CIS on
the number of messages that are posted on our forum in terms of time per
1,000 messages -- i.e., say, I know that 1,000 messages were posted
between the hours of 17:05 on July 5 and 3:03 on July 7. I need to know
how many hours and minutes it took for those 1000 messages to be posted.
So I would like some way to use FDATE to calculate the difference
between those two times (which, of course, include the dates).
FORATIM2.BAT is an improvement of the original FORATIME.BAT batch file.
FORATIM2.BAT uses the /Fget function, which first appeared in Fdate 8.3, to
get user input from the terminal, rather than requiring all parameters to
be entered at the command line as FORATIME.BAT did.
.CODE........: @echo off
cls
:: ------------------------------------------------------
:: FORATIM2.BAT batch file
::
:: FUNCTION
:: Calculate the elapsed time (in days and minutes)
:: between some "begin" date/time and some "end" date/time
::
:: ------------------------------------------------------
echo --------------------------------------------------------------
echo Calculate elapsed time between two date/times
echo --------------------------------------------------------------
:BegDate
Fdate /Fget /VBEGdate /Q"Enter BEGIN DATE (mm-dd-ccyy): "
if (%BegDate%)==() goto Cleanup
:BegTime
Fdate /Fget /VBEGtime /Q"Enter BEGIN TIME (hh:mm).....: "
if (%BegTime%)==() goto Cleanup
:: validate date & time
Fdate /fv /A%BEGdate% /T%BEGtime% >nul
if errorlevel 1 echo Invalid date/time
if errorlevel 1 goto BegDate
:: get absolute minute of start date/time.
Fdate /Ff /ominute# /A%BEGdate% /T%BEGtime% /VABStime1
if errorlevel 1 goto BegTime
Fdate /Ff /Ofull /A%BEGdate% /T%BEGtime% /Vfull1
::
echo.
:EndDate
Fdate /Fget /VENDdate /Q"Enter END.. DATE (mm-dd-ccyy): "
if (%EndDate%)==() goto Cleanup
:EndTime
Fdate /Fget /VENDtime /Q"Enter END.. TIME (hh:mm).....: "
if (%EndTime%)==() goto Cleanup
:: validate date & time
Fdate /fv /A%ENDdate% /T%ENDtime% >nul
if errorlevel 1 echo Invalid date/time
if errorlevel 1 goto EndDate
:: get absolute minute of end date/time.
Fdate /Ff /ominute# /A%ENDdate% /T%ENDtime% /VABStime2
if errorlevel 1 goto EndTime
Fdate /Ff /Ofull /A%ENDdate% /T%ENDtime% /Vfull2
echo.
echo Calculating elapsed time...
:: calculate the difference between ABStime1 and ABStime2
Fdate /f#dif /A%ABStime1% /B%ABStime2% /VMinutes
:: calculate the number of hours in it took
Fdate /f#Idiv /A%minutes% /B60 /VHours
:: calculate the number of extra minutes it took
Fdate /f#mod /A%minutes% /B60 /VMins
echo.
echo Between %full1%
echo and %full2%
echo.
echo Elapsed time was:
echo %hours% hours and %mins% minutes
Fdate /f#Idiv /A%minutes% /B1440 /Vday1
Fdate /f#mod /A%minutes% /B1440 /Vmin1
Fdate /f#Idiv /A%min1% /B60 /Vhour1
Fdate /f#mod /A%min1% /B60 /Vmin2
echo or
echo %day1% day(s) %hour1% hour(s) and %min2% minute(s).
echo.
echo.
:cleanup
set ENDdate=
set BEGdate=
set BEGtime=
set ENDtime=
set full1=
set full2=
set minutes=
set ABStime1=
set ABStime2=
set day1=
set hour1=
set min1=
set min2=
set mins=
set hours=
:endit
Entry number 75 Table of Contents
.EXAMPLE.....: 13 Find the elapsed years/months/days between two dates.
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
:: illustrate Fdate's Month# output format
cls
echo --------------------------------------------------------------
echo YMD_DIF.BAT Calculate elapsed time between two dates
echo --------------------------------------------------------------
:: --------------------------------------------------------------
:D1
Fdate /Fget /VD1 /Q"Enter date #1 (mm-dd-ccyy), or ENTER to quit: "
if (%D1%)==() goto Cleanup
:: validate date
Fdate /Fv /A%D1% >nul
if errorlevel 1 echo Invalid date
if errorlevel 1 goto D1
:: translate date into various formats, including absolute month
Fdate /Ff /oMonth# /A%D1% /VAbsMonth1
Fdate /Ff /oday# /A%D1% /VAbsDay1
Fdate /Ff /A%D1% /VFull1
Fdate /Ff /odd /A%D1% /VDd1
:: --------------------------------------------------------------
:D2
Fdate /Fget /VD2 /Q"Enter date #2 (mm-dd-ccyy), or ENTER to quit: "
echo.
if (%D2%)==() goto Cleanup
:: validate date
Fdate /Fv /A%D2% >nul
if errorlevel 1 echo Invalid date
if errorlevel 1 goto D2
:: translate date
Fdate /Ff /oMonth# /A%D2% /VAbsMonth2
Fdate /Ff /oday# /A%D2% /VAbsDay2
Fdate /Ff /A%D2% /VFull2
Fdate /Ff /odd /A%D2% /VDd2
:: --------------------------------------------------------------
:: verify that D2 is later than D1
Fdate /Fcomp /A%D2% /B%D1% /v
if (%Fdate%)==(GT) goto EndIf1
echo D2 must be later than D1. Please try again.
echo.
goto D1
:EndIf1
:: verify that D2 is in a later month than D1
Fdate /F#comp /A%AbsMonth2% /B%Absmonth1% /v
if (%Fdate%)==(GT) goto EndIf2
:: they are in the same month
Fdate /Fdif /A%D1% /B%D2% /P"Difference is " /S" days."
echo.
goto Cleanup
:EndIf2
:: --------------------------------------------------------------
:: get difference in months
Fdate /F#dif /A%AbsMonth2% /B%Absmonth1% /vMonthsDif
:: compare days of month
Fdate /F#comp /A%Dd2% /B%Dd1% /v
if not (%Fdate%)==(LT) goto EndIf3
:: Dd2 is less than Dd1 ... subtract 1 from (add -1 to) MonthsDif
Fdate /F#add /A%MonthsDif% /B-1 /VMonthsDif
:EndIf3
:: do month arithmetic, to get a date (D3) that is
:: less than 1 month prior to D2
Fdate /Fm /A%D1% /N%MonthsDif% /Omm-dd-ccyy /VD3
:: find difference in days between D3 & D2
Fdate /Fdif /A%D3% /B%D2% /Vdaysdif
:: --------------------------------------------------------------
echo Between %Full1% & %Full2% ...
echo %MonthsDif% month(s) %DaysDif% day(s)
:: calculate the number of years, by dividing MonthsDif by 12
Fdate /F#Idiv /A%Monthsdif% /B12 /VYearsDif
:: calculate the number of extra months
Fdate /F#mod /A%MonthsDif% /B12 /VMonthsDif
echo or %YearsDif% year(s) %MonthsDif% month(s) %DaysDif% day(s)
:: --------------------------------------------------------------
:cleanup
echo.
echo.
set D1=
set D2=
set D3=
set AbsMonth1=
set AbsMonth2=
set AbsDay1=
set AbsDay2=
set Full1=
set Full2=
set Dd1=
set Dd2=
set YearsDif=
set MonthsDif=
set DaysDif=
set Fdate=
:endit
Entry number 76 Table of Contents
.EXAMPLE.....: 14 Determine how long it took a program to run
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
cls
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo DETERMINE HOW LONG IT TOOK A PROGRAM TO RUN
echo The demo will run for 1 - 60 seconds.
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PAUSE
cls
:: Get the time (in Julian seconds) that the program began running
set PgmName=DemoFake_Pgm
FDATE /Ff /Osecond# /VBegS
FDATE /Ff /Ohh:mm:ss /P"%PgmName% execution begins at "
:: ~~~~~~~~~ DEMO BEGIN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: For purposes of this demo, we simulate execution of a
:: program by looping until the minute changes. In your real
:: batch file, you would put your program statements here.
:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FDATE /Ff /Ohhmm /vBegM
:BegLoop
rem Since this is a demo, give the folks something to watch
FDATE /Ff /Osecond# /vSeconds
FDATE /F#dif /A%Seconds% /B%BegS% /P".... elapsed time: " /S" seconds."
FDATE /Ff /Ohhmm /vNowM
if (%NowM%)==(%BegM%) goto BegLoop
set BegM=
set NowM=
:: ~~~~~~~~~ DEMO END ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: Get the time (in Julian seconds) that the program finished
FDATE /Ff /Osecond# /vEndS
:: tell the user the time that the program finished
FDATE /Ff /Ohh:mm:ss /P"%PgmName% execution ends at "
:: calculate run time (difference between start time and end time)
FDATE /F#dif /A%EndS% /B%BegS% /vSeconds
:: convert seconds to minutes + seconds format
FDATE /F#idiv /A%Seconds% /B60 /vMinutes
FDATE /F#mod /A%Seconds% /B60 /vMinSecs
:: tell the user how long the program took to run
echo Runtime: %Seconds% seconds (%Minutes% minutes %MinSecs% seconds)
:: cleanup
set PgmName=
set BegS=
set EndS=
set Seconds=
set Minutes=
set MinSecs=
Entry number 77 Table of Contents
.EXAMPLE.....: 15 Find years when a given date fell on a given day of the week
.CATEGORY....: examples
.DISCUSSION..:
This program has virtually no data validation, but if you are
careful to enter valid input data, it does the job.
This program calculates the years (within a specified range) that a
certain day of a certain month fell on a certain day of the week.
Note that we calculate and test both the day of the week and the month.
This is because, for example, "February 29" of a non-leapyear (an
invalid date) will be converted to the valid date of March 1. So we
want to be sure that in a given year, February 29 not only occurred on
the weekday in question, but also actually occurred in February.
.CODE........: @echo off
cls
echo This program calculates the years (within a specified range) that a
echo certain day of a certain month fell on a certain day of the week.
echo.
echo Please enter the day of the week that you want to search for.
echo 1 = Sunday
echo 2 = Monday
echo 3 = Tuesday
echo 4 = Wednesday
echo 5 = Thursday
echo 6 = Friday
echo 7 = Saturday
echo.
Fdate /FgetK /K1234567x /Q"Please press a number, or ESC to exit > " /vdow
if (%Dow%)==(x) goto endit
if (%Dow%)==(1) set DowName=Sunday
if (%Dow%)==(2) set DowName=Monday
if (%Dow%)==(3) set DowName=Tuesday
if (%Dow%)==(4) set DowName=Wednesday
if (%Dow%)==(5) set DowName=Thursday
if (%Dow%)==(6) set DowName=Friday
if (%Dow%)==(7) set DowName=Saturday
echo You chose day of the week: %dowName%
pause
Fdate /fget /Q"Please enter first year in year range > " /vBegYr
Fdate /fget /Q"Please enter last_ year in year range > " /vEndYr
Fdate /fget /Q"Please enter month number (1-12) > " /vMonNum
Fdate /fget /Q"Please enter day__ number (1-31) > " /vDayNum
set Yr=%BegYr%
Fdate /Fsubstr /a-2 /q00%MonNum% /vMonNum
REM >whatday.txt
cls
echo Looking for %MonNum%/%DayNum% on %DowName%
echo between %BegYr% and %EndYr%
echo ----------------------------------------------
echo Looking for %MonNum%/%DayNum% on %DowName% >>whatday.txt
echo between %BegYr% and %EndYr% >>whatday.txt
echo ---------------------------------------------- >>whatday.txt
:LoopTop
Fdate /Fsubstr /a-4 /q0000%yr% /vyr
echo Testing %yr%
Fdate /Ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /v
Fdate /Ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /odow# /vdow#
Fdate /Ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /omm /vmm
if (%Dow#%)==(%Dow%) if (%MonNum%)==(%mm%) echo %fdate%
if (%Dow#%)==(%Dow%) if (%MonNum%)==(%mm%) echo %fdate% >>Whatday.txt
Fdate /f#add /A%yr% /B1 /vYr
Fdate /F#comp /A%yr% /B%EndYr% /v
if (%fdate%)==(GT) goto LoopEnd
goto LoopTop
:LoopEnd
cls
type whatday.txt
echo.
echo This data has been written to file: Whatday.txt
echo.
:endit
set Yr=
set BegYr=
set EndYr=
set mm=
set Dow=
set Dow#=
set DowName=
set Fdate=
set MonNum=
set DayNum=
Entry number 78 Table of Contents
.EXAMPLE.....: 16 Find calendar date corresponding to a "business Julian" date
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: :: business Julian date is 1992:045. Note input format CCYYjjj
FDATE /Ff /A1992045 /Iccyyjjj /Od1
:: You don't need to left-zero-fill the day
FDATE /Ff /A199245 /Iccyyjjj /Od1
:: You can assume the century, if you specify the YYjjj input format
FDATE /Ff /A9245 /Iyyjjj /Od1
Entry number 79 Table of Contents
.EXAMPLE.....: 17 Set your PC's date to a business Julian date
.CATEGORY....: examples
.DISCUSSION..:
This batch file was created by Aran Spence [CIS: 70162,3044]. Its
function is to emulate the DOS DATE command, but allow the user to set
the date using a business Julian date format (yyjjj) instead of
mm-dd-yy.
Note the format is YYjjj. This is the BUSINESS Julian date: a date
expressed as the number of days from the beginning of the year,
when January 1 is day 1.
date BUSINESS Julian date
----------- --------------------
Jan 5, 1992 92005
Jan 5, 1993 93005
Dec 31, 1993 93365 [Dec 31 is 365th day of year 1993]
As Aran originally wrote it, the user-prompt was virtually identical to
that of the DATE command. I have modified his original version, so it
now looks less like the DATE command but displays a bit more
information, and so it can operate from the command line.
If the user enters a business Julian date as a command-line
parameter, JDATE resets the date to that Julian date.
EXAMPLE: JDATE 92005
If there is no input parameter, /fget is used to prompt the user for a
date.
Note that the user must enter both of the year digits (yy),
but may enter an abbreviated set of day digits (jjj). That is,
for Julian day 92005, the user is permitted to enter 925.
One handy use for JDATE is simply to find out what the current
business Julian date is.
.CODE........: @echo off
SET NewJD=%1
if not (%NewJD%)==() goto GotDate
:ShowDate
Fdate /Ff /Od1 /P"Current Gregorian date: "
Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
:GetDate
GET S "Enter new date (yyddd): " /VNewJD /L
if (%NewJD%)==() goto endit
:GotDate
Fdate /Ff /A%NewJD% /Omm-dd-yy /Iyyjjj /VNewGD
if errorlevel 1 echo Invalid date "%NewJD%"
if errorlevel 1 goto GetDate
:: reset the date
DATE %NewGD%
echo SYSTEM DATE HAS BEEN RESET
Fdate /Ff /Od1 /P"Current Gregorian date: "
Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
:endit
SET NewJD=
SET NewGD=
echo.
Entry number 80 Table of Contents
.EXAMPLE.....: 18 Determine if parm %1 contains a valid date
.CATEGORY....: examples
.DISCUSSION..:
Note that we throw away the FDATE output by redirecting it to NUL. All
we really want here is the errorlevel, which tells us whether or not the
string in %1 is a valid year.
.CODE........: Fdate /Fv /Imm-dd-ccyy /A%1 >nul
if errorlevel 1 echo Parm 1 was not a valid date: %1
if errorlevel 1 goto endit
::
:: Put the body of your batch file here.
::
:endit
Entry number 81 Table of Contents
.EXAMPLE.....: 19 "Roll your own" date format
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo of
cls
:: EXAMPLE A: create a date in the format of the DOS "date" command
:: format, followed by the DOS "time" command format
:: get the three-character day-of-week name
Fdate /Ff /Odow3 /Vx
:: add mm-dd-ccyy to it
Fdate /Ff /Omm-dd-ccyy /p"%x% " /Vx
:: add the DOS "time" format (new output format in Fdate 8.6)
Fdate /Ff /Otdos /p"%x% " /Vx
echo Date/time = %x%
:: EXAMPLE B: create a date in custom-made format: yymn3dd
Fdate /Ff /Oyy /Vx
Fdate /Ff /Omn3 /P"%x%" /Vx
Fdate /Ff /Odd /P"%x%" /Vx
echo Today is %x%
:: EXAMPLE C: create a date with day and month date-parts right justified
:: and padded with spaces, such as " 1- 1-1995" for Jan 1, 1995
Fdate /Ff /ozd /j"R 2" /vzd
Fdate /Ff /ozm /j"R 2" /vzm
Fdate /Ff /occyy /p"%zd%-%zm%-" /v
echo Today is [%fdate%]
Entry number 82 Table of Contents
.EXAMPLE.....: 20 Find the 4th Thursday in November (Thanksgiving)
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: Fdate /Fw /D5 /N4 /A11-01-%year% /Imm-dd-ccyy /Od1 /P"Thanksgiving: "
Entry number 83 Table of Contents
.EXAMPLE.....: 22 On a date, show what anniversary it is for some event
.CATEGORY....: examples
.DISCUSSION..:
See HOLIDAYS.BAT demo batch file
.CODE........:
Entry number 84 Table of Contents
.EXAMPLE.....: 23 Show a list of holidays in a given year
.CATEGORY....: examples
.DISCUSSION..:
See HOLIDAYS.BAT demo batch file
.CODE........:
Entry number 85 Table of Contents
.EXAMPLE.....: 24 Show a list of Federal holidays in a given year
.CATEGORY....: examples
.DISCUSSION..:
See HOLIFEDS.BAT demo batch file
.CODE........:
Entry number 86 Table of Contents
.EXAMPLE.....: 25 Determine if a year is valid, and evenly divisible by 4
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
cls
echo FUNCTION: Accept a year parm (CCYY) as parameter 1. Determine if
echo the year is an election or inauguration year in the United States.
echo ===================================================================
:: verify %1 is a valid year
Fdate /Fv /Imm-dd-ccyy /A01-01-%1 >nul
if errorlevel 1 echo Year parm [%1] is not valid.
if errorlevel 1 goto endit
Fdate /Ff /Imm-dd-ccyy /A01-01-%1 /p"@set year=">junktemp.bat
call junktemp.bat
Fdate /F#mod /A%1 /B4 /p"@set mod=">junktemp.bat
call junktemp.bat
if (%mod%)==(0) echo %1 is an American presidential election year.
if (%mod%)==(1) echo %1 is an American presidential inauguration year.
for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an election year.
for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an inauguration year.
set mod=
:endit
if exist junktemp.bat del junktemp.bat
Entry number 87 Table of Contents
.EXAMPLE.....: 30 Find the date 1 month, 3 months, 1 year from today
.CATEGORY....: examples
.DISCUSSION..:
This example uses Fdate's month-arithmetic function: /Fm.
The /N parm specifies the number of months that we want to add to the
date specified on the /A parm. Note that we can specify a negative
number on the /N parm, which will return a date which is the number of
months BEFORE the date on the /A parm.
In the last example, we find the date one year after February 29, 2004,
which is a leap year. Note that Fdate does NOT return February 29, 2005,
which is a non-existent date.
.CODE........: @ECHO OFF
echo.
set months=1
FDATE /Fm /At /N%months% /p"set date2=" > junk.bat
call junk.bat
del junk.bat
Echo %months% month(s) from today is %date2%
:: Show month arithmetic
set months=-1
FDATE /Fm /At /N%months% /p"set date2=" > junk.bat
call junk.bat
del junk.bat
Echo %months% month(s) from today is %date2%
echo.
set months=3
FDATE /Fm /At /N%months% /p"set date2=" > junk.bat
call junk.bat
del junk.bat
Echo %months% month(s) from today is %date2%
set months=12
FDATE /Fm /At /N%months% /p"set date2=" > junk.bat
call junk.bat
del junk.bat
Echo One year from today is %date2%
echo.
set date1=2004-02-29
set months=12
FDATE /Fm /A%date1% /Iccyy-mm-dd /N%months% /p"set date2=" > junk.bat
call junk.bat
del junk.bat
Echo %months% month(s) from %date1% is %date2%
::cleanup
SET DATE1=
SET DATE2=
Entry number 88 Table of Contents
.EXAMPLE.....: 33 MIN_MATH.BAT -- "time arithmetic" in minutes
.CATEGORY....: examples
.DISCUSSION..:
MIN_MATH.BAT -- Add or subtract time, in minutes, from the present
We get number of minutes from parm1, if present. otherwise, we use
a default of 4 minutes.
Note that Minutes can contain a negative number, if we wish to
subtract some minutes
.CODE........: @echo off
cls
set Minutes=4
if not (%1)==() set Minutes=%1
:: get the absolute minute NOW
:: Alternatively, you can use the /A parm and the /T parm
:: to start from the date and time of your choice.
Fdate /Ff /ominute# /vAbsMin
:: add a certain number of minutes
Fdate /f#add /a%AbsMin% /b%Minutes% /VNewMin
:: display the results
Fdate /Ff /iminute# /Ofull /a%AbsMin% /p"We add %Minutes% minutes to "
Fdate /Ff /iminute# /Ofull /a%NewMin% /p"producing: "
set Minutes=
set AbsMin=
set NewMin=
echo.
:endit
Entry number 89 Table of Contents
.EXAMPLE.....: 34 TIME_SET.BAT -- "time arithmetic" -- set TIME
.CATEGORY....: examples
.DISCUSSION..:
Advance the time by 3 hours, then set it back again
.CODE........: @echo off
set Minutes=180
cls
FDATE /FF /Ofull /P"It is now "
:: get the absolute minutes now
Fdate /Ff /ominute# /vAbsMin
:: add a certain number of minutes
Fdate /f#add /a%AbsMin% /b%Minutes% /VNewMin
:: reset the time and date
Fdate /Ff /a%NewMin% /Iminute# /omm-dd-yy /vdate
Fdate /Ff /a%NewMin% /Iminute# /ohh:mm /vtime
time %time%
date %date%
echo %Minutes% minutes added...
FDATE /FF /Ofull /P"It is now "
echo.
echo DOING SOME WORK ...
echo.
FDATE /FF /Ofull /P"It is now "
:: get the absolute minutes now
Fdate /Ff /ominute# /vAbsMin
:: subtract (add negative) a certain number of minutes
Fdate /f#add /a%AbsMin% /b-%Minutes% /VNewMin
:: reset the time and date
Fdate /Ff /a%NewMin% /Iminute# /omm-dd-yy /vdate
Fdate /Ff /a%NewMin% /Iminute# /ohh:mm /vtime
time %time%
date %date%
echo %Minutes% minutes subtracted ...
FDATE /FF /Ofull /P"It is now "
set Minutes=
set AbsMin=
set NewMin=
set time=
set date=
echo.
:endit
Entry number 90 Table of Contents
.EXAMPLE.....: 42 Get date to tell PKZIP to compress files older than 30 days
.CATEGORY....: examples
.DISCUSSION..:
PKZIP (a popular file-compression utility) can be used to compress and
archive files that are older/younger than a given date. To run PKZIP on
files that are, for example, older than 30 days, we need the date that was
30 days before today's date. To get it, we use Fdate to subtract 30 days
from today's date, and put that date out in PKZIP's "American" format
(MMDDYY). (Fdate also supports PKZIP's Japanese and European formats.)
The example code compress all files that were created before a date 30 days ago.
For more information, see PKZIP's MANUAL.DOC file.
.CODE........: Fdate /Fsub /N30 /Ommddyy /VArchiveDate
pkzip test.zip -T%ArchiveDate%
Entry number 91 Table of Contents
.EXAMPLE.....: 43 Loop through an array of environment variables
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
cls
SET pct=%%%
SET prefix=Address
echo LOADING AN ARRAY
SET subscript=1
SET %prefix%.%subscript%=Stephen Ferg
SET subscript=2
SET %prefix%.%subscript%=5113 N. 8th Road
SET subscript=3
SET %prefix%.%subscript%=Arlington, VA 22205
echo UNLOADING AND DISPLAYING THE ARRAY
SET subscript=1
:LoopTop
:: do while subscript less than/equal 3
if %subscript%==4 goto LoopEnd
REM put value of subscripted variable into tempvar
ECHO SET tempvar=%pct%%prefix%.%subscript%%pct%>JUNKTEMP.BAT
CALL JUNKTEMP.BAT
REM display value of subscripted variable
ECHO %prefix%.%subscript% is: %tempvar%
REM delete subscripted variable
SET %prefix%.%subscript%=
REM increment the loop variable
Fdate /F#add /A%subscript% /B1 /Vsubscript
goto LoopTop
:LoopEnd
SET pct=
SET tempvar=
SET prefix=
SET subscript=
DEL JUNKTEMP.BAT
Entry number 92 Table of Contents
.EXAMPLE.....: 44 Do something on the last day (or last Friday) of the month
.CATEGORY....: examples
.DISCUSSION..:
We often need batch files that do some special task on the last day of the
month: run a backup job, display a reminder message, etc. This example
batch file, LASTDAY.BAT, simply displays a message -- you can modify it to
do whatever it is that YOU want to do.
If you plan to run LASTDAY.BAT at work, and you work Monday through Friday,
then checking for the last day of the month would be a poor strategy --
after you leave work on a Friday, the last day of the month might occur on
the following Saturday or Sunday. So I've included a check to see if the
Friday is the last working day of the month. If you don't want that
functionality, deleting the lines between the first and last occurrence of
the string "EndCheck" will remove it.
.CODE........: @echo off
:: ---------------------------------------------------------------
:: check to see if today is the last day of the month
:: ---------------------------------------------------------------
:: get today's month
Fdate /Ff /omm /vmmtoday
:: get tomorrow's month
Fdate /fadd /n1 /omm /vmmtomorrow
:: if tomorrow occurs in a different month,
:: then today is the last day of this month
if not (%mmtoday%)==(%mmtomorrow%) echo LAST DAY OF THE MONTH
if not (%mmtoday%)==(%mmtomorrow%) goto EndCheck
:: -------------------------------------------------------------
:: check to see if today is the last Friday of the month
:: -------------------------------------------------------------
:: get today's day of the week, to see if it is Friday
Fdate /Ff /odow3 /vdow3
if not (%dow3%)==(Fri) goto EndCheck
:: today is Friday. Get next Monday's month
Fdate /fadd /n3 /omm /vmmMonday
:: if next Monday occurs in a different month,
:: then today is the last Friday of this month
if not (%mmtoday%)==(%mmMonday%) echo LAST WORKING DAY OF THE MONTH
:EndCheck
:: cleanup
set dow3=
set mmtoday=
set mmtomorrow=
set mmMonday=
Entry number 93 Table of Contents
.EXAMPLE.....: 45 Get information about the month prior to the current month
.CATEGORY....: examples
.DISCUSSION..:
When running a monthly backup job at the beginning of the month, one often
needs to identify the previous month, or the last day of the previous
month. Here's how to use Fdate to obtain that sort of information.
Basically, we subtract one day from the first day of the current month,
giving us the last day of the previous month.
.CODE........: @echo off
cls
:: ---------------------------------------------------------------------
:: The simplest way to get information about last month is to subtract
:: 1 day from the first day of this month ...
:: ---------------------------------------------------------------------
Fdate /Fsub /n1 /att-01-tttt /omm /p"Last month was.................: "
Fdate /Fsub /n1 /att-01-tttt /occyy /p"Last month occurred in the year: "
Fdate /Fsub /n1 /att-01-tttt /odd /p"The last day of last month was : "
Fdate /Fsub /n1 /att-01-tttt /od1 /p"The last day of last month was : "
Entry number 94 Table of Contents
.EXAMPLE.....: 46 Show the last Monday (or any other weekday) in this month
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
cls
:: Use monthly arithmetic to get first day of next month
Fdate /fm /n1 /att-01-tttt /omm-dd-ccyy /v
:: get the preceding Monday, i.e. the last Monday in this month
Fdate /Fw /d2 /n-1 /x /a%fdate%
Entry number 95 Table of Contents
.EXAMPLE.....: 47 Show the last Monday in the month, for a series of months
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
cls
:: initialize constants
set StartDate=01-01-1996
set MONTHS=15
echo Show the last Mondays in the month,
echo for the %months% months starting %StartDate%
echo ==============================================================
set COUNT=1
:LOOPTOP
:: compare COUNT to MONTHS, exit loop if COUNT exceeds MONTHS
FDATE /F#comp /A%COUNT% /B%MONTHS% /vCOMP
if (%COMP%)==(GT) goto ENDLOOP
:: Use monthly arithmetic to get first day of next month
FDATE /Fm /N%COUNT% /A%StartDate% /Omm-dd-ccyy /VFdate
:: get the preceding Monday (/D2) -- the last Monday in this month
FDATE /Fw /D2 /N-1 /X /A%fdate% /P"%count% "
:: increment COUNT
FDATE /F#add /A%COUNT% /B1 /Vcount
GOTO LOOPTOP
:ENDLOOP
echo.
:endit
set StartDate=
set MONTHS=
set COUNT=
set COMP=
set FDATE=
Entry number 96 Table of Contents
.EXAMPLE.....: 50 Represent a date in 3 bytes of "extended hex" notation
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: :: produce today's date as 3 bytes
Fdate /Ff /oxxx
:: produce yesterday's date in xxx format
Fdate /Fsub /N1 /oxxx
Entry number 97 Table of Contents
.EXAMPLE.....: 51 Represent a date in a short (4-byte) format (technique #1)
.CATEGORY....: examples
.DISCUSSION..:
A common use of Fdate is to format today's date and use it to rename a file
(typically a log file of some sort). You may wish to store the date
information in as few characters as possible, in order to maximize the
number of other characters in the filename that you can use to store other
information.
In this example, and the next one, I illustrate two ways to store a date in
4 bytes.
The simplest way is to represent today's date as a 4-digit number.
To do this, we first pick a base date: I'll use January 1, 1990.
Then it is a simple matter to calculate the number of days between today
and the base date:
FDATE /Fdif /at /b01-01-1990
Starting in 1993, this will always generate a 4-digit number, and will
continue to do so for 20 years, until approximately the year 2003. Dates
before 1993 may produce 1-, 2-, or 3-digit numbers, and dates after 2003
will begin to produce 5-digit numbers. But this technique will work quite
nicely for most ordinary purposes for the next 20 years.
In the year 2003 you can switch to using January 1, 2000 as your base
date and function quite nicely for the next 20 years after that.
.CODE........:
Entry number 98 Table of Contents
.EXAMPLE.....: 52 Represent a date in a short (4-byte) format (technique #2)
.CATEGORY....: examples
.DISCUSSION..:
This batch file shows how to use Fdate's #2XX function to
obtain and represent today's date in 4 characters, YYMD, where:
- YY is the year (e.g. "93" for 1993)
- M is the month in extended hexadecimal (XX) notation
- D is the day-of-the-month in extended hexadecimal (XX) notation
You can also use Fdate's "XXX" output format to represent dates between
1990 and 2024 in 3 bytes of extended hex notation.
.CODE........: @echo off
cls
:: OBTAIN 1-CHARACTER REPRESENTATION FOR THE MONTH
Fdate /Ff /Omm /Vmm
Fdate /f#2xx /A%mm% /Vmm
echo XX representation of this month's number is %mm%
:: OBTAIN 1-CHARACTER REPRESENTATION FOR THE DAY
Fdate /Ff /Odd /Vdd
Fdate /f#2xx /A%dd% /Vdd
echo XX representation of today's day of the month is %dd%
:: CONCATENATE THEM TO THE 2-CHARACTER REPRESENTATION FOR THE YEAR
Fdate /Ff /Oyy /S%mm%%dd% /Vdate
echo XX representation of today's full date is %date%
:: CLEANUP
set mm=
set dd=
set date=
:endit
Entry number 99 Table of Contents
.EXAMPLE.....: 53 Convert numbers to "extended hex" (XX) format
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
cls
SET decnum=0
:top
if (%decnum%)==(37) goto endit
Fdate /f#2xx /A%decnum% /P"XX representation of %decnum% is "
Fdate /f#add /A%decnum% /b1 /Vdecnum
goto top
:endit
Entry number 100 Table of Contents
.EXAMPLE.....: 54 Customize Fdate for a language of your choice
.CATEGORY....: examples
.DISCUSSION..:
You can use Fdate with a customized batch file to obtain the names of
the days of the week and the months in a language of your choice. Or
you could use it to obtain names in uppercase, or the first 5
characters of the names (rather than the first three), or some other
customized formatting of your choice.)
I've invented a language called Fergian, which has its own names for
the days of the week, and the months. In the following examples, I
invoke FERGIAN.BAT to make the translation. The text of FERGIAN.BAT,
which does the real work here, is given in the next example.
.CODE........: @echo off
cls
Fdate /Ff /omm /v
call Fergian mm- result %Fdate%
echo Month is %result%
Fdate /Ff /omm /v
call Fergian mm3 result %Fdate%
echo Month3 is %result%
Fdate /Ff /odow# /v
call Fergian dw- result %Fdate%
echo Day of week is %result%
Fdate /Ff /odow# /v
call Fergian dw3 result %Fdate%
echo Day of week3 is %result%
:: cleanup
set Fdate=
set result=
Entry number 101 Table of Contents
.EXAMPLE.....: 55 Fergian.BAT (used in the previous example)
.CATEGORY....: examples
.DISCUSSION..:
This batch file converts a month number, or day of the week number,
to a name in the FERGIAN language.
You can copy this batch file and customize it, to make it translate
into some other language of your choice.
This batch file expects the following parameters:
- %1 contains the type of number you want to convert:
- MM- if you want the entire name of the month
- MM3 if you want the first 3 letters of the name of the month
- DW- if you want the entire name of the day of the week
- DW3 if you want the first 3 letters of the name of the day of the week
- %2 contains the name of the environment variable that you
want to use to hold the result
- %3 contains the number that you want to convert
.CODE........: @echo off
set %2=
goto %1
:MM-
if (%3)==(01) set %2=Jaded
if (%3)==(02) set %2=Febrile
if (%3)==(03) set %2=Martial
if (%3)==(04) set %2=Abigail
if (%3)==(05) set %2=Maybelene
if (%3)==(06) set %2=Junkaroo
if (%3)==(07) set %2=Julia
if (%3)==(08) set %2=Augmentation
if (%3)==(09) set %2=Separation
if (%3)==(10) set %2=Ostentation
if (%3)==(11) set %2=Novelty
if (%3)==(12) set %2=Decadence
goto endit
:MM3
if (%3)==(01) set %2=Jad
if (%3)==(02) set %2=Feb
if (%3)==(03) set %2=Mar
if (%3)==(04) set %2=Abi
if (%3)==(05) set %2=May
if (%3)==(06) set %2=Jun
if (%3)==(07) set %2=Jul
if (%3)==(08) set %2=Aug
if (%3)==(09) set %2=Sep
if (%3)==(10) set %2=Ost
if (%3)==(11) set %2=Nov
if (%3)==(12) set %2=Dec
goto endit
:DW-
if (%3)==(1) set %2=SunDay
if (%3)==(2) set %2=MoonDay
if (%3)==(3) set %2=TwickasDay
if (%3)==(4) set %2=WodensDay
if (%3)==(5) set %2=ThorsDay
if (%3)==(6) set %2=FreyasDay
if (%3)==(7) set %2=SaturnDay
goto endit
:DW3
if (%3)==(1) set %2=Sun
if (%3)==(2) set %2=Moo
if (%3)==(3) set %2=Twi
if (%3)==(4) set %2=Wod
if (%3)==(5) set %2=Tho
if (%3)==(6) set %2=Fre
if (%3)==(7) set %2=Sat
goto endit
:endit
Entry number 102 Table of Contents
.EXAMPLE.....: 61 DO-ONCE: Run apps when booting for the first time of the day
.CATEGORY....: examples
.DISCUSSION..:
Put this code in AUTOEXEC.BAT.
.CODE........: if not exist C:\LASTRUN.BAT goto RunNow
:: call LASTRUN.BAT, which will set an environment variable, %LASTRUN%,
:: that will contain the date when this batch file was last run.
:: ------------------------------------------------------------------
call C:\LASTRUN.BAT
:: compare the date in %LASTRUN% to today's date
:: ------------------------------------------------------------------
Fdate /Fcomp /At /B%LastRun% /Vcomp
:: Today's date may be less than %LASTRUN% if you reset the system clock
IF (%COMP%)==(LT) goto NoRun
:: If %LASTRUN% was the same as today's date,
:: then this batch file has already been run once today
IF (%COMP%)==(EQ) goto NoRun
:: Daily processing hasn't been run today. Run it.
:: ------------------------------------------------------------------
:: Here, you should put the batch-file body --
:: the code to run the applications that you want to run once per day
:: ------------------------------------------------------------------
:: ------------------------------------------------------------------
:: Save today's date in a new version of LastRun.BAT. Note that
:: this code will be executed only if daily processing runs to
:: completion without hanging the machine or aborting the batch file.
:: ------------------------------------------------------------------
Fdate /Ff /Omm-dd-ccyy /At /P"@set LastRun=">LastRun.BAT
:NoRun
set LastRun=
set COMP=
Entry number 103 Table of Contents
.EXAMPLE.....: 62 Run specific software, depending on the day of the week
.CATEGORY....: examples
.DISCUSSION..:
This is a very common use for Fdate. I use it to load an alarm-clock TSR
(Terminate and Stay Resident, "memory resident", program) that beeps at me
(at different times on different days of the week) to remind me that it is
time to attend a meeting that is regularly scheduled for that day of the
week.
Note that stuff for a given day of the week will be executed every time you
boot up on that day of the week. If you want stuff (e.g. a backup job) to
be run only once (the first time you boot up) on a given day of the week,
then:
- (1) copy the code from DO-ONCE (the previous example) into your
AUTOEXEC.BAT file, then
- (2) copy this code into the body of the DO-ONCE code that you copied into
AUTOEXEC.BAT in the last step. If you do that, then this code will be
run only once per day, even if you boot up multiple times per day.
Remember that if you are executing other batch files from a batch file,
you should invoke them with a CALL statement:
CALL batchfilename parm1 parm2 ...
so control will return to the calling batch file when execution of the
called batch file is complete.
Note that the string comparison is case sensitive.
.CODE........: :: get 3-character day-of-week name and put it in DOW e-var
FDATE /Ff /oDOW3 /vDOW
if (%DOW%)==(Mon) alarmTSR.exe 10:30 Time for Monday staff meeting
if (%DOW%)==(Fri) echo Running Friday backup. Please wait...
if (%DOW%)==(Fri) CALL BACKUP C:
if (%DOW%)==(Fri) CALL BACKUP D:
set dow=
Entry number 104 Table of Contents
.EXAMPLE.....: 63 Run a program at a specified time later in the day
.CATEGORY....: examples
.DISCUSSION..:
This batch file can be used to run a program at a specified time during
the day.
In general, this is probably not a good use of Fdate, because this batch
file involves a lot of disk activity, which occurs because DOS re-reads
the batch file from disk every time it does a GOTO LOOPTOP. You can
avoid all this disk activity by running the batch file from a RAM DISK.
This was quite a common solution in the days of DOS, but has pretty much
fallen by the wayside now. For this reason, you're probably better off
using a proper task-scheduler program, some of which are available free
on the Web.
But if all else fails, it is indeed possible to use Fdate to do this.
This first batch file uses Fdate's /V feature to put the result into an
environment variable. (If you are running in an environment where /V
doesn't work, see below.) Note that I have included a display of
second#, so you could see that the batch file is looping properly -- you
can see the seconds ticking by! You'll want to remove this if you decide
to use the batch file from some real use.
.CODE........: @echo off
:: GET CURRENT ABSOLUTE MINUTE AND PUT IN ENVIRONMENT VARIABLE RUNTIME
FDATE /Ff /At /Ominute# /vRUNTIME
:: ADD 120 MINUTES (2 HOURS) TO ENVIRONMENT VARIABLE RUNTIME
FDATE /F#add /A%RunTime% /B120 /vRUNTIME
:: LOOP UNTIL NOWTIME HAS REACHED RUNTIME
:LoopTop
FDATE /Ff /At /Ominute# /vNOWTIME
Fdate /Ff /Osecond#
FDATE /F#comp /A%NowTime% /B%RunTime% /vTIMECOMP
if (%TimeComp%)==(LT) goto LoopTop
:LoopEnd
echo STARTING EXECUTION OF APPLICATION: [program name]
.DISCUSSION..:
If you are running on a system that doesn't support the /V parm, you can
use the following code.
The problem with this technique is that it is constantly writing a new
copy of TEMP.BAT to your hard disk. A lot of wear and tear on your hard
disk. Back in the days when DOSausaurs ruled the earth, and people
routinely used virtual disks, that wasn't a problem. But nowadays
(September, 2001) I wouldn't use it except as a last resort.
.CODE........: @echo off
:: GET CURRENT ABSOLUTE MINUTE AND PUT IN ENVIRONMENT VARIABLE RUNTIME
FDATE /Ff /At /Ominute# /p"set RUNTIME=" > temp.bat
call temp.bat
:: ADD 120 MINUTES (2 HOURS) TO ENVIRONMENT VARIABLE RUNTIME
FDATE /F#add /A%RunTime% /B120 /p"set RUNTIME=" > temp.bat
call temp.bat
:: LOOP UNTIL NOWTIME HAS REACHED RUNTIME
:LoopTop
FDATE /Ff /At /Ominute# /p"set NOWTIME=" > temp.bat
call temp.bat
FDATE /F#comp /A%NowTime% /B%RunTime% /p"set TIMECOMP=" > temp.bat
call temp.bat
if (%TimeComp%)==(LT) goto LoopTop
:LoopEnd
:: cleanup
del temp.bat
echo STARTING EXECUTION OF APPLICATION: [program name]
Entry number 105 Table of Contents
.EXAMPLE.....: 71 Extract the rightmost n characters of a string
.CATEGORY....: examples
.DISCUSSION..:
extract the rightmost 6 characters of a string
.CODE........: FDATE /Fsubstr /a-6 /Q"1994 Jun 03" ===> "Jun 03"
Entry number 106 Table of Contents
.EXAMPLE.....: 72 Left-pad a number with zeroes, or a string with spaces
.CATEGORY....: examples
.DISCUSSION..:
Pad a number (stored in environment variable) STRING
to the left with zeroes, to make sure it is 4 bytes long
.CODE........: set STRING=1
Fdate /FE /Q%STRING% /Jr04 /Vstring
echo STRING is [%string%]
.DISCUSSION..:
Here's another example -- we pad a string (stored in environment
variable) STRING to the left with spaces, to make sure it is 4
bytes long
.CODE........: set STRING=aa
Fdate /Fe /Q%STRING% /J"r 4" /Vstring
echo STRING is [%string%]
Entry number 107 Table of Contents
.EXAMPLE.....: 80 --- SECTION: CHECKING/MANIPULATING A FILE'S DATE/TIMESTAMP
.CATEGORY....: examples
.DISCUSSION..:
I've collected together the examples that involve checking or
change a file's date/timestamp. Read on...
Entry number 108 Table of Contents
.EXAMPLE.....: 81 Rename a file name to a name that contains today's date
.CATEGORY....: examples
.DISCUSSION..:
A very common need is to change a file's name to a name that
contains today's date. This is something that you might want to
do if you are a system administrator, for example, and every night you run a
backup utility that produces a log file called something like
BACKUP.LOG. To keep a historical collection of these files, each night,
you need to rename BACKUP.LOG to <TodaysDate>.LOG.
This is how to do it.
If you need to do this with a granularity down to the minute,
see EXAMPLE 82 Rename a file to a name that contains today's time
If you need to store a date in a filename, but are really limited
in the number of bytes available,
see EXAMPLE 83 Rename a file to a name that contains today's date in only 3 bytes
.CODE........: :: today's date (/At) in CCYYMMDD format into environment variable DATE1
FDATE /Ff /At /Occyymmdd /Vdate1
:: rename BACKUP.LOG to ccyymmdd.LOG (ex. 19950508.LOG on May 8, 1995)
REN BACKUP.LOG %date1%.LOG
SET DATE1=
Entry number 109 Table of Contents
.EXAMPLE.....: 82 Rename a file to a name that contains today's time
.CATEGORY....: examples
.DISCUSSION..:
This is a way to keep a complete series of files, such as log files,
that are all created with the same name on the same day. The only
requirement is that they be created at least one minute apart. You
won't need to be able to decipher the absolute minute to figure out when
the file was created; you can simply do a DIR on the file and look at
its date/time stamp.
If don't need to do this with a granularity down to the minute, if
a granularity of just a date will do the job,
see EXAMPLE 81 Rename a file name to a name that contains today's date
.CODE........: FDATE /FF /At /Ominute# /VJulMin
REN online.log %JulMin%.log
SET JulMin=
Entry number 110 Table of Contents
.EXAMPLE.....: 83 Rename a file to a name that contains today's date in only 3 bytes
.CATEGORY....: examples
.DISCUSSION..:
It is possible to store information about a date in only 3 bytes,
using "extended hex" format.
If you need to store a date in a filename, but are really limited
in the number of bytes available, here is how to do it.
For more information about the extended hex output format ("/Oxxx"),
see PARAMETER /Oxxx - Extended Hex Output Date Format
.CODE........: :: get today's date in extended hex format
FDATE /Ff /Oxxx /p"SET XXX=">junk.bat
call junk.bat
del junk.bat
:: rename a file, using the xxx date
ren BACKUP.LOG %XXX%-BACK.LOG
:: cleanup
SET XXX=
Entry number 111 Table of Contents
.EXAMPLE.....: 85 Compare a file's date to today's date
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: :: Compare today's date to the date on the filename in %1
Fdate /Fcomp /At /If /B%1 /Vcomp
if (%comp%)==(EQ) echo %1 was created or updated today
set comp=
Entry number 112 Table of Contents
.EXAMPLE.....: 86 Compare two files' date/time using COMPARE-FUNCTION ERRORLEVELS
.CATEGORY....: examples
.DISCUSSION..:
There are many ways to check errorlevels. This example shows
several of them.
.CODE........: @echo off
cls
SET F1=FDATE.BAT
SET F2=FDATE.EXE
Fdate /Ftcomp /If /A%f1% /B%F2% /P"%f1% is " /S" %f2%"
if errorlevel 101 if not errorlevel 103 echo %f1% is LT/EQ %f2%
if errorlevel 102 echo %f1% is GT/EQ %f2%
if errorlevel 101 if not errorlevel 102 echo %f1% is older than %f2%
if errorlevel 102 if not errorlevel 103 echo %f1% is same age as %f2%
if errorlevel 103 if not errorlevel 104 echo %f1% is younger than %f2%
if errorlevel 101 if not errorlevel 103 echo %f1% at least as old as %f2%
if errorlevel 102 echo %f1% is no older than %f2%
if errorlevel 101 if not errorlevel 102 echo errorlevel is 101
if errorlevel 102 if not errorlevel 103 echo errorlevel is 102
if errorlevel 103 if not errorlevel 104 echo errorlevel is 103
SET F1=
SET F2=
:endit
Entry number 113 Table of Contents
.EXAMPLE.....: 87 Take action if a file has not been updated recently
.CATEGORY....: examples
.DISCUSSION..:
Steve Komosa, IT Operations Manager at the National Gallery in
London, needed to check the timestamp on a particular logfile.
The logfile SHOULD be updated every 10 minutes. If for some
reason the file had not been updated in the last hour, he wanted
to kick off a program that would send a message to his pager.
Here's how we did it.
.CODE........: @ECHO OFF
:: We set the name of the file whose date we want to check.
:: Here, for demo purposes, we check on AUTOEXEC.BAT
SET F=C:\AUTOEXEC.BAT
:: get date/time stamp, in seconds, from the file
FDATE /FF /Osecond# /If /A%f% /P"set ftime=" > junk.bat
call junk.bat
:: get date/time, in seconds, of the current time
FDATE /FF /Osecond# /P"set ctime=" > junk.bat
call junk.bat
:: get the difference
Fdate /f#dif /a%ctime% /b%ftime% /P"set tdiff=">junk.bat
call junk.bat
:: see if the difference is greater than 3600 seconds (1 hour)
Fdate /F#comp /a%tdiff% /b3600 >nul
:: if difference is greater than 3600 seconds, we have a problem
if errorlevel 103 goto bad_time
:: else..
goto ok_time
:bad_time
:: PUT YOUR PROBLEM-HANDLING CODE HERE
:: For demo purposes, we just display a message and pause.
:: Steve would have put code here to send a message to his pager
echo File %F% has not been updated on time
echo Time difference is %tdiff% seconds
pause
goto endit
:ok_time
:: For demo purposes, we display a message and pause.
:: In an actual batch file, you'd probably do nothing at all.
echo Time difference is %tdiff% seconds
echo No problem!
pause
:: ... and fall through to the ":endit" label
:endit
:: cleanup
set ctime=
set ftime=
set tdiff=
set f=
del junk.bat
Entry number 114 Table of Contents
.EXAMPLE.....: 88 Display a list of all files that were created/updated today.
.CATEGORY....: examples
.DISCUSSION..:
.CODE........: @echo off
if (%1)==(SUBROUTINE) goto %2
CLS
echo FILES MEETING FILESPEC [%1] THAT WERE CREATED OR UPDATED TODAY
:: The batch file calls itself: Its own name is in parm %0
for %%v in (%1) do CALL %0 SUBROUTINE CHECKFILE %%v
set comp=
goto endit
:CHECKFILE
shift
shift
:: Compare today's date to the date on the %1 file
Fdate /Fcomp /If /A%1 /Vcomp
:: echo the filename if the file was created/updated today
if (%comp%)==(EQ) echo %1
:endit
Entry number 115 Table of Contents
.EXAMPLE.....: 89 Delete files more than X days old (use a batch-file subroutine)
.CATEGORY....: examples
.DISCUSSION..:
Some background
I present two versions of this batch file. The older version is
for use with DOS, the newer version for use with Win9X, Win2000,
ME, NT, etc. The difference in the batch files is due to the fact
that the newer versions of Windows (1) support long filenames,
which FDATE does not, and (2) don't allow Fdate to use its /V
feature to set environment variables
Introduction
This batch file uses a crude, but effective, technique for giving a
batch file the ability to call subroutines. If you've never seen
something like this before, it is sort of mind-blowing. Here's some
commentary on the more important lines involved in the technique.
if (%1)==(SUBROUTINE) goto %2
If the first parameter, %1, is "SUBROUTINE", then the batch file
recognizes that it is being called for the purpose of executing
one of its own subroutines. In such a case, it does a GOTO to the
start of the requested subroutine. That is, it goes to the label
whose name is in the second parameter.
Explicitly specifying the name of the desired subroutine permits
permits us to have multiple subroutines in the batch file,
each with its own name. (As it happens, in this batch file
we have only one subroutine, named "PROCESS!")
If the first parameter is not "SUBROUTINE", then we fall through
and begin executing the main routine of the batch file. In such a
case, the first parameter (%1) may contain a number, indicating
the number of days to use in determining which files to delete.
Note that this technique will make the batch file malfunction
if the user himself ever executes the batch file from the
DOS command line with the word "SUBROUTINE" as the first
parameter, the word "PROCESS!" as the second parameter, and a
third parameter that is missing or not a valid filename.
This is so unlikely, however, that it is reasonable
to assume that it will never happen.
for %%v in (*.*) do CALL %0 SUBROUTINE PROCESS! %%v
In a batch file, %0 contains the name by which the batch file was
invoked. We use this fact to allow a batch file to call itself,
regardless of what name the user has given to it.
The first parameter passed, when the batch file calls
itself, is the string "SUBROUTINE". This string allows the batch
file to recognize when it is being called for the purpose of
executing one of its own subroutines.
The second parameter is the name of the subroutine that we want
to call: in this case, "PROCESS!".
The third parameter is what we would normally think of as the first
parameter to the subroutine. In this case, when the
FOR statement is executed, and the substitution for %%v takes
place, it will contain the name of the file to be processed.
Note that we could, if we wished, pass additional parameters to
the subroutine. Note also that we can control the files that
we process. We do so via the filemask in the FOR statement.
It we used, for example, "*.EXE", then we would process only
executable files.
GOTO ENDIT
When the mainline of the batch file is finished executing, we
goto the end of the batch file. We MUST do this GOTO in order
to avoid falling through into, and starting to execute, the first
of the batch file's subroutines.
:PROCESS!
shift
shift
Note that when the batch file is called as a subroutine, and the
batch file goes to the PROCESS! label, the values of the parms are:
%0 = [the name of the batch file]
%1 = SUBROUTINE
%2 = PROCESS!
%3 = [name of the file to be processed]
We shift all the parameters to the left twice, to move the
parameter(s) into what we think of as the
proper places for parameters to the subroutine.
After the first SHIFT command:
%0 = SUBROUTINE
%1 = PROCESS!
%2 = [name of the file to be processed]
After the second SHIFT command:
%0 = PROCESS!
%1 = [name of the file to be processed]
Now %1 contains what we think of as the proper parameter(s)
to the subroutine. In this case, %1 contains the filename that
we want the subroutine to process.
At the end of every subroutine, there should be a GOTO ENDIT,
which causes the batch file to go to its own end, and then
end and return control to the statement in the program which called
it. (This is, of course, the CALL statement embedded in the
FOR statement.)
We can optimize the batch file a little by omitting the "goto endit"
at the end of the last subroutine. Instead, we simply allow the
last subroutine to fall through to the end of the batch file.
This batch file shows how to do work on files that are older than
%NumDays%. The PROCESS! subroutine can be modified to do any kind of
work you want.
.CODE........: @echo off
:: A newer version, for use with Windows 9X, Win2000, NT, etc.
::
if (%1)==(SUBROUTINE) goto %2
cls
:: set the number of days in the past. if this value is not passed
:: in via parameter %1, it defaults to 3 days
set NumDays=%1
if (%NumDays%)==() SET NumDays=3
echo ------------------------------------------------------------------
echo PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO
echo ------------------------------------------------------------------
:: Note the use of ~s in the variable reference.
:: This causes the use of the short (8.3) filename, since Fdate cannot
:: handle long filenames.
for %%I in (*.*) do CALL %0 SUBROUTINE PROCESS! %%~sI
echo ------------------------------------------------------------------
echo END OF PROCESSING
echo ------------------------------------------------------------------
:: CLEANUP
set NumDays=
set DaysOld=
set Comparison=
GOTO ENDIT
:PROCESS!
shift
shift
:: get difference in days between filedate and today.
:: Note that /B parm (which is omitted) defaults to today's date.
Fdate /fdif /A%1 /IF /p"set DaysOld=" >temp.bat
call temp.bat
:: compare DaysOld to NumDays
Fdate /F#comp /A%DaysOld% /B%NumDays% /p" set comparison=">temp.bat
call temp.bat
:: the following line will DISPLAY THE NAME AND AGE OF
:: any file for which %DaysOld% is greater than %NumDays%
:: --------------------------------------------------------------
if (%comparison%)==(GT) echo %1 is %DaysOld% days old.
:: EXAMPLE (to activate this routine, remove the REM from column 1)
:: the following line will COPY TO AN ARCHIVE SUBDIRECTORY
:: any file for which %DaysOld% is greater than %NumDays%
:: -----------------------------------------------
:: if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.*
:: EXAMPLE (to activate this routine, remove the REM from column 1)
:: the following line will DELETE
:: any file for which %DaysOld% is greater than %NumDays%
:: -----------------------------------------------
:: if (%comparison%)==(GT) DEL %1
:: fall through to endit
:endit
.CODE........: @echo off
:: An older version, for use with DOS
::
if (%1)==(SUBROUTINE) goto %2
cls
:: set the number of days in the past. if this value is not passed
:: in via parameter %1, it defaults to 3 days
set NumDays=%1
if (%NumDays%)==() SET NumDays=3
echo ------------------------------------------------------------------
echo PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO
echo ------------------------------------------------------------------
for %%v in (*.*) do CALL %0 SUBROUTINE PROCESS! %%v
echo ------------------------------------------------------------------
echo END OF PROCESSING
echo ------------------------------------------------------------------
:: CLEANUP
set NumDays=
set DaysOld=
set Comparison=
GOTO ENDIT
:PROCESS!
shift
shift
:: get difference in days between filedate and today.
:: Note that /B parm (which is omitted) defaults to today's date.
Fdate /fdif /A%1 /IF /VDaysOld
:: compare DaysOld to NumDays
Fdate /F#comp /A%DaysOld% /B%NumDays% /Vcomparison
:: the following line will DISPLAY THE NAME AND AGE OF
:: any file for which %DaysOld% is greater than %NumDays%
:: --------------------------------------------------------------
if (%comparison%)==(GT) echo %1 is %DaysOld% days old.
:: EXAMPLE (to activate this routine, remove the REM from column 1)
:: the following line will COPY TO AN ARCHIVE SUBDIRECTORY
:: any file for which %DaysOld% is greater than %NumDays%
:: -----------------------------------------------
:: if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.*
:: EXAMPLE (to activate this routine, remove the REM from column 1)
:: the following line will DELETE
:: any file for which %DaysOld% is greater than %NumDays%
:: -----------------------------------------------
:: if (%comparison%)==(GT) DEL %1
:: fall through to endit
:endit