Addsum web site and general info




Follow by e-mail

Tuesday, July 10, 2018

Short dates revisited

Short dates allow a software user to enter the year of a date by just indicating its last two digits.  It is convenient and saves time.

The problem with short dates is that they have to be interpreted as to which century they fall in, since they are after all only denoted with two digits.

This was the infamous Y2K problem when systems interpreting those last two digits after 1999 ("99") rolled over to 1900 ("00") instead of 2000 (also "00").   At some point, however, when whatever sliding century logic is in place and the end of its 100th year is reached, then a "Y2K" problem recurs.

For the most part, calamity does not ensue when the "next century" begins because software typically works on a relative basis.  The only real problem for accounting software for example was that once we were in 2000, the software (depending on the version) might not understand that "99" was older  then "00."  And while this would be a problem for the proper display of certain detailed data when crossing years, it in no way prevented the software from continuing to work within the relative space of the "current" year.  Hence, the world kept turning and life moved on.  The main problems that users had in 2000 who failed to move to a compliant system was when running a report that crossed into a prior year or where there was date logic that required comparision with pre-2000 dates (such as making an accounting entry into a prior period).  After a few years however most of those issues also became moot for those users who decided to live with that problem (although older historical data would still be out of chronological date sequence order).

The Windows operating system deals with the sliding century for short dates through regional settings where date formats can also be assigned. These settings also impact how short dates are interpreted.   XP Pro, Windows 7 and Windows 10 all default the century as 1930 to 2029 (which can be changed via the Control Panel under Clock, Language and Region in Windows 7, 8 and 10; under the Control Panel's Regional and Language section in XP Pro).

It is the application  itself typically that determines the sliding century and not the database. So for example with Btrieve/Pervasive data that we frequently work with, there was no Y2K type problem:  all date values were already being stored in a long date format.   It is instead the application that has to tell the database engine how to interpret the short date which is then saved into a long date (albeit potentially in the wrong century).

In the TAS programming world and the applications written in it (including Advanced Accounting), we wrote a memo in 1998 outlining short date issues in various versions of the products that then existed.   See Year 2000 issues and statement of year 2000 compliancy.    No version prior to 5.1 was technically compliant.   Versions 3.0 (and prior) were not at all compliant.  Version 5.0 was meant to be compliant but had some issues in the year 2000 itself.   

Programmers of highly customized TAS 3.0 systems (including highly customized versions of Advanced Accounting 3.0) typically chose not to move those systems forward into version 5.1 as the year 2000 approached, but instead took on the time consuming task of changing every defined short date field (both temporary variables and permanent field variables established via the data dictionary) from the short size (i.e. 8) to the long date size (i.e. 10).  Technically the data files did not require a restructure because the byte size of the field wasn't being changed, but typically the data was nonetheless restructured and every single use of those fields had to be identified and changed including on every screen and report form which required extensive manual repositioning of each and every date field since they now occupied two additional characters and also because of how the TAS 3.0 screen editor worked.  To migrate the TAS 3.0 code forward was admittedly potentially costly particularly for programmers who had not been working with the newer versions and were not familiar with them (version 3.0 did not even support functions), plus because it was relatively primitive code to start with, so some re-writing of code was inevitable; hence the long date approach was typically always chosen.  Converting code forward from version 4.0 (assuming it was written in that more modern language) is easier than 3.0.   But there was a better way than the above in terms of dealing with the Y2K issue even staying in the 3.0 version.

Version 5.1's sliding century, as outlined in our 1998 memo, was set by the prior publisher to be 1920 to 2019.   That century period however is now coming to a close and anyone running the  5.1 version will have to anticipate making some changes since January 1, 2020 will be here fairly soon, and since a 01/01/20 (mm-dd-yy) date will be saved by the 5.1 runtime engine as 01/01/1920 (mm-dd-yyyy) internally and not as 01/01/2020.    So the exact same issue is coming up for the 5.1 version that users of 3.0 versions were faced with in the 1998-1999 timeframe.  But does this mean that the same long date solution is required?   While that would be a potential solution, no, nor it is necessarily the optimum solution.

Before outlining an alternative solution for version 5.1 (besides migrating the application to a newer version altogether), it should be noted that the sliding century of the current version 7i (then TAS Professional 7 as first released by us) was expanded back in 2004 to be 1961 to 2060.  Users therefore of our 7 and 7i runtime versions should have no worries with respect to short dates.  Prior to that in TAS Professional 6 as released by Business Tools, the sliding century was defined as 1931 to 2030, so even a TAS Pro 6 user has nothing to worry about for now with respect to short dates.

Version 5.1 users do have another option that does not involve having to modify and adjust every single screen and report form nor change all of the temporary and permanent data variables in every program.  Instead, a one-line function can be called right after any field with a date value is being assigned and its century then adjusted programmatically.    As with the long date option, it does still require that programs with date values be recompiled and still requires some amount of work.   But it otherwise should involve far less time, end users will not notice any difference, there will be no repositioning issues, and users will still be able to enter short dates.

An example of the type of alternative function for 5.1 systems using short dates which we have called get_new_date() is outlined below.  We have placed this function in a 5.1 library file (Addsum.lib) in-house for use by systems we support that may need it (the semi-colon reflects the principal way of commenting a 5.1 program):

;Assume that the permanent field BKAR.INV.INVDTE 
;(the AR invoice date) has a value before saving 
;it to its corresponding data file


And here is the function contained in the LIB file (the calling program needs to have a #LIB compiler directive referring to that file and since all of accounting software programs already have a compiler directive referring to the Addsum.lib file where we have placed it, it creates no additional work):

;Copyright 2018 Addsum Business Software, Inc.

define old_date,ret_date type D size 8 local
define newyear_a type A size 4 local
define longdate_a,newdate_a type A size 10 local

func get_new_date old_date

   ;we are simplistically assuming that any date less than 2020

   ;needs to be adjusted - there are many different ways 
   ;this could be accomplished, this is just one example
   ;NOTE that more variables have been used than
   ;absolutely necessary to make it somewhat more understandable
   ;this routine could be used on data saved with older
   ;versions, changing 2020 to a date such as 1980
   ;and then when re-saved back to the data file, a date in 
   ;the wrong century would then be fixed

   if val(year(old_date))  < 2020
      longdate_a = dtoc(old_date)
      newyear_a = "20"+mid(longdate_a,7,2)
      newdate_a = mid(longdate_a,1,6)+newyear_a
      ret_date = ctod(mid(longdate_a,1,6)+str(newyear_a))
   ret ret_date


Just as there were reasons for some users to stay with TAS 3.0 and even though 5.1 is also 16-bit (unlike newer versions), the same reason for staying with a highly customized TAS 5.1 system persists potentially into 2019 and beyond just as it did in 1999 with TAS 3.0.

Related information/posts:

Year 2000 issues and statement of year 2000 compliancy (1998)

From Books 2.04 to Advanced Accounting 7i  (2017)