NOWMINUS.TXT www.merlyn.demon.co.uk >= 2009-03-11 Copyrights apply; the code, text, etc. are presented only to help users. INTRODUCTION Program NOWMINUS.EXE is a date-time handler, primarily for batch files, written in Borland Pascal MASOS mode. It can set the DOS date and/or time, current or that of a file, local or maybe GMT, actual or offset or truncated etc., in a chosen ISO or other format (UK Tax, CJD, time_t, RFC, ...) to a parent DOS Environment, if there is room; and can send it to Standard Output, optionally as a SET command. It can subtract date/times. It can read the RTC. It can set a file datestamp. To manipulate files depending on their dates, use my program HUNT; it can, but often does not need to, be given a date from NOWMINUS. Initially, NOWMINUS loads the current local civil DOS date and time (DOS Int 21; not RTC Int 1A) as the date/time-in-hand, DT. The parameters presented on the command line are processed in turn, operating on the current value of DT. The command R shows DT. Note that the DOS clock, not the RTC, is normally the proper source to use; it is standard for applications to use it. DOS & RTC will run at slightly different rates. To use the RTC, use ^ as first parameter. To obtain non-preferred date/time field orders, pipe option R into my program COLS. NOWMINUS uses the (Astronomical Proleptic) Gregorian Calendar. Remember Summer Time; there is no spontaneous adjustment. CJD = Chronological Julian Date; local day Julian BC 4713-01-01 Mon = 0 CMJD = Chronological Modified Julian Date; local day 1858-11-17 Wed = 0 CMJD = CJD - 2400001. Here, time_t calculation disregards both Leap Seconds and Summer Time. True time_t is based on Winter Time at Greenwich. For true time_t, adjust with U## (in EU) or (A## U##) in NA) or otherwise. One day, I may introduce NOW_PLUS and develop that instead. In it, the parameters S M H D W N Y will be reversed in effect, and there will be one set of numbers for Formatting Date and another for Time (and separate for Zeroing?). Before 2002-08-11, the Y and N commands went to the same "day-of-month" even if after the end of the month. From then, if the starting day does not occur in the resulting month, the last day is given. For the previous behaviour, use _ and ~ respectively. For examples of the use of NOWMINUS, see below. Another date-handling program for batch use, with overlapping capabilities, is FDATE by Stephen Ferg - . AVAILABILITY NOWMINUS only needs 16-bit DOS; OK in MSDOS, in Win3, Win9x, WinXP DOS boxes; in WinME, WinNT, Win2K ?? ; see NOTES. NOWMINUS.(PAS,EXE,TXT,ZIP) are available from the Web directory . Date routines are in DATEPROX.PAS, environment ones in JRS_ENVU.PAS; same directory. Filenames are actually lower-case. A Turbo Pascal 7 compiler is sometimes free from Borland in France; see . DELPHI 2006-01-19 ff. : There may be a Delphi version, using Win-32. These parameters are (initially?) not implemented - ! ^ C O E V # - and parameter R does not use the Environment, and # is not implemented. Currently not available. PARAMETERS Parameter letters are case-independent; initial / and - are optional. A semi-colon starting a parameter begins comment to end-of-parameters. A parameter starting with equals is ignored. Here ## is a number, up to longint; it may be signed or hexadecimal ($d+). It may also be given as # where is + - and is an environment variable. S## = Seconds to reduce DT by, M## = Minutes, H## = Hours, D## = Days, W## = Weeks, N## = Months, Y## = Years likewise; all are optionally signed integers. Reductions are not limited to their natural range; they can be negative. Z## = Clear field(s) of DT - Z1..Z6 = least 1..6 fields of YYYY-MM-DD hh:mm:ss, to 0001-01-01 00:00:00, Z7 = ISO Day Number (to Day 1 = Monday), Z8 = ISO Week and Day Numbers (to Week 1, Day 1 of current ISO year), Z9 = CMJD, to Day 0 = 1858-11-17 Wed, Z10 = cf. UNIX time_t, to 0s = 1970-01-01 00:00:00, Z11-Z13 UK Revenue & Customs Tax calendar - go to the beginning of DT's : UK R&C Week (7*N days from Apr 6), UK R&C Month (N months from Apr 6), UK R&C Year (back to Apr 6), Z14 = to start of Quarter, Z15-Z17 = move a weekend day to the previous/nearest/following weekday; F## = Output Format Bitmap, additive: B0 = $01 = 1 = noTime, otherwise hh:mm:ss, B1 = $02 = 2 = noDate, otherwise YYYY-MM-DD, B2 = $04 = 4 = Date ISO 8601 YYYY-WW-DD, week Mon..Sun, week 1 has Jan 4th. B3 = $08 = 8 = CJD (noon+ Julian Date, CMJD+2400001; /caveat/ the 1), B4 = $10 = 16 = cf. UNIX time_t (seconds LCT from 1970-01-01T00:00:00), B5 = $20 = 32 = UK Tax YYYY-WW-DD (start at Day 1 Week 1 on Apr 6), B6 = $40 = 64 = UK Tax YYYY-MM-DD (start at Day 1 Month 1 on Apr 6), B7 = $80 = 128 = Date ISO 8601 YYYY-DDD, B8 = $100 = 256 = Date as "Sun, 06 Nov 1994 08:49:37" (may need u, h, a - user's responsibility), can add GMT (RFC2068) or UTC offset (RFC2822), B9 = $200 = 512 = Date YYYY-N-DD NQYY NQYYYY for N'th quarter of Cal Year, B10 = $400 = 1024 = Time is seconds of day (Date+5, or 8/10, digits), B11 = $800 = 2048 = use DMY instead of YMD, B12 = $1000 = 4096 = signed seconds (for use after subtraction), B15 = $8000 = 32768 = Random(10000) or Random($10000), as four digits; N.B. F3 will therefore clear an environment variable. N.B. some bits overrule others, where the combination is illogical. N.B. be wary with Randomize if NOWMINUS is scheduled or repeated. Initial Date/Time Formats (for the same date and time) : F0 2001-12-25T01:02:03 F1 2001-12-25 F2 01:02:03 F3 F4 2001-52-02T01:02:03 F8 0002452269T01:02:03 F16 1009242123 F32 2001-38-05T01:02:03 F64 2001-09-20T01:02:03 F128 2001-359T01:02:03 F256 Tue, 25 Dec 2001 01:02:03 GMT F512 2001-4-86 4Q01 4Q2001 T01:02:03 F1024 2001-12-25T03723 F2048 25-12-2001T01:02:03 F4096 +0000000003 - for difference of +3; B discounts the sign Ix = use the character x, or a space if x is absent, to replace 'T' as the centre separator in date-time output - use a digit 0..9 for no separation, Jx acts likewise replacing '-' within the Date, Kx acts likewise replacing ':' within the Time; B## = Output DT will start with character number B, default 1; L## = Output DT will be cut to L characters, default use all; For other date formats, set the individual fields into the environment, and then assemble with the DOS SET command. X## = monitoring (partial debug) output 1/0 = on/off; default off. G## = Generation; the environment manipulated is that of the ##'th ancestor back of the present program. The effect of ##<0 is both undefined and unconsidered at present. Default is 8, presumed to go back as far as possible. Exx = set the environment (Gen) variable xx=DT directly, Vxx = as Exx but with less screen output; Pxx = send a 'SET xx=DT' command to Standard Output (good for test), Qxx = as Pxx but '@SET xx=DT', Rxx = send '%xx% DT' (in %xx%, 'œ' is converted to '='). Tstring = the supplied string is read into DT, assuming the current F fields (F32768: into RandSeed). T%EnvVar% could well be useful; note that it reads the call-time Environment, which is copied to that of NOWMINUS itself. No formats should have been omitted. Cxx = the value of the named string of Environment Gen is read into DT. For O, the file named string must be openable; use the Short File Name form, without quotes. Ostring = DT is set to the datestamp of the file. O*string = The datestamp of the file is set to DT. If string is empty, the previous string, initially empty, is used. U## = DT is decremented by ## hours, and if it then appears to be within UK local Summer Time it is decremented by an hour. With ##=0, should convert from UK Civil Time to UTC/GMT; with ##=1, should first convert from French time to UK; with ##=2, from Eastern EU time to UK. CHECK. One Autumn hour of Civil Time is inevitably ambiguous. A## = Summer starts a week after EU and changes are at local clock 0200h, value odd/even = on/off; default off. Use before U##. 1987-2006 Rules! &xx is 5+5 characters, for zone number with RFC format; see example below. ^ = Read RTC. ] = Store DT, [ = Recall DT. - = DT := Store - DT. For result use F1032, equality is 0002400001T00000; or F4096 is better. ª = Set to Gregorian Easter Sunday of the stored year; all corresponding Moveable Feasts are at determinate offsets from that. !envname = execute Env(envname). @filename = parameters are read from file. :## = Random(##) to 5 digits; 0 <= Result < ## < 65536 ; :0 disables; does not need F. :: = save RandSeed (not implemented). # = I/O (T; E, V, P) is set to Decimal (default state!), $ = I/O (T; E, V, P) is set to Hexadecimal, but ... $$ = I/O (T; E, V, P) is set to Base 36. 'string = Write string, * = Write space. *## = write ## spaces. ** = write " - if used an odd number of times, puts another " at the end of an R command, counting it. œ = Wait for , useful in test, ; = Rest of line is comment, = = This parameter ignored, ? = Help. OUTPUT Output numbers (except F4096) cannot be <0; but the internal date range is otherwise +-32100 years; output years are probably 0000-9999. The value of time_t has the usual signed 32-bit limit. RUNTIME ERRORS 201 : Range check error 215 : Arithmetic overflow error 216 : General Protection fault 255 : Any Unimplemented sub-feature STATUS Status values: 0 = OK 1 = No environment found 2 = Empty environment found 3 = No environment terminator found 4 = Insufficient space for change The Unit cannot at present expand the Environment; first SETting the variable to be used could well do this. NOTES For the environment handling, including status, see the comment (and code) in unit JRS_EnvU.pas (same directory). It seems OK for DOS, Win3, Win98; but that direct environment access is not effective in Windows NT and up. Commands P & Q are necessarily safer than E or V and can always be used. Windows NT and later: try (for hhmmss) CONSOLE: for /f %t in ('nowminus f2 k0 r') do @set XX=%t BATCH: for /f %%t in ('nowminus f2 k0 r') do @set XX=%%t or redirect P or Q output to a file and execute the file. Windows-64 without 16-bit support - Delphi version? CHANGES 2002-08-11 : Behaviour of Y and N modified, at ends of short months. 2003-05-27 : GetDT with F$80 was a day out; fixed. 2005-05-08 : Parameter ª for Easter added. 2005-10-06 : Description of F16 & Z10 amended. 2006-01-19 : To Delphi-3-compilable though then with fewer features. REFERENCES ISO Standard 8601. My and links. EXAMPLES COLS, HUNT are available from the same Web directory as NOWMINUS. There may now be improved ways of doing earlier examples. 1 To operate on files less than 10 minutes old : NOWMINUS m10 Eeee HUNT * f%eee% "ren" "*.new" u set eee= 2 To rename a file (%1) to yesterday's date YYYYMMDD : NOWMINUS f1 d1 j0 Eeee ren %1 %eee%.* set eee= 3 To rename files ABCD.* to include today's date YYMMDD : NOWMINUS f1 j0 b3 r | COLS 'ren * 'ABCD.* * 'ABCD 1- '.* > temp.bat call temp del temp.bat 4 To find Next Tuesday : NOWMINUS 'Next * 'Tuesday * 'is * d1 w-1 z7 d-1 r 5 To set Week Number and Day-of-Week Number via a file : NOWMINUS f5 b6 l2 PWkNo b10 PDyNo > file.bat 6 To set CMJD & CJD, via a file (consider h12/h-12 and place for JD, MJD) : NOWMINUS f9 b4 pCJD d1 b6 pCMJD > file.bat 7 To send the ISO DateTime to standard output : NOWMINUS r ; comment 8 To send the *Julian* Calendar DateTime to standard output : NOWMINUS d13 r ; *between* 1900-02-29 & 2100-02-29 Julian 9 To set date and time fields individually via a file : NOWMINUS l4 pYR b6 l2 pMO b9 pDY b12 pHR b15 pMIN b18 pSEC > file.bat 10 To increment an environment variable xx, giving digits 8-10 of 10 : NOWMINUS f16 t%vv% s-1 b8 vxx 11 To set the date of a file, as YYYYMMDD, into environment 'itsdate' : NOWMINUS Ofilename f1 j0 Eitsdate 12 To test whether the time is in 11:21:31-12:22:32 (maybe adjust by 1s) : NOWMINUS L10 ] h11 m21 s31 Ex1 [ d-1 h12 m22 s32 Ex2 IF %x1%==%x2% goto NotBetween 13 To set the TLA for the DoW (in English), into environment 'DOW' : NOWMINUS f256 l3 vDoW 14 To show the Quarter, as 3Q01 : NOWMINUS f$200 b11 l4 r 15 To send RFC2068 date/time to Std Out, from UK (check) : NOWMINUS u f256 r 16 To send RFC2822 date/time to Std Out, from UK (check); aaaaabbbbb is the winter+summer suffices for the zone, +0000+0100 for the UK : NOWMINUS ] u [ f256 &aaaaabbbbb r 17 To set the UTC start of EU Summer Time for the year (others similarly) : NOWMINUS z5 n-3 z7 d1 h-1 Eston 18 To show the UTC corresponding to a time_t : NOWMINUS z10 s-%time_t% i r NOWMINUS f16 t%time_t% f0 i r 19 To show the date of Next Christmas, in three ways : NOWMINUS f1 d-7 y-1 z5 d+7 r f5 r f9 r 20 To give a 16-digit random number : NOWMINUS f32768 r r r r | COLS , , , 1- 21 To test whether a file is older than 15 minutes (use 'if "%xx%"=""') : NOWMINUS f16 ] Ofile.ext Exx [ S#+xx m15 Exx f3 Exx or NOWMINUS m15 ] Ofile.ext - f9 d2400001 Exx 22 To show ISO date, CJD, time_t, and SecOfDay : NOWMINUS 'date * r f9 'CJD * r f16 'time_t * r f1026 'SecOfDay * r 23 To show and set by how many seconds DOS is ahead of RTC : NOWMINUS 'DOS * r ] ^ 'RTC * r - f$1000 'Diff * r Ediff 24 To set UK/EU DD/MM/YY do this, then use %DDMM%+%YY% : NOWMINUS f2049 j/ l6 eDDMM b9 eYY 25 To test for Leap Year (sets 28/29, 0/1) : NOWMINUS f1 z5 n-2 d1 b9 eFebLen d8 b10 e01 26 To test formatted date in EnvVar for validity (and/or Time) : NOWMINUS t%EnvVar% f1 eTemp IF %Temp%==%EnvVar% ... 27 To represent a date in 2000-2035 in 3 characters YMD : NOWMINUS y20 $$ l1 b4 vY b7 vM b10 vD SET date=%Y%%M%%D% 28 To represent a C.21 daycount most compactly (3 base-36 digits) : NOWMINUS d2451910 f9 $$ b4 r 29 To reduce the datestamp of file %1 by 10.5 hours, removing seconds : NOWMINUS o%1 h10 m30 z1 o* 30 To set DOS time to RTC time, presuming day (caveat MASSEXEC) : NOWMINUS ^ F2 'time= r | MASSEXEC 31 To set environment Y M D in NT or XP : NOWMINUS 'set * 'Y= L4 r 'set * 'M= B6 L2 r 'set * 'D= B9 L2 r > $$$.BAT call $$$ 32 For an absolute week count, ENVICALC uses RPN : NOWMINUS F9 EDN ; set CJD in env. DN ENVICALC CDN 3 - 7 / B6 EWN ; set AbsWkNo in WN Adjust the value of 3 by up to +-3 to get desired first day of week (Mon, ...); adjust by putting N - after / to change the zero week by N weeks. 33 For noon on Easter Sunday of the next year (note: ª not -): NOWMINUS y-1 ª z3 h-12 r 34 For timing a process NOWMINUS vTIME Capture start (process) NOWMINUS vTIME ] t%TIME% - f$1000 r f2 r Show diff in time 35 To represent a daycount from 2000-01-01 in 3 base-36 characters (9ZZ on 2035, ZZZ in 2127) NOWMINUS F9 d2451545 $$ b4 r 36 To show standard ISO Week Numbering form NOWMINUS F4 I R | COLS 1-5 'W 6-8 10- . 37 To get Ordinal Date for arithmetic, protected against octal NOWMINUS f129 b6 '1 r ; and subtract 1000 --- To Do ? Make ', * (&c?) build a string prepended to St for output, and make something toggle between that string and one to be appended.