Six Million Dollar Date
In the opening to the TV show, Six Million Dollar Man, they promised to rebuild him - better, faster, and stronger. This occasional series, the Six Million Dollar _____ will offer suggestions on how to elevate mvBASIC commands by making them better, faster, and stronger. We have the technology.
Getting data into an mvBASIC program requires a READ or an INPUT. While I have seen many, many attempts at creating a wrapper around the INPUT command, the diversity of data we push through often makes the wrapper into a programming language unto itself, using dozens of parameters and conditionals to attempt a one-size-fits-all solution. Instead of trying to be everything to everything , our six million dollar DATE will be an input wrapper focused on getting date-related input right. Sometimes limiting scope is the best answer.
Dates take on many forms: most operating systems have a time-date stamp based on an epoch. MultiValue has a epoch based on date alone. Europeans write dates as day/month/year while Americans write month/day/year. People who care about sorting external dates use year/month/day. Then there's Julian format, longhand (1 June 1981), and shorter longhand (28 Sept 1985). Reasonably, our wrapper needs to understand all of them (plus two bonus cases to be discussed later) and should be able to convert them any-to-any for use [ Figure 1 ].
001 subroutine DATER(RESULT, RULES, DEFAULT)
002 * by Charles Barouch (Results@HDWP.com)
003 * as seen in International Spectrum Magazine
004 input ANS
005 convert '/' to '-' in ANS
006 if ANS = "" then ANS = DEFAULT
006 begin case
007 case ANS = matches '"T"-1N0N' and INDEX(RULES<1>,'T',1) = 0
008 * Example: T-1 (yesterday)
009 IDT = DATE() - oconv(ANS,'MCN')
010 case ANS = matches '"T"+1N0N' and INDEX(RULES<1>,'T',1) = 0
011 * Example: T+1 (tomorrow)
012 IDT = DATE() + oconv(ANS,'MCN')
013 case ANS matches '1N0N"-"1N0N"-"1N0N' and (RULES<3> = "A" or RULES<3> = "")
014 * American format (mm-dd-yy or mm-dd-yyyy)
015 IDT = OCONV(ANS,'D') ;* Assuming You are set to American format
016 case ANS matches '1N0N"-"1N0N"-"1N0N' and RULES<3> = "E"
017 * European format (dd-mm-yy or dd-mm-yyyy)
018 TEMP = oconv(ANS,'G1-1'):'-':oconv(ANS,'G0-1'):'-':oconv(ANS,'G1-1')
019 IDT = OCONV(TEMP,'D') ;* Assuming You are set to American format
020 case 1
021 IDT = ANS
022 end case
024 begin case
025 case RULES<2> = "I"
026 RESULT = IDT
027 case RULES<2>[1,1] = "D"
028 RESULT = oconv(IDT,RULES<2>)
029 case 1
030 RESULT = IDT
031 end case
RULES<1> has the allow/disallow for input formats, null means allow. RULES<2> has the desired resulting format. RULES<3> is either "A"merican, "E"uropean, or "J"ulian.
About that first bonus case: Date math and date shorthand are among the most common things needed by data entry. T+7 is much easier than making the user look up the date seven days from now. EOM is much easier than forcing them to memorize 30 days hath September, April, June, and November . Personally, I like being able to type W-1 for last week or Sun+1 for a week from Sunday.
I've only put in a fraction of the code here because the rest becomes easy once you have the examples. To create week math (W-7 style logic) just copy lines seven through twelve and change "T" for "W" and multiply the oconv result by seven.
To create end-of-month (EOM style logic) just take today's date, keep the month and year and sub out the day for 28,29,30, or 31 as appropriate. To create day-of-the-week (SUN+1 style) divide the internal date by seven to get the SUN date. If MON was requested, get the SUN date and add one. SAT is SUN plus six. If you prefer SUN, MON, TUE... only being future, you can use the formula outlined and add seven if the result is less than today.
About that second bonus case: We often need to distinguish between skipped and intentionally left out. When I worked in rush courier, we had two special 'dates' called International and Unknown. Placing an "I" in a date field meant that there needs to be a date but it can't be determined until business hours at the international destination. "U" meant that there needs to be a date but it can't be filled in yet for any reason other than the one which "I" denotes.
Having a generalized date routine that can be plugged into any program makes adding or restricting features like this easy. Did I miss a format you use? You can add it to your version of the six million dollar date. is
Got your own wrapper for a MultiValue BASIC command or TCL verb? Send us your Six Million Dollar make-overs so we can share them with the community. Email firstname.lastname@example.org .
More about Dates
I've actually had to ask "What does a day mean?" For some companies, the day ends at closing time, not at midnight. Mom-and-pop shops might close their day whenever mom leaves because she won't be updating the financials again until tomorrow.
Oh, and if you think a day has twenty-four hours, consider that some have twenty-five due to DST (Daylight's Saving Time), and some have twenty-three, also due to DST. Of course, when to add or subtract that hour is locational. Australia and the U.S. have DST reversed from one another. And, inside the borders of Arizona for example, they never have DST. Well, except on Navajo land, where they do. Florida has a plan underway to make DST permanent (as in, never "fall back" to Standard Time).
Weeks and months are similarly complex. While the SEC (Security Exchange Commission) has rules against closing a month early or holding it open late, privately held companies can elect do do those things. So, assuming a month ends on the last day is not a sure assumption.
What about years? For most businesses, a year is made of full weeks, which means either a few days in December roll into the next year or a few days in January are owed to the previous year. And, for the historically minded, one year is missing eleven days. The day after September 2nd, 1752 is September 14th, 1752. At least it was in England.
You can read more about that here: http://mentalfloss.com/article/51370/why-our-calendars-skipped-11-days-1752