views:

194

answers:

4

I use a DATE's master table for looking up dates and other values in order to control several events, intervals and calculations within my app. It has rows for every single day begining from 01/01/1990 to 12/31/2041.

One example of how I use this lookup table is:

  1. A customer pawned an item on: JAN-31-2010
  2. Customer returns on MAY-03-2010 to make an interest pymt to avoid forfeiting the item.
  3. If he pays 1 months interest, the employee enters a "1" and the app looks-up the pawn
    date (JAN-31-2010) in date master table and puts FEB-28-2010 in the applicable interest pymt date. FEB-28 is returned because FEB-31's dont exist! If 2010 were a leap-year, it would've returned FEB-29.
  4. If customer pays 2 months, MAR-31-2010 is returned. 3 months, APR-30... If customer pays more than 3 months or another period not covered by the date lookup table, employee manually enters the applicable date.

Here's what the date lookup table looks like:


{ Copyright 1990:2010, Frank Computer, Inc. }

{ DBDATE=YMD4- (correctly sorted for faster lookup) }

CREATE TABLE     datemast 
(
 dm_lookup       DATE,    {lookup col used for obtaining values below}
 dm_workday      CHAR(2), {NULL=Normal Working Date,}
                          {NW=National Holiday(Working Date),}
                          {NN=National Holiday(Non-Working Date),}
                          {NH=National Holiday(Half-Day Working Date),}
                          {CN=Company Proclamated(Non-Working Date),}
                          {CH=Company Proclamated(Half-Day Working Date)}

 {several other columns omitted}

 dm_description CHAR(30), {NULL, holiday description or any comments}
 dm_day_num     SMALLINT, {number of elapsed days since begining of year}
 dm_days_left   SMALLINT, (number of remaining days until end of year}

 dm_plus1_mth   DATE,     {plus 1 month from lookup date}
 dm_plus2_mth   DATE,     {plus 2 months from lookup date}
 dm_plus3_mth   DATE,     {plus 3 months from lookup date}
 dm_fy_begins   DATE,     {fiscal year begins on for lookup date}
 dm_fy_ends     DATE,     {fiscal year ends on for lookup date}
 dm_qtr_begins  DATE,     {quarter begins on for lookup date}
 dm_qtr_ends    DATE,     {quarter ends on for lookup date}
 dm_mth_begins  DATE,     {month begins on for lookup date}
 dm_mth_ends    DATE,     {month ends on for lookup date}
 dm_wk_begins   DATE,     {week begins on for lookup date}
 dm_wk_ends     DATE,     {week ends on for lookup date}

 {several other columns omitted}
)
IN "S:\PAWNSHOP.DBS\DATEMAST"; 

Is there a better way of doing this or is it a cool method?

+2  A: 

This is a reasonable way of doing things. If you look into data warehousing, you'll find that those systems often use a similar system for the time fact table. Since there are less than 20K rows in the fifty-year span you're using, there isn't a huge amount of data.

There's an assumption that the storage gives better performance than doing the computations; that most certainly isn't clear cut since the computations are not that hard (though neither are they trivial) and any disk access is very slow in computational terms. However, the convenience of having the information in one table may be sufficient to warrant having to keep track of an appropriate method for each of the computed values stored in the table.

Jonathan Leffler
Well that's good to know!.. I've always wondered if I was going about it the wrong way. I also wonder how certain apps like anthropology and antiquities handle B.C. dates before the 12-31-1899, judicial apps that deal with convicts sentences extiguishing 100 years or more from today and astrophysics which deal with billions of years handle dates.
Frank Computer
The main problem is that those other apps normally do not count DAYS or MONTHS over significant timespans. Sentences more than 100 years basically calculate start, end date. Astrophysics / anthropology rarely goes into larg timetframes AND daily reporting at the same time.
TomTom
@TomTom: Astrophysics and anthropology and palaeontology benefit more from INTERVAL YEAR(9) TO YEAR than DATE, and YEAR(9) isn't quite enough. If you need dates BC, you can tag them specially in IDS (no built-in support). Informix applies the so-called proleptic Gregorian calendar retrospectively, ignoring such historical intricacies as when particular regions switch from the Julian to the Gregorian calendar (and interesting dates like the 30th of February - there was one, once, in Sweden!), and missing dates like 3-13 September 1752 in the UK and its colonies (such as what is now the USA!).
Jonathan Leffler
@TomTom - ??.. so like birth/death dates of people born/died before 12-31-1899 (ifx min date) for a cemetery app or famous historic dates cannot be done?.. or if we wanted a date, thousands of years in the future for predicting major astrophysical events ?
Frank Computer
@Frank: dates in the range 0001-01-01 through 9999-12-31 are managed by Informix. There are interesting historical issues to deal with before about 1900 (Russia switch calendars to Gregorian in the 1920s, except for the Russian Orthodox Church). But dates of birth are generally not a real problem. Astrophysics is better handled using INTERVAL values - or simply DECIMAL(n) values for the number of years. You are seldom concerned with which day of the year for a date a million years ago (indeed, you seldom know which year to within ±1000 or more years).
Jonathan Leffler
@Jonathan Leffler - Is their a good weblink for viewing sample time/period fact schemas or other useful business schemas?
Frank Computer
@Frank: you can look at Ralph Kimball's [web site](http://www.ralphkimball.com/html/articles.html), and in particular at a link from it (http://www.ralphkimball.com/html/articles_search/articles1997/9707d05.html)
Jonathan Leffler
Thank You all for answering and contributing your knowledge!
Frank Computer
A: 

It depends on which database you are using. SQL Server has horrible support for temporal data and I almost always end up using a date fact table there. But databases like Oracle, Postgres and DB2 have really good support and it is typically more efficient to calculate dates on the fly for OLTP applications.

For instance, Oracle has a last_day() function to get the last day of a month and an add_months() function to, well, add months. Typically in Oracle I'll use a pipelined function that takes start and end dates and returns a nested table of dates.

Scott Bailey
@Jonathan Leffler - Does informix have these oracle functions described by Scott Bailey?
Frank Computer
Informix has ADD_MONTHS(); it doesn't have LAST_DAY() built-in, but it is pretty easy to implement: `(MDY(MONTH(dateval), 1, YEAR(dateval)) + 1 UNITS MONTH) - 1 UNITS DAY`.
Jonathan Leffler
ok, thank y'all for this info!.. Last question: Aside from GL Support, is there a way to override GL with custom values for month and day when using mmm-dd-yyyy, modified spanish examples: Jan = ENE, Aug = AGO, or long dates (mmmm) January = ENERO, August = AGOSTO, or (dddd) Monday = LUNES, Thursday = JUEVES, etc.?
Frank Computer
A: 

The cool way of generating a rowset of dates in Oracle is to use the hierarchical query functionality, connect by. I have posted an example of this usage in another thread.

It gives a lot of flexibility without the PL/SQL overhead of a pipelined function.

APC
@Jonathan Leffler - Can the following Oracle query, described by APC "in another thread" above, be done in Informix?
Frank Computer
A: 

OK, so I tested my app using 31 days/month to calculate interest rates & pawnshops are happy with it! Local Law prays as follows: From pawn or last int. pymt. date to 5 elapsed days, 5% interest on principal, 6 to 10 days = 10%, 11 to 15 days = 15%, and 16 days to 1 "month" = 20%.

So the interest table is now defined as follows:

NUMBER OF ELAPSED DAYS SINCE
PAWN DATE OR LAST INTEREST PYMT

 FROM     TO  ACUMULATED
  DAY    DAY    INTEREST
-----   ----  ----------
    0      5       5.00%
    6     10      10.00%
   11     15      15.00%
   16     31      20.00%
   32     36      25.00%
   37     41      30.00%
   42     46      35.00%
   47     62      40.00%

   [... until day 90 (forfeiture allowed)]
   from day 91 to 999, daily prorate based on 20%/month.

Did something bad happen in the UK on MAR-13 or SEP-1752?

Frank Computer
@Jonathan: Did something bad happen in the UK on 13-MAR or SEP-1752?
Frank Computer