DSN8DUCD

Converts a given date from one to another of these 34 formats.

 /********************************************************************* 00010000
 * Module name = DSN8DUCD (DB2 sample program)                        * 00020000
 *                                                                    * 00030000
 * DESCRIPTIVE NAME = General date reformatter (UDF)                  * 00040000
 *                                                                    * 00050000
 *                                                                    * 00120000
 *  LICENSED MATERIALS - PROPERTY OF IBM                              * 00130000
 *  5675-DB2                                                          * 00140000
 *  (C) COPYRIGHT 2000 IBM CORP.  ALL RIGHTS RESERVED.                * 00150000
 *                                                                    * 00160000
 *  STATUS = VERSION 7                                                * 00170000
 *                                                                    * 00190000
 *                                                                    * 00210000
 * Function: Converts a given date from one to another of these 34    * 00220000
 *           formats:                                                 * 00230000
 *                                                                    * 00240000
 *             D MONTH YY  D MONTH YYYY  DD MONTH YY  DD MONTH YYYY   * 00250000
 *                 D.M.YY  D.M.YYYY      DD.MM.YY     DD.MM.YYYY      * 00260000
 *                 D-M-YY  D-M-YYYY      DD-MM-YY     DD-MM-YYYY      * 00270000
 *                 D/M/YY  D/M/YYYY      DD/MM/YY     DD/MM/YYYY      * 00280000
 *                 M/D/YY  M/D/YYYY      MM/DD/YY     MM/DD/YYYY      * 00290000
 *                 YY/M/D  YYYY/M/D      YY/MM/DD     YYYY/MM/DD      * 00300000
 *                 YY.M.D  YYYY.M.D      YY.MM.DD     YYYY.MM.DD      * 00310000
 *                         YYYY-M-D                   YYYY-MM-DD      * 00320000
 *                         YYYY-D-XX                  YYYY-DD-XX      * 00330000
 *                         YYYY-XX-D                  YYYY-XX-DD      * 00340000
 *                                                                    * 00350000
 *           where:                                                   * 00360000
 *                                                                    * 00370000
 *             D: Suppress leading zero if the day is less than 10    * 00380000
 *            DD: Retain leading zero if the day is less than 10      * 00390000
 *             M: Suppress leading zero if the month is less than 10  * 00400000
 *            MM: Retain leading zero if the month is less than 10    * 00410000
 *         MONTH: Use English-language name of month                  * 00420000
 *            XX: Use a capital Roman numeral for month               * 00430000
 *            XX: Use a capital Roman numeral for month               * 00440000
 *            YY: Use non-century year format                         * 00450000
 *          YYYY: Use century year format                             * 00460000
 *                                                                    * 00470000
 *           Example invocation:                                      * 00480000
 *            EXEC SQL SET :newDate = ALTDATE( "3/15/1947",           * 00490000
 *                                             "M/D/YYYY",            * 00500000
 *                                             "DD MONTH YY" );       * 00510000
 *            ==> newDate = "15 March 47"                             * 00520000
 * Notes:                                                             * 00530000
 *   Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher       * 00540000
 *                                                                    * 00550000
 *   Restrictions:                                                    * 00560000
 *                                                                    * 00570000
 * Module type: C program                                             * 00580000
 *   Processor: IBM C/C++ for OS/390 V1R3 or higher                   * 00590000
 * Module size: See linkedit output                                   * 00600000
 *  Attributes: Re-entrant and re-usable                              * 00610000
 *                                                                    * 00620000
 * Entry Point: DSN8DUCD                                              * 00630000
 *     Purpose: See Function                                          * 00640000
 *     Linkage: DB2SQL                                                * 00650000
 *              Invoked via SQL UDF call                              * 00660000
 *                                                                    * 00670000
 *       Input: Parameters explicitly passed to this function:        * 00680000
 *              - *dateIn      : pointer to a char[18], null-termi-   * 00690000
 *                               nated string having a date in the    * 00700000
 *                               format indicated by *formatIn.       * 00710000
 *              - *formatIn    : pointer to a char[14], null-termi-   * 00720000
 *                               nated string having the format of    * 00730000
 *                               date found in *dateIn (see "Func-    * 00740000
 *                               tion", above, for valid formats).    * 00750000
 *              - *formatOut   : pointer to a char[14], null-termi-   * 00760000
 *                               nated string having the format to    * 00770000
 *                               which the date found in *dateIn is   * 00780000
 *                               to be converted.  See "Function",    * 00790000
 *                               above, for valid formats.            * 00800000
 *              - *niDateIn    : pointer to a short integer having    * 00810000
 *                               the null indicator variable for      * 00820000
 *                               *dateIn.                             * 00830000
 *              - *niFormatIn  : pointer to a short integer having    * 00840000
 *                               the null indicator variable for      * 00850000
 *                               *formatIn.                           * 00860000
 *              - *niFormatOut : pointer to a short integer having    * 00870000
 *                               the null indicator variable for      * 00880000
 *                               *formatOut.                          * 00890000
 *              - *fnName      : pointer to a char[138], null-termi-  * 00900000
 *                               nated string having the UDF family   * 00910000
 *                               name of this function.               * 00920000
 *              - *specificName: pointer to a char[129], null-termi-  * 00930000
 *                               nated string having the UDF specific * 00940000
 *                               name of this function.               * 00950000
 *                                                                    * 00960000
 *                                                                    * 00970000
 *      Output: Parameters explicitly passed by this function:        * 00980000
 *              - *dateOut     : pointer to a char[18], null-termi-   * 00990000
 *                               nated string to receive the refor-   * 01000000
 *                               matted date.                         * 01010000
 *              - *niDateOut   : pointer to a short integer to re-    * 01020000
 *                               ceive the null indicator variable    * 01030000
 *                               for *dateOut.                        * 01040000
 *              - *sqlstate    : pointer to a char[06], null-termi-   * 01050000
 *                               nated string to receive the SQLSTATE.* 01060000
 *              - *message     : pointer to a char[70], null-termi-   * 01070000
 *                               nated string to receive a diagnostic * 01080000
 *                               message if one is generated by this  * 01090000
 *                               function.                            * 01100000
 *                                                                    * 01110000
 * Normal Exit: Return Code: SQLSTATE = 00000                         * 01120000
 *              - Message: none                                       * 01130000
 *                                                                    * 01140000
 *  Error Exit: Return Code: SQLSTATE = 38601                         * 01150000
 *              - Message: DSN8DUCD Error: No input date entered      * 01160000
 *              - Message: DSN8DUCD Error: No input format entered    * 01170000
 *              - Message: DSN8DUCD Error: No output format entered   * 01180000
 *                                                                    * 01190000
 *              Return Code: SQLSTATE = 38602                         * 01200000
 *              - Message: DSN8DUCD Error: Unknown input format       * 01210000
 *                                         specified                  * 01220000
 *              - Message: DSN8DUCD Error: Value for year is incor-   * 01230000
 *                                         rect or does not conform   * 01240000
 *                                         to input format            * 01250000
 *              - Message: DSN8DUCD Error: Value for month is incor-  * 01260000
 *                                         rect or does not conform   * 01270000
 *                                         to input format            * 01280000
 *              - Message: DSN8DUCD Error: Value for day is incor-    * 01290000
 *                                         rect or does not conform   * 01300000
 *                                         to input format            * 01310000
 *                                                                    * 01320000
 *              Return Code: SQLSTATE = 38602                         * 01330000
 *              - Message: DSN8DUCD Error: Unknown output format      * 01340000
 *                                         specified                  * 01350000
 *                                                                    * 01370000
 *    External References:                                            * 01380000
 *             - Routines/Services: None                              * 01390000
 *             - Data areas       : None                              * 01400000
 *             - Control blocks   : None                              * 01410000
 *                                                                    * 01420000
 *                                                                    * 01430000
 *  Pseudocode:                                                       * 01440000
 *   DSN8DUCD:                                                        * 01450000
 *   - Issue sqlstate 38601 and a diagnostic message if no input date * 01460000
 *     was provided.                                                  * 01470000
 *   - Issue sqlstate 38601 and a diagnostic message if no input for- * 01480000
 *     mat was provided.                                              * 01490000
 *   - Issue sqlstate 38601 and a diagnostic message if no output     * 01500000
 *     format was provided.                                           * 01510000
 *   - Call deconDate to deconstruct the input date into year, month, * 01520000
 *     and day components according to the input format.              * 01530000
 *   - Call reconDate to create an output date from the  year, month, * 01540000
 *     and day components according to the output format.             * 01550000
 *   - If no errors, unset null indicators, and return SQLSTATE 00000 * 01560000
 *     else set null indicator and return null date out.              * 01570000
 *   End DSN8DUCD                                                     * 01580000
 *                                                                    * 01590000
 *   deconDate                                                        * 01600000
 *   - Parse day, month, and year (sequence unknown) components from  * 01610000
 *     the input date by breaking on delimiters (blank, /, ., and -). * 01620000
 *   - Use the input format to determine sequence of date components. * 01630000
 *     - if format invalid, issue SQLSTATE 38602 and a diag. message  * 01640000
 *   - Call checkDay to validate the day component                    * 01650000
 *     - if not valid day, issue SQLSTATE 38602 and a diag. message   * 01660000
 *   - Call checkMonth to validate the month component and convert it * 01670000
 *     (if required) from a calendar month name or roman numeral to   * 01680000
 *     a month number (1-12).                                         * 01690000
 *     - if not valid month, issue SQLSTATE 38602 and a diag. message * 01700000
 *   - Call checkYear to validate the year component.                 * 01710000
 *     - if not valid year, issue SQLSTATE 38602 and a diag. message  * 01720000
 *   End deconDate                                                    * 01730000
 *                                                                    * 01740000
 *   reconDate                                                        * 01750000
 *   - Use the output format to edit and sequence the date components * 01760000
 *     - call add0prefix to prepend leading 0's to the day and/or     * 01770000
 *       month component(s), as appropriate                           * 01780000
 *     - or call remove0prefix to drop leading 0's from the day and/  * 01790000
 *       or month component(s), as appropriate                        * 01800000
 *     - call nameMonth to convert the month number (1-12) to calen-  * 01810000
 *       dar name, if appropriate                                     * 01820000
 *     - call romanMonth to convert the month number (1-12) to roman  * 01830000
 *       numeral, if appropriate                                      * 01840000
 *     - call addCentury to convert a non-century year to century     * 01850000
 *       date, if appropriate                                         * 01860000
 *     - call removeCentury to convert a century year to non-century  * 01870000
 *       if appropriate                                               * 01880000
 *       - convert the month to a calendar name or roman numeral, if  * 01890000
 *         appropriate                                                * 01900000
 *       - convert the year to a non-century format, if appropriate   * 01910000
 *     - if output format is invalid, issue SQLSTATE 38603 and a      * 01920000
 *       diagnostic message                                           * 01930000
 *   - Call buildDate to create the output date from the edited, re-  * 01940000
 *     sequenced date components                                      * 01950000
 *   End reconDate                                                    * 01960000
 *                                                                    * 01970000
 *   buildDate                                                        * 01980000
 *   - Generate the date out by concatenating the date componentents  * 01990000
 *     (month, day, and year) with intervening delimiters (blank, .,  * 02000000
 *     /, or -) in the sequence directed by reconDate                 * 02010000
 *   End buildDate                                                    * 02020000
 *                                                                    * 02030000
 *   nameMonth                                                        * 02040000
 *   - convert a month in the standard form, 1-12, to the correspond- * 02050000
 *     ing caldendar month name.                                      * 02060000
 *   End nameMonth                                                    * 02070000
 *                                                                    * 02080000
 *   unnameMonth                                                      * 02090000
 *   - convert a calendar month name to the corresponding month no.   * 02100000
 *     in the standard form, 1-12.                                    * 02110000
 *   End unnameMonth                                                  * 02120000
 *                                                                    * 02130000
 *   romanMonth                                                       * 02140000
 *   - convert a month in the standard form, 1-12, to the correspond- * 02150000
 *     ing roman numeral, I-XII.                                      * 02160000
 *   End romanMonth                                                   * 02170000
 *                                                                    * 02180000
 *   unromanMonth                                                     * 02190000
 *   - convert a roman numeral (I-XII) to the corresponding month no. * 02200000
 *     in the standard form, 1-12.                                    * 02210000
 *   End unromanMonth                                                 * 02220000
 *                                                                    * 02230000
 *   checkYear                                                        * 02240000
 *   - Verify that the year component of the input date is one of the * 02250000
 *     following, in accordance with the input format:                * 02260000
 *     - A valid century year (0000-9999)                             * 02270000
 *     - A valid non-century year (00-99)                             * 02280000
 *   - If not valid, set error flag and return null value for year    * 02290000
 *   End checkYear                                                    * 02300000
 *                                                                    * 02310000
 *   checkMonth                                                       * 02320000
 *   - Verify the month component of the input date in accordance     * 02330000
 *     with the input format:                                         * 02340000
 *     - if the month is a calendar name, call unnameMonth to convert * 02350000
 *       it to a month number (1-12).                                 * 02360000
 *     - if the month is a roman numeral, call unromanMonth to con-   * 02370000
 *       vert it to a month number (1-12).                            * 02380000
 *   - If not valid, set error flag and return null value for month   * 02390000
 *   End checkMonth                                                   * 02400000
 *                                                                    * 02410000
 *   checkDay                                                         * 02420000
 *   - Verify that the day component of the input date is one or two  * 02430000
 *     numeric characters                                             * 02440000
 *   - If not valid, set error flag and return null value for day     * 02450000
 *   End checkDay                                                     * 02460000
 *                                                                    * 02470000
 *   add0prefix                                                       * 02480000
 *   - prepend a day or month with a leading 0 if it is less than 10  * 02490000
 *   End add0prefix                                                   * 02500000
 *                                                                    * 02510000
 *   remove0prefix                                                    * 02520000
 *   - strip leading zero from a day or month if it is less than 10   * 02530000
 *   End remove0prefix                                                * 02540000
 *                                                                    * 02550000
 *   addCentury                                                       * 02560000
 *   - If the year component is non-century format, prepend it with   * 02570000
 *     the current century.                                           * 02580000
 *   End addCentury                                                   * 02590000
 *                                                                    * 02600000
 *   removeCentury                                                    * 02610000
 *   - If the year component is century format, strip off the century * 02620000
 *     portion.                                                       * 02630000
 *   End removeCentury                                                * 02640000
 *                                                                    * 02650000
 *                                                                    * 02660000
 *********************************************************************/ 02670000
                                                                        02680000
 #pragma linkage(DSN8DUCD,fetchable)                                    02682990
                                                                        02685980
 /********************** C library definitions ***********************/ 02690000
 #include <stdio.h>                                                     02700000
 #include <string.h>                                                    02710000
 #include <ctype.h>                                                     02720000
 #include <time.h>                                                      02730000
                                                                        02740000
 /***************************** Equates ******************************/ 02750000
 #define     NULLCHAR     '\0'         /* Null character             */ 02760000
                                                                        02770000
 #define     MATCH          0          /* Comparison status: Equal   */ 02780000
 #define     NOT_OK         0          /* Run status indicator: Error*/ 02790000
 #define     OK             1          /* Run status indicator: Good */ 02800000
                                                                        02810000
                                                                        02820000
 /************************* Global constants *************************/ 02830000
 char        *char0 = "0";                                              02840000
                                                                        02850000
 char        *delimiters               /* Valid format delimiters    */ 02860000
             = " .-/";                                                  02870000
                                                                        02880000
 char        *monthNames[12]           /* Month names                */ 02890000
             = { "January",  "February", "March",                       02900000
                 "April",    "May",      "June",                        02910000
                 "July",     "August",   "September",                   02920000
                 "October",  "November", "December" };                  02930000
                                                                        02940000
 char        *monthNums[12]            /* Month numbers (as strings) */ 02950000
             = { "1",        "2",        "3",                           02960000
                 "4",        "5",        "6",                           02970000
                 "7",        "8",        "9",                           02980000
                 "10",       "11",       "12" };                        02990000
                                                                        03000000
 char        *romanNums[12]            /* Roman numerals             */ 03010000
             = { "I",        "II",       "III",                         03020000
                 "IV",       "V",        "VI",                          03030000
                 "VII",      "VIII",     "IX",                          03040000
                 "X",        "XI",       "XII" };                       03050000
                                                                        03060000
                                                                        03070000
 /*********************** DSN8DUCD functions *************************/ 03080000
 void DSN8DUCD                         /* main routine               */ 03090000
 ( char        *dateIn,                /* in: date to be converted   */ 03100000
   char        *formatIn,              /* in: format of dateIn       */ 03110000
   char        *formatOut,             /* in: format for dateOut     */ 03120000
   char        *dateOut,               /* out: reformatted date      */ 03130000
   short int   *nullDateIn,            /* in: indic var for dateIn   */ 03140000
   short int   *nullFormatIn,          /* in: indic var for formatIn */ 03150000
   short int   *nullFormatOut,         /* in: indic var, formatOut   */ 03160000
   short int   *nullDateOut,           /* out: indic var for dateOut */ 03170000
   char        *sqlstate,              /* out: SQLSTATE              */ 03180000
   char        *fnName,                /* in: family name of function*/ 03190000
   char        *specificName,          /* in: specific name of func  */ 03200000
   char        *message                /* out: diagnostic message    */ 03210000
 );                                                                     03220000
                                                                        03230000
 int deconDate                         /* get yr, mo, dy from dateIn */ 03240000
 ( char        *yr,                    /* out: year component        */ 03250000
   char        *mo,                    /* out: month component       */ 03260000
   char        *dy,                    /* out: day component         */ 03270000
   char        *message,               /* out: diagnostic message    */ 03280000
   char        *sqlstate,              /* out: SQLSTATE              */ 03290000
   char        *dateIn,                /* in: inputted date string   */ 03300000
   char        *fmtIn                  /* in: format of dateIn       */ 03310000
 );                                                                     03320000
                                                                        03330000
 int reconDate                         /* get dateOut from yr,mo,dy  */ 03340000
 ( char        *dateOut,               /* out: reformatted date str  */ 03350000
   char        *message,               /* out: diagnostic message    */ 03360000
   char        *sqlstate,              /* out: SQLSTATE              */ 03370000
   char        *yr,                    /* in: year component         */ 03380000
   char        *mo,                    /* in: month component        */ 03390000
   char        *dy,                    /* in: day component          */ 03400000
   char        *fmtOut                 /* in: format for dateOut     */ 03410000
 );                                                                     03420000
                                                                        03430000
 void buildDate                        /* build date from parts      */ 03440000
 ( char        *dtOut,                 /* out: date                  */ 03450000
   char        *d1,                    /* in: year, month, or day    */ 03460000
   char        *d2,                    /* in: year, month, or day    */ 03470000
   char        *d3,                    /* in: year, month, or day    */ 03480000
   char        *delim                  /* in: delimiter              */ 03490000
 );                                                                     03500000
                                                                        03510000
 void add0prefix                       /* add leading zero to string */ 03520000
 ( char        *str3                   /* in/out: string to prefix   */ 03530000
 );                                                                     03540000
                                                                        03550000
 void remove0prefix                    /* strips leading zeroes      */ 03560000
 ( char        *string                 /* in/out: string to strip    */ 03570000
 );                                                                     03580000
                                                                        03590000
 int nameMonth                         /* converts month num to name */ 03600000
 ( char        *monthIn                /* in/out: month to convert   */ 03610000
 );                                                                     03620000
                                                                        03630000
 int unnameMonth                       /* converts month name to num */ 03640000
 ( char        *monthIn                /* in/out: month to convert   */ 03650000
 );                                                                     03660000
                                                                        03670000
 int romanMonth                        /* converts month# to roman#  */ 03680000
 ( char        *monthIn                /* in/out: month to convert   */ 03690000
 );                                                                     03700000
                                                                        03710000
 int unromanMonth                      /* converts roman# to month#  */ 03720000
 ( char        *monthIn                /* in/out: month to convert   */ 03730000
 );                                                                     03740000
                                                                        03750000
 int checkYear                         /* verify/standardize yearIn  */ 03760000
 ( char        *yearOut,               /* out: 4-digit yr, validated */ 03770000
   char        *yearIn,                /* in: 2- or 4-digit year     */ 03780000
   char        *style                  /* in: style of yearIn        */ 03790000
 );                                                                     03800000
                                                                        03810000
 int checkMonth                        /* verify/standardize monthIn */ 03820000
 ( char        *monthOut,              /* out: month#, validated     */ 03830000
   char        *monthIn,               /* in: month name, #, roman#  */ 03840000
   char        *style                  /* in: style of monthIn       */ 03850000
 );                                                                     03860000
                                                                        03870000
 int checkDay                          /* verify/standardize dayIn   */ 03880000
 ( char        *dayOut,                /* out: day, validated        */ 03890000
   char        *dayIn                  /* in: day number             */ 03900000
 );                                                                     03910000
                                                                        03920000
 void addCentury                       /* adds century to yearIn     */ 03930000
 ( char        *yearIn                 /* in/out: year               */ 03940000
 );                                                                     03950000
                                                                        03960000
 void removeCentury                    /* strip century from yearIn  */ 03970000
 ( char        *yearIn                 /* in/out: year               */ 03980000
 );                                                                     03990000
                                                                        04000000
 /********************************************************************/ 04010000
 /*************************** main routine ***************************/ 04020000
 /********************************************************************/ 04030000
 void DSN8DUCD                         /* main routine               */ 04040000
 ( char        *dateIn,                /* in: date to be converted   */ 04050000
   char        *formatIn,              /* in: format of dateIn       */ 04060000
   char        *formatOut,             /* in: format for dateOut     */ 04070000
   char        *dateOut,               /* out: reformatted date      */ 04080000
   short int   *nullDateIn,            /* in: indic var for dateIn   */ 04090000
   short int   *nullFormatIn,          /* in: indic var for formatIn */ 04100000
   short int   *nullFormatOut,         /* in: indic var, formatOut   */ 04110000
   short int   *nullDateOut,           /* out: indic var for dateOut */ 04120000
   char        *sqlstate,              /* out: SQLSTATE              */ 04130000
   char        *fnName,                /* in: family name of function*/ 04140000
   char        *specificName,          /* in: specific name of func  */ 04150000
   char        *message                /* out: diagnostic message    */ 04160000
 )                                                                      04170000
 /********************************************************************* 04180000
 *                                                                    * 04190000
 * Assumptions:                                                       * 04200000
 * - *dateIn        points to a char[18], null-terminated string      * 04210000
 * - *formatIn,     points to a char[14], null-terminated string      * 04220000
 * - *formatOut     points to a char[14], null-terminated string      * 04230000
 * - *dateOut       points to a char[18], null-terminated string      * 04240000
 * - *nullDateIn    points to a short integer                         * 04250000
 * - *nullFormatIn  points to a short integer                         * 04260000
 * - *nullFormatOut points to a short integer                         * 04270000
 * - *nullDateOut   points to a short integer                         * 04280000
 * - *sqlstate      points to a char[06], null-terminated string      * 04290000
 * - *fnName        points to a char[138], null-terminated string     * 04305990
 * - *specificName  points to a char[129], null-terminated string     * 04311980
 * - *message       points to a char[70], null-terminated string      * 04320000
 *********************************************************************/ 04330000
 {                                                                      04340000
   /************************ Local variables *************************/ 04350000
   short int   i;                      /* loop control vars          */ 04360000
   char        year[5];                /* gets year from dateIn      */ 04370000
   char        month[10];              /* gets month from dateIn     */ 04380000
   char        day[3];                 /* gets day from dateIn       */ 04390000
                                                                        04400000
   short int   status = OK;            /* DSN8DUCD run status        */ 04410000
                                                                        04420000
   /******************************************************************* 04430000
   * Verify that an input date, its current format, and its new format* 04440000
   * have been passed in.                                             * 04450000
   *******************************************************************/ 04460000
   if( *nullDateIn || ( strlen( dateIn ) == 0 ) )                       04470000
     {                                                                  04480000
       status = NOT_OK;                                                 04490000
       strcpy( message,                                                 04500000
               "DSN8DUCD Error: No input date entered" );               04510000
       strcpy( sqlstate, "38601" );                                     04520000
     }                                                                  04530000
   else if( *nullFormatIn || ( strlen( formatIn ) == 0 ) )              04540000
     {                                                                  04550000
       status = NOT_OK;                                                 04560000
       strcpy( message,                                                 04570000
               "DSN8DUCD Error: No input format entered" );             04580000
       strcpy( sqlstate, "38601" );                                     04590000
     }                                                                  04600000
   else if( *nullFormatOut || ( strlen( formatOut ) == 0 ) )            04610000
     {                                                                  04620000
       status = NOT_OK;                                                 04630000
       strcpy( message,                                                 04640000
               "DSN8DUCD Error: No output format entered" );            04650000
       strcpy( sqlstate, "38601" );                                     04660000
     }                                                                  04670000
                                                                        04680000
   /******************************************************************* 04690000
   * Use formatIn to deconstruct date in into year, month, and day    * 04700000
   *******************************************************************/ 04710000
   if( status == OK )                                                   04720000
     status = deconDate( year, month, day, message, sqlstate,           04730000
                         dateIn, formatIn );                            04740000
                                                                        04750000
   /******************************************************************* 04760000
   * Use formatOut to reconstruct date from year, month, and day      * 04770000
   *******************************************************************/ 04780000
   if( status == OK )                                                   04790000
     status = reconDate( dateOut, message, sqlstate,                    04800000
                         year, month, day, formatOut );                 04810000
                                                                        04820000
   /******************************************************************* 04830000
   * If conversion was successful, clear the message buffer and sql-  * 04840000
   * state, and unset the SQL null indicator for dateOut.             * 04850000
   *******************************************************************/ 04860000
   if( status == OK )                                                   04870000
     {                                                                  04880000
       *nullDateOut = 0;                                                04890000
       message[0] = NULLCHAR;                                           04900000
       strcpy( sqlstate,"00000" );                                      04910000
     }                                                                  04920000
   /******************************************************************* 04930000
   * If errors occurred, clear the dateOut buffer and set the SQL null* 04940000
   * indicator.  A diagnostic message and the SQLSTATE have been set  * 04950000
   * where the error was detected.                                    * 04960000
   *******************************************************************/ 04970000
   else                                                                 04980000
     {                                                                  04990000
       dateOut[0] = NULLCHAR;                                           05000000
       *nullDateOut = -1;                                               05010000
     }                                                                  05020000
                                                                        05030000
   return;                                                              05040000
 } /* end of DSN8DUCD */                                                05050000
                                                                        05060000
                                                                        05070000
 /********************************************************************/ 05080000
 /***************************** Functions ****************************/ 05090000
 /********************************************************************/ 05100000
 int deconDate                         /* get yr, mo, dy from dateIn */ 05110000
 ( char        *yr,                    /* out: year component        */ 05120000
   char        *mo,                    /* out: month component       */ 05130000
   char        *dy,                    /* out: day component         */ 05140000
   char        *message,               /* out: diagnostic message    */ 05150000
   char        *sqlstate,              /* out: SQLSTATE              */ 05160000
   char        *dateIn,                /* in: inputted date string   */ 05170000
   char        *fmtIn                  /* in: format of dateIn       */ 05180000
 )                                                                      05190000
 /********************************************************************* 05200000
 * Deconstructs *dateIn into *yr, *mo, and *dy according to *fmtIn.   * 05210000
 * Returns 1 if deconstruction succeeds, otherwise places diagnostic  * 05220000
 * text in *message and returns 0.                                    * 05230000
 *********************************************************************/ 05240000
 {                                                                      05250000
   /************************ Local variables *************************/ 05260000
                                                                        05270000
   short int   func_status = OK;       /* function status indicator  */ 05280000
   short int   yrStatus = OK;          /* indicates if year    is OK */ 05290000
   short int   moStatus = OK;          /*     "     "  month   "  "  */ 05300000
   short int   dyStatus = OK;          /*     "     "  day     "  "  */ 05310000
   short int   ftStatus = OK;          /*     "     "  format  "  "  */ 05320000
                                                                        05330000
   char        workDateIn[18];         /* work copy of dateIn        */ 05340000
   char        *token;                 /* Value from token parser    */ 05350000
                                                                        05360000
   char        tok1[17];               /* Gets 1st date component    */ 05370000
   char        tok2[17];               /*  "   2nd  "       "        */ 05380000
   char        tok3[17];               /*  "   3rd  "       "        */ 05390000
                                                                        05400000
   /******************************************************************* 05410000
   * Parse day, month, and year (order unknown) from dateIn           * 05420000
   *******************************************************************/ 05430000
   strcpy( workDateIn,dateIn );                                         05440000
   token = strtok( workDateIn," .-/" );                                 05450000
   strcpy( tok1,token );                                                05460000
   token = strtok( NULL," .-/" );                                       05470000
   strcpy( tok2,token );                                                05480000
   token = strtok( NULL," .-/" );                                       05490000
   strcpy( tok3,token );                                                05500000
                                                                        05510000
   /******************************************************************* 05520000
   * Use fmtIn to check and set year, month, and day from date tokens * 05530000
   *******************************************************************/ 05540000
   if( ( strcmp( fmtIn,"D MONTH YY" ) == MATCH )                        05550000
    || ( strcmp( fmtIn,"DD MONTH YY" ) == MATCH ) )                     05560000
     {                                                                  05570000
       dyStatus = checkDay( dy,tok1 );                                  05580000
       moStatus = checkMonth( mo,tok2,"MONTH" );                        05590000
       yrStatus = checkYear( yr,tok3,"YY" );                            05600000
     }                                                                  05610000
   else if( ( strcmp( fmtIn,"D MONTH YYYY" ) == MATCH )                 05620000
         || ( strcmp( fmtIn,"DD MONTH YYYY" ) == MATCH ) )              05630000
     {                                                                  05640000
       dyStatus = checkDay( dy,tok1 );                                  05650000
       moStatus = checkMonth( mo,tok2,"MONTH" );                        05660000
       yrStatus = checkYear( yr,tok3,"YYYY" );                          05670000
     }                                                                  05680000
   else if( ( strcmp( fmtIn,"D.M.YY" ) == MATCH )                       05690000
         || ( strcmp( fmtIn,"DD.MM.YY" ) == MATCH )                     05700000
         || ( strcmp( fmtIn,"D-M-YY" ) == MATCH )                       05710000
         || ( strcmp( fmtIn,"DD-MM-YY" ) == MATCH )                     05720000
         || ( strcmp( fmtIn,"D/M/YY" ) == MATCH )                       05730000
         || ( strcmp( fmtIn,"DD/MM/YY" ) == MATCH ) )                   05740000
     {                                                                  05750000
       dyStatus = checkDay( dy,tok1 );                                  05760000
       moStatus = checkMonth( mo,tok2,"M/MM" );                         05770000
       yrStatus = checkYear( yr,tok3,"YY" );                            05780000
     }                                                                  05790000
   else if( ( strcmp( fmtIn,"D.M.YYYY" ) == MATCH )                     05800000
         || ( strcmp( fmtIn,"DD.MM.YYYY" ) == MATCH )                   05810000
         || ( strcmp( fmtIn,"D-M-YYYY" ) == MATCH )                     05820000
         || ( strcmp( fmtIn,"DD-MM-YYYY" ) == MATCH )                   05830000
         || ( strcmp( fmtIn,"D/M/YYYY" ) == MATCH )                     05840000
         || ( strcmp( fmtIn,"DD/MM/YYYY" ) == MATCH ) )                 05850000
     {                                                                  05860000
       dyStatus = checkDay( dy,tok1 );                                  05870000
       moStatus = checkMonth( mo,tok2,"M/MM" );                         05880000
       yrStatus = checkYear( yr,tok3,"YYYY" );                          05890000
     }                                                                  05900000
   else if( ( strcmp( fmtIn,"M/D/YY" ) == MATCH )                       05910000
         || ( strcmp( fmtIn,"MM/DD/YY" ) == MATCH ) )                   05920000
     {                                                                  05930000
       moStatus = checkMonth( mo,tok1,"M/MM" );                         05940000
       dyStatus = checkDay( dy,tok2 );                                  05950000
       yrStatus = checkYear( yr,tok3,"YY" );                            05960000
     }                                                                  05970000
   else if( ( strcmp( fmtIn,"M/D/YYYY" ) == MATCH )                     05980000
         || ( strcmp( fmtIn,"MM/DD/YYYY" ) == MATCH ) )                 05990000
     {                                                                  06000000
       moStatus = checkMonth( mo,tok1,"M/MM" );                         06010000
       dyStatus = checkDay( dy,tok2 );                                  06020000
       yrStatus = checkYear( yr,tok3,"YYYY" );                          06030000
     }                                                                  06040000
   else if( ( strcmp( fmtIn,"YY/M/D" ) == MATCH )                       06050000
         || ( strcmp( fmtIn,"YY/MM/DD" ) == MATCH )                     06060000
         || ( strcmp( fmtIn,"YY.M.D" ) == MATCH )                       06070000
         || ( strcmp( fmtIn,"YY.MM.DD" ) == MATCH ) )                   06080000
     {                                                                  06090000
       yrStatus = checkYear( yr,tok1,"YY" );                            06100000
       moStatus = checkMonth( mo,tok2,"M/MM" );                         06110000
       dyStatus = checkDay( dy,tok3 );                                  06120000
     }                                                                  06130000
   else if( ( strcmp( fmtIn,"YYYY/M/D" ) == MATCH )                     06140000
         || ( strcmp( fmtIn,"YYYY/MM/DD" ) == MATCH )                   06150000
         || ( strcmp( fmtIn,"YYYY.M.D" ) == MATCH )                     06160000
         || ( strcmp( fmtIn,"YYYY.MM.DD" ) == MATCH )                   06170000
         || ( strcmp( fmtIn,"YYYY-M-D" ) == MATCH )                     06180000
         || ( strcmp( fmtIn,"YYYY-MM-DD" ) == MATCH ) )                 06190000
     {                                                                  06200000
       yrStatus = checkYear( yr,tok1,"YYYY" );                          06210000
       moStatus = checkMonth( mo,tok2,"M/MM" );                         06220000
       dyStatus = checkDay( dy,tok3 );                                  06230000
     }                                                                  06240000
   else if( ( strcmp( fmtIn,"YYYY-D-XX" ) == MATCH )                    06250000
         || ( strcmp( fmtIn,"YYYY-DD-XX" ) == MATCH ) )                 06260000
     {                                                                  06270000
       yrStatus = checkYear( yr,tok1,"YYYY" );                          06280000
       dyStatus = checkDay( dy,tok2 );                                  06290000
       moStatus = checkMonth( mo,tok3,"XX" );                           06300000
     }                                                                  06310000
   else if( ( strcmp( fmtIn,"YYYY-XX-D" ) == MATCH )                    06320000
         || ( strcmp( fmtIn,"YYYY-XX-DD" ) == MATCH ) )                 06330000
     {                                                                  06340000
       yrStatus = checkYear( yr,tok1,"YYYY" );                          06350000
       moStatus = checkMonth( mo,tok2,"XX" );                           06360000
       dyStatus = checkDay( dy,tok3 );                                  06370000
     }                                                                  06380000
   else /* date-in format is invalid or unknown */                      06390000
     ftStatus = NOT_OK;                                                 06400000
                                                                        06410000
   /******************************************************************* 06420000
   * set up error handling                                            * 06430000
   *******************************************************************/ 06440000
   func_status = NOT_OK;                                                06450000
   strcpy( message,"DSN8DUCD Error: " );                                06460000
   strcpy( sqlstate, "38602" );                                         06470000
                                                                        06480000
   /******************************************************************* 06490000
   * if error detected, issue diagnostic message and return NOT_OK    * 06500000
   *******************************************************************/ 06510000
   if( ftStatus != OK )                                                 06520000
     strcpy( message,                                                   06530000
             "Unknown input format specified" );                        06540000
   else if( yrStatus != OK )                                            06550000
     strcpy( message,                                                   06560000
             "Value for year "                                          06570000
             "is incorrect or does not "                                06580000
             "conform to input format" );                               06590000
   else if( moStatus != OK )                                            06600000
     strcpy( message,                                                   06610000
             "Value for month "                                         06620000
             "is incorrect or does not "                                06630000
             "conform to input format " );                              06640000
   else if( dyStatus != OK )                                            06650000
     strcpy( message,                                                   06660000
             "Value for day "                                           06670000
             "is incorrect or does not "                                06680000
             "conform to input format " );                              06690000
                                                                        06700000
   /******************************************************************* 06710000
   * if no error detected, clear message and sqlstate and return OK   * 06720000
   *******************************************************************/ 06730000
   else                                                                 06740000
     {                                                                  06750000
       *message = NULLCHAR;                                             06760000
       func_status = OK;                                                06770000
       strcpy( sqlstate, "00000" );                                     06780000
     }                                                                  06790000
                                                                        06800000
   return( func_status );                                               06810000
 }  /* end deconDate */                                                 06820000
                                                                        06830000
 int reconDate                         /* get dateOut from yr,mo,dy  */ 06840000
 ( char        *dateOut,               /* out: reformatted date str  */ 06850000
   char        *message,               /* out: diagnostic message    */ 06860000
   char        *sqlstate,              /* out: SQLSTATE              */ 06870000
   char        *yr,                    /* in: year component         */ 06880000
   char        *mo,                    /* in: month component        */ 06890000
   char        *dy,                    /* in: day component          */ 06900000
   char        *fmtOut                 /* in: format for dateOut     */ 06910000
 )                                                                      06920000
 /********************************************************************* 06930000
 * Reconstructs *yr, *mo, and *dy into *dateOut according to *fmtOut. * 06940000
 * Returns 1 if reconstruction succeeds, otherwise places diagnostic  * 06950000
 * text in *message and returns 0.                                    * 06960000
 *********************************************************************/ 06970000
 {                                                                      06980000
   /************************ Local variables *************************/ 06990000
                                                                        07000000
   short int   func_status = OK;       /* function status indicator  */ 07010000
                                                                        07020000
   /******************************************************************* 07030000
   * Use fmtOut to reformat date from year, month, and day tokens     * 07040000
   *******************************************************************/ 07050000
   if( strcmp( fmtOut,"D MONTH YY" ) == MATCH )                         07060000
     {                                                                  07070000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 07080000
       nameMonth( mo );                /* convert month no. to name  */ 07090000
       removeCentury( yr );            /* strip century from year    */ 07100000
       buildDate( dateOut, dy, mo, yr, " " );                           07110000
     }                                                                  07120000
   else if( strcmp( fmtOut,"DD MONTH YY" ) == MATCH )                   07130000
     {                                                                  07140000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 07150000
       nameMonth( mo );                /* convert month no. to name  */ 07160000
       removeCentury( yr );            /* strip century from year    */ 07170000
       buildDate( dateOut, dy, mo, yr, " " );                           07180000
     }                                                                  07190000
   else if( strcmp( fmtOut,"D MONTH YYYY" ) == MATCH )                  07200000
     {                                                                  07210000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 07220000
       nameMonth( mo );                /* convert month no. to name  */ 07230000
       addCentury( yr );               /* ensure year has century    */ 07240000
       buildDate( dateOut, dy, mo, yr, " " );                           07250000
     }                                                                  07260000
   else if( strcmp( fmtOut,"DD MONTH YYYY" ) == MATCH )                 07270000
     {                                                                  07280000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 07290000
       nameMonth( mo );                /* convert month no. to name  */ 07300000
       addCentury( yr );               /* ensure year has century    */ 07310000
       buildDate( dateOut, dy, mo, yr, " " );                           07320000
     }                                                                  07330000
   else if( strcmp( fmtOut,"D.M.YY" ) == MATCH )                        07340000
     {                                                                  07350000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 07360000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 07370000
       removeCentury( yr );            /* strip century from year    */ 07380000
       buildDate( dateOut, dy, mo, yr, "." );                           07390000
     }                                                                  07400000
   else if( strcmp( fmtOut,"DD.MM.YY" ) == MATCH )                      07410000
     {                                                                  07420000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 07430000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 07440000
       removeCentury( yr );            /* strip century from year    */ 07450000
       buildDate( dateOut, dy, mo, yr, "." );                           07460000
     }                                                                  07470000
   else if( strcmp( fmtOut,"D-M-YY" ) == MATCH )                        07480000
     {                                                                  07490000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 07500000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 07510000
       removeCentury( yr );            /* strip century from year    */ 07520000
       buildDate( dateOut, dy, mo, yr, "-" );                           07530000
     }                                                                  07540000
   else if( strcmp( fmtOut,"DD-MM-YY" ) == MATCH )                      07550000
     {                                                                  07560000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 07570000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 07580000
       removeCentury( yr );            /* strip century from year    */ 07590000
       buildDate( dateOut, dy, mo, yr, "-" );                           07600000
     }                                                                  07610000
   else if( strcmp( fmtOut,"D/M/YY" ) == MATCH )                        07620000
     {                                                                  07630000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 07640000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 07650000
       removeCentury( yr );            /* strip century from year    */ 07660000
       buildDate( dateOut, dy, mo, yr, "/" );                           07670000
     }                                                                  07680000
   else if( strcmp( fmtOut,"DD/MM/YY" ) == MATCH )                      07690000
     {                                                                  07700000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 07710000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 07720000
       removeCentury( yr );            /* strip century from year    */ 07730000
       buildDate( dateOut, dy, mo, yr, "/" );                           07740000
     }                                                                  07750000
   else if( strcmp( fmtOut,"D.M.YYYY" ) == MATCH )                      07760000
     {                                                                  07770000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 07780000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 07790000
       addCentury( yr );               /* ensure year has century    */ 07800000
       buildDate( dateOut, dy, mo, yr, "." );                           07810000
     }                                                                  07820000
   else if( strcmp( fmtOut,"DD.MM.YYYY" ) == MATCH )                    07830000
     {                                                                  07840000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 07850000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 07860000
       addCentury( yr );               /* ensure year has century    */ 07870000
       buildDate( dateOut, dy, mo, yr, "." );                           07880000
     }                                                                  07890000
   else if( strcmp( fmtOut,"D-M-YYYY" ) == MATCH )                      07900000
     {                                                                  07910000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 07920000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 07930000
       addCentury( yr );               /* ensure year has century    */ 07940000
       buildDate( dateOut, dy, mo, yr, "-" );                           07950000
     }                                                                  07960000
   else if( strcmp( fmtOut,"DD-MM-YYYY" ) == MATCH )                    07970000
     {                                                                  07980000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 07990000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 08000000
       addCentury( yr );               /* ensure year has century    */ 08010000
       buildDate( dateOut, dy, mo, yr, "-" );                           08020000
     }                                                                  08030000
   else if( strcmp( fmtOut,"D/M/YYYY" ) == MATCH )                      08040000
     {                                                                  08050000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 08060000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 08070000
       addCentury( yr );               /* ensure year has century    */ 08080000
       buildDate( dateOut, dy, mo, yr, "/" );                           08090000
     }                                                                  08100000
   else if( strcmp( fmtOut,"DD/MM/YYYY" ) == MATCH )                    08110000
     {                                                                  08120000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 08130000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 08140000
       addCentury( yr );               /* ensure year has century    */ 08150000
       buildDate( dateOut, dy, mo, yr, "/" );                           08160000
     }                                                                  08170000
   else if( strcmp( fmtOut,"M/D/YY" ) == MATCH )                        08180000
     {                                                                  08190000
       remove0prefix( mo );            /* strip leading 0 if day < 10*/ 08200000
       remove0prefix( dy );            /* strip leading 0 if mon < 10*/ 08210000
       removeCentury( yr );            /* strip century from year    */ 08220000
       buildDate( dateOut, mo, dy, yr, "/" );                           08230000
     }                                                                  08240000
   else if( strcmp( fmtOut,"MM/DD/YY" ) == MATCH )                      08250000
     {                                                                  08260000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 08270000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 08280000
       removeCentury( yr );            /* strip century from year    */ 08290000
       buildDate( dateOut, mo, dy, yr, "/" );                           08300000
     }                                                                  08310000
   else if( strcmp( fmtOut,"M/D/YYYY" ) == MATCH )                      08320000
     {                                                                  08330000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 08340000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 08350000
       addCentury( yr );               /* ensure year has century    */ 08360000
       buildDate( dateOut, mo, dy, yr, "/" );                           08370000
     }                                                                  08380000
   else if( strcmp( fmtOut,"MM/DD/YYYY" ) == MATCH )                    08390000
     {                                                                  08400000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 08410000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 08420000
       addCentury( yr );               /* ensure year has century    */ 08430000
       buildDate( dateOut, mo, dy, yr, "/" );                           08440000
     }                                                                  08450000
   else if( strcmp( fmtOut,"YY/M/D" ) == MATCH )                        08460000
     {                                                                  08470000
       removeCentury( yr );            /* strip century from year    */ 08480000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 08490000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 08500000
       buildDate( dateOut, yr, mo, dy, "/" );                           08510000
     }                                                                  08520000
   else if( strcmp( fmtOut,"YY/MM/DD" ) == MATCH )                      08530000
     {                                                                  08540000
       removeCentury( yr );            /* strip century from year    */ 08550000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 08560000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 08570000
       buildDate( dateOut, yr, mo, dy, "/" );                           08580000
     }                                                                  08590000
   else if( strcmp( fmtOut,"YY.M.D" ) == MATCH )                        08600000
     {                                                                  08610000
       removeCentury( yr );            /* strip century from year    */ 08620000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 08630000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 08640000
       buildDate( dateOut, yr, mo, dy, "." );                           08650000
     }                                                                  08660000
   else if( strcmp( fmtOut,"YY.MM.DD" ) == MATCH )                      08670000
     {                                                                  08680000
       removeCentury( yr );            /* strip century from year    */ 08690000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 08700000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 08710000
       buildDate( dateOut, yr, mo, dy, "." );                           08720000
     }                                                                  08730000
   else if( strcmp( fmtOut,"YYYY/M/D" ) == MATCH )                      08740000
     {                                                                  08750000
       addCentury( yr );               /* ensure year has century    */ 08760000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 08770000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 08780000
       buildDate( dateOut, yr, mo, dy, "/" );                           08790000
     }                                                                  08800000
   else if( strcmp( fmtOut,"YYYY/MM/DD" ) == MATCH )                    08810000
     {                                                                  08820000
       addCentury( yr );               /* ensure year has century    */ 08830000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 08840000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 08850000
       buildDate( dateOut, yr, mo, dy, "/" );                           08860000
     }                                                                  08870000
   else if( strcmp( fmtOut,"YYYY.M.D" ) == MATCH )                      08880000
     {                                                                  08890000
       addCentury( yr );               /* ensure year has century    */ 08900000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 08910000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 08920000
       buildDate( dateOut, yr, mo, dy, "." );                           08930000
     }                                                                  08940000
   else if( strcmp( fmtOut,"YYYY.MM.DD" ) == MATCH )                    08950000
     {                                                                  08960000
       addCentury( yr );               /* ensure year has century    */ 08970000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 08980000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 08990000
       buildDate( dateOut, yr, mo, dy, "." );                           09000000
     }                                                                  09010000
   else if( strcmp( fmtOut,"YYYY-M-D" ) == MATCH )                      09020000
     {                                                                  09030000
       addCentury( yr );               /* ensure year has century    */ 09040000
       remove0prefix( mo );            /* strip leading 0 if mon < 10*/ 09050000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 09060000
       buildDate( dateOut, yr, mo, dy, "-" );                           09070000
     }                                                                  09080000
   else if( strcmp( fmtOut,"YYYY-MM-DD" ) == MATCH )                    09090000
     {                                                                  09100000
       addCentury( yr );               /* ensure year has century    */ 09110000
       add0prefix( mo );               /* add leading 0 if mon < 10  */ 09120000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 09130000
       buildDate( dateOut, yr, mo, dy, "-" );                           09140000
     }                                                                  09150000
   else if( strcmp( fmtOut,"YYYY-D-XX" ) == MATCH )                     09160000
     {                                                                  09170000
       addCentury( yr );               /* ensure year has century    */ 09180000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 09190000
       romanMonth( mo );               /* convert month# to roman no.*/ 09200000
       buildDate( dateOut, yr, dy, mo, "-" );                           09210000
     }                                                                  09220000
   else if( strcmp( fmtOut,"YYYY-DD-XX" ) == MATCH )                    09230000
     {                                                                  09240000
       addCentury( yr );               /* ensure year has century    */ 09250000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 09260000
       romanMonth( mo );               /* convert month# to roman no.*/ 09270000
       buildDate( dateOut, yr, dy, mo, "-" );                           09280000
     }                                                                  09290000
   else if( strcmp( fmtOut,"YYYY-XX-D" ) == MATCH )                     09300000
     {                                                                  09310000
       addCentury( yr );               /* ensure year has century    */ 09320000
       romanMonth( mo );               /* convert month# to roman no.*/ 09330000
       remove0prefix( dy );            /* strip leading 0 if day < 10*/ 09340000
       buildDate( dateOut, yr, mo, dy, "-" );                           09350000
     }                                                                  09360000
   else if( strcmp( fmtOut,"YYYY-XX-DD" ) == MATCH )                    09370000
     {                                                                  09380000
       addCentury( yr );               /* ensure year has century    */ 09390000
       romanMonth( mo );               /* convert month# to roman no.*/ 09400000
       add0prefix( dy );               /* add leading 0 if day < 10  */ 09410000
       buildDate( dateOut, yr, mo, dy, "-" );                           09420000
     }                                                                  09430000
   else /* date-in format is invalid or unknown */                      09440000
     func_status = NOT_OK;                                              09450000
                                                                        09460000
   if( func_status != OK )                                              09470000
     {                                                                  09480000
       strcpy( sqlstate, "38603" );                                     09490000
       strcpy( message,                                                 09500000
               "Unknown output format specified" );                     09510000
     }                                                                  09520000
   else                                                                 09530000
     {                                                                  09540000
       *message = NULLCHAR;                                             09550000
       strcpy( sqlstate, "00000" );                                     09560000
     }                                                                  09570000
                                                                        09580000
   return( func_status );                                               09590000
 } /* end reconDate */                                                  09600000
                                                                        09610000
                                                                        09620000
 void buildDate                        /* build date from parts      */ 09630000
 ( char        *dtOut,                 /* out: date                  */ 09640000
   char        *d1,                    /* in: year, month, or day    */ 09650000
   char        *d2,                    /* in: year, month, or day    */ 09660000
   char        *d3,                    /* in: year, month, or day    */ 09670000
   char        *delim                  /* in: delimiter              */ 09680000
 )                                                                      09690000
 /********************************************************************* 09700000
 * Forms a date by concatenating d1, delim, d2, delim, and d3.        * 09710000
 *********************************************************************/ 09720000
 {                                                                      09730000
   strcpy( dtOut, d1 );                                                 09740000
   strcat( dtOut, delim );                                              09750000
   strcat( dtOut, d2 );                                                 09760000
   strcat( dtOut, delim );                                              09770000
   strcat( dtOut, d3 );                                                 09780000
 } /* end buildDate */                                                  09790000
                                                                        09800000
                                                                        09810000
 int nameMonth                         /* converts month num to name */ 09820000
 ( char        *monthIn                /* in/out: month to convert   */ 09830000
 )                                                                      09840000
 /********************************************************************* 09850000
 * Converts *monthIn from a number string to a name.  Returns 1 if    * 09860000
 * conversion succeeds, otherwise returns 0.                          * 09870000
 *********************************************************************/ 09880000
 {                                                                      09890000
   /************************ Local variables *************************/ 09900000
                                                                        09910000
   short int   i;                      /* loop control               */ 09920000
   short int   func_status = OK;       /* function status indicator  */ 09930000
                                                                        09940000
   /******************************************************************* 09950000
   * Strip leading zero (if any) from monthIn                         * 09960000
   *******************************************************************/ 09970000
   remove0prefix( monthIn );                                            09980000
                                                                        09990000
   /******************************************************************* 10000000
   * Look up *monthIn in the month number strings array               * 10010000
   *******************************************************************/ 10020000
   for( i=0; i<12 && strcmp( monthIn,monthNums[i] ) != MATCH; i++ );    10030000
                                                                        10040000
   /******************************************************************* 10050000
   * If found assign month name else set function error indicator     * 10060000
   *******************************************************************/ 10070000
   if( i < 12 )                                                         10080000
     strcpy( monthIn,monthNames[i] );                                   10090000
   else                                                                 10100000
    func_status = NOT_OK;                                               10110000
                                                                        10120000
   return( func_status );                                               10130000
                                                                        10140000
 } /* end nameMonth */                                                  10150000
                                                                        10160000
                                                                        10170000
 int unnameMonth                       /* converts month name to num */ 10180000
 ( char        *monthIn                /* in/out: month to convert   */ 10190000
 )                                                                      10200000
 /********************************************************************* 10210000
 * Converts *monthIn from a name to a number string.  Returns 1 if    * 10220000
 * conversion succeeds, otherwise returns 0.                          * 10230000
 *********************************************************************/ 10240000
 {                                                                      10250000
   /************************ Local variables *************************/ 10260000
                                                                        10270000
   short int   i;                      /* loop control               */ 10280000
   short int   func_status = OK;       /* function status indicator  */ 10290000
                                                                        10300000
   /******************************************************************* 10310000
   * Make 1st char of month name upper case and the rest lower case   * 10320000
   *******************************************************************/ 10330000
   monthIn[0] = toupper(monthIn[0]);                                    10340000
   for( i=1;i<strlen(monthIn);i++ )                                     10350000
     monthIn[i] = tolower(monthIn[i]);                                  10360000
                                                                        10370000
   /******************************************************************* 10380000
   * Look up *monthIn in the month names array                        * 10390000
   *******************************************************************/ 10400000
   for( i=0; i<12 && strcmp( monthIn,monthNames[i] ) != MATCH; i++ );   10410000
                                                                        10420000
   /******************************************************************* 10430000
   * If found assign month no. str  else set function error indicator * 10440000
   *******************************************************************/ 10450000
   if( i < 12 )                                                         10460000
     strcpy( monthIn,monthNums[i] );                                    10470000
   else                                                                 10480000
    func_status = NOT_OK;                                               10490000
                                                                        10500000
   return( func_status );                                               10510000
                                                                        10520000
 } /* end unnameMonth */                                                10530000
                                                                        10540000
                                                                        10550000
 int romanMonth                        /* converts month# to roman#  */ 10560000
 ( char        *monthIn                /* in/out: month to convert   */ 10570000
 )                                                                      10580000
 /********************************************************************* 10590000
 * Converts *monthIn from a number string to a roman numeral. Returns * 10600000
 * 1 if conversion succeeds, otherwise returns 0.                     * 10610000
 *********************************************************************/ 10620000
 {                                                                      10630000
   /************************ Local variables *************************/ 10640000
                                                                        10650000
   short int   i;                      /* loop control               */ 10660000
   short int   func_status = OK;       /* function status indicator  */ 10670000
                                                                        10680000
   /******************************************************************* 10690000
   * Strip leading zero (if any) from monthIn                         * 10700000
   *******************************************************************/ 10710000
   remove0prefix( monthIn );                                            10720000
                                                                        10730000
   /******************************************************************* 10740000
   * Look up *monthIn in the month number strings array               * 10750000
   *******************************************************************/ 10760000
   for( i=0; i<12 && strcmp( monthIn,monthNums[i] ) != MATCH; i++ );    10770000
                                                                        10780000
   /******************************************************************* 10790000
   * If found assign roman numeral else set function error indicator  * 10800000
   *******************************************************************/ 10810000
   if( i < 12 )                                                         10820000
     strcpy( monthIn,romanNums[i] );                                    10830000
   else                                                                 10840000
    func_status = NOT_OK;                                               10850000
                                                                        10860000
   return( func_status );                                               10870000
                                                                        10880000
 } /* end romanMonth */                                                 10890000
                                                                        10900000
                                                                        10910000
 int unromanMonth                      /* converts roman# to month#  */ 10920000
 ( char        *monthIn                /* in/out: month to convert   */ 10930000
 )                                                                      10940000
 /********************************************************************* 10950000
 * Converts *monthIn from a roman numeral to a number string. Returns * 10960000
 * 1 if conversion succeeds, otherwise returns 0.                     * 10970000
 *********************************************************************/ 10980000
 {                                                                      10990000
   /************************ Local variables *************************/ 11000000
                                                                        11010000
   short int   i;                      /* loop control               */ 11020000
   short int   func_status = OK;       /* function status indicator  */ 11030000
                                                                        11040000
   /******************************************************************* 11050000
   * Convert all chars of *monthIn to upper case                      * 11060000
   *******************************************************************/ 11070000
   for( i=0; i<strlen(monthIn); i++ )                                   11080000
     monthIn[i] = toupper(monthIn[i]);                                  11090000
                                                                        11100000
   /******************************************************************* 11110000
   * Look up *monthIn in the roman numerals array                     * 11120000
   *******************************************************************/ 11130000
   for( i=0; i<12 && strcmp( monthIn,romanNums[i] ) != MATCH; i++ );    11140000
                                                                        11150000
   /******************************************************************* 11160000
   * If found assign month no. str  else set function error indicator * 11170000
   *******************************************************************/ 11180000
   if( i < 12 )                                                         11190000
     strcpy( monthIn,monthNums[i] );                                    11200000
   else                                                                 11210000
    func_status = NOT_OK;                                               11220000
                                                                        11230000
   return( func_status );                                               11240000
                                                                        11250000
 } /* end unromanMonth */                                               11260000
                                                                        11270000
                                                                        11280000
 int checkYear                         /* verify/standardize yearIn  */ 11290000
 ( char        *yearOut,               /* out: 4-digit yr, validated */ 11300000
   char        *yearIn,                /* in: 2- or 4-digit year     */ 11310000
   char        *style                  /* in: style of yearIn        */ 11320000
 )                                                                      11330000
 /********************************************************************* 11340000
 * Verifies that *yearIn is either of the following:                  * 11350000
 * - 2 numeric characters if *style is YY; or                         * 11360000
 * - 4 numeric characters if *style is YYYY.                          * 11370000
 * If criteria satisfied, copies *yearIn to *yearOut and returns 1.   * 11380000
 * If criteria not satisfied, sets *yearOut to null and returns 0.    * 11390000
 *********************************************************************/ 11400000
 {                                                                      11410000
   /************************ Local variables *************************/ 11420000
                                                                        11430000
   short int   i;                      /* loop control               */ 11440000
   short int   yearIn_len              /* length of *yearIn          */ 11450000
               = strlen( yearIn );                                      11460000
   short int   func_status = OK;       /* function status indicator  */ 11470000
                                                                        11480000
   /******************************************************************* 11490000
   * Verify that all bytes of *yearIn are numeric characters          * 11500000
   *******************************************************************/ 11510000
   for( i=0; (i<yearIn_len) && (isdigit(yearIn[i])); i++ );             11520000
   if( i < yearIn_len )                                                 11530000
     func_status = NOT_OK;                                              11540000
   /******************************************************************* 11550000
   * If input format is YY, verify that *yearIn has 2 bytes           * 11560000
   *******************************************************************/ 11570000
   else if( (strcmp( style,"YY" ) == MATCH) && (yearIn_len != 2) )      11580000
     func_status = NOT_OK;                                              11590000
   /******************************************************************* 11600000
   * If input format is YYYY, verify that *yearIn has 4 bytes         * 11610000
   *******************************************************************/ 11620000
   else if( (strcmp( style,"YYYY" ) == MATCH) && (yearIn_len != 4) )    11630000
     func_status = NOT_OK;                                              11640000
                                                                        11650000
   /******************************************************************* 11660000
   * If all checks satisfied, copy *yearIn to *yearOut and return 1   * 11670000
   *******************************************************************/ 11680000
   if( func_status == OK )                                              11690000
     strcpy( yearOut, yearIn );                                         11700000
   /******************************************************************* 11710000
   * If a check failed, sets *yearOut to null and return 0            * 11720000
   *******************************************************************/ 11730000
   else                                                                 11740000
     *yearOut = NULLCHAR;                                               11750000
                                                                        11760000
   return( func_status );                                               11770000
 } /* end checkYear */                                                  11780000
                                                                        11790000
                                                                        11800000
 int checkMonth                        /* verify/standardize monthIn */ 11810000
 ( char        *monthOut,              /* out: month#, validated     */ 11820000
   char        *monthIn,               /* in: month name, #, roman#  */ 11830000
   char        *style                  /* in: style of monthIn       */ 11840000
 )                                                                      11850000
 /********************************************************************* 11860000
 * Verifies that *monthIn is one of the following:                    * 11870000
 * - A valid month name, January - December, if *style is MONTH; or   * 11880000
 * - A valid roman numeral, I - XII, if *style is XX; or              * 11890000
 * - 1 or 2 numeric characters between 1 and 12 if *style is M or MM. * 11900000
 * If criteria satisfied, copies *monthIn to *monthOut and returns 1. * 11910000
 * - if *monthIn is a month name or a roman numeral, it will have     * 11920000
 *   been standardized to the form 1-12.                              * 11930000
 * If criteria not satisfied, sets *monthOut to null and returns 0.   * 11940000
 *********************************************************************/ 11950000
 {                                                                      11960000
   /************************ Local variables *************************/ 11970000
                                                                        11980000
   short int   i;                      /* loop control               */ 11990000
   short int   func_status = OK;       /* function status indicator  */ 12000000
                                                                        12010000
   /******************************************************************* 12020000
   * If *style is MONTH, verify that *monthIn is a valid month name   * 12030000
   *******************************************************************/ 12040000
   if( strcmp( style,"MONTH" ) == MATCH )                               12050000
     func_status = unnameMonth( monthIn );                              12060000
   /******************************************************************* 12070000
   * If *style is XX, verify that *monthIn is a roman numeral, I - XII* 12080000
   *******************************************************************/ 12090000
   else if( strcmp( style,"XX" ) == MATCH )                             12100000
     func_status = unromanMonth( monthIn );                             12110000
   /******************************************************************* 12120000
   * Otherwise, verify that *monthIn is valid month number, 1 - 12    * 12130000
   *******************************************************************/ 12140000
   else                                                                 12150000
     {                                                                  12160000
       remove0prefix( monthIn );       /* strip any leading zero     */ 12170000
       for( i=0; i<12 && strcmp( monthIn,monthNums[i] ) != MATCH; i++ );12180000
       if( i >= 12 )                                                    12190000
         func_status = NOT_OK;                                          12200000
     }                                                                  12210000
   /******************************************************************* 12220000
   * If all checks satisfied, copy *monthIn to *monthOut and return 1 * 12230000
   *******************************************************************/ 12240000
   if( func_status == OK )                                              12250000
     strcpy( monthOut, monthIn );                                       12260000
   /******************************************************************* 12270000
   * If a check failed, set *monthOut to null and return 0            * 12280000
   *******************************************************************/ 12290000
   else                                                                 12300000
     *monthOut = NULLCHAR;                                              12310000
                                                                        12320000
   return( func_status );                                               12330000
 } /* end checkMonth */                                                 12340000
                                                                        12350000
                                                                        12360000
 int checkDay                          /* verify/standardize dayIn   */ 12370000
 ( char        *dayOut,                /* out: day, validated        */ 12380000
   char        *dayIn                  /* in: day number             */ 12390000
 )                                                                      12400000
 /********************************************************************* 12410000
 * Verifies that *dayIn is either 1 or 2 numeric characters.          * 12420000
 * If criteria satisfied, copies *dayIn to *dayOut and returns 1.     * 12430000
 * If criteria not satisfied, set *dayOut to null and returns 0.      * 12440000
 *********************************************************************/ 12450000
 {                                                                      12460000
   /************************ Local variables *************************/ 12470000
                                                                        12480000
   short int   i;                      /* loop control               */ 12490000
   short int   dayIn_len               /* length of *dayIn           */ 12500000
               = strlen( dayIn );                                       12510000
   short int   func_status = OK;       /* function status indicator  */ 12520000
                                                                        12530000
   /******************************************************************* 12540000
   * Verify that *dayIn is 1 or 2 numeric characters                  * 12550000
   *******************************************************************/ 12560000
   for( i=0; ( i<dayIn_len ) && ( isdigit(dayIn[i]) ); i++ );           12570000
   if( i < dayIn_len || dayIn_len < 1 || dayIn_len > 2 )                12580000
     func_status = NOT_OK;                                              12590000
   /******************************************************************* 12600000
   * If all checks satisfied, copy *dayIn to *dayOut and return 1     * 12610000
   *******************************************************************/ 12620000
   if( func_status == OK )                                              12630000
     strcpy( dayOut, dayIn );                                           12640000
   /******************************************************************* 12650000
   * If a check failed, set *dayOut to null and return 0              * 12660000
   *******************************************************************/ 12670000
   else                                                                 12680000
     *dayOut = NULLCHAR;                                                12690000
                                                                        12700000
   return( func_status );                                               12710000
 } /* end checkDay */                                                   12720000
                                                                        12730000
                                                                        12740000
 void add0prefix                                                        12750000
 ( char        *str3                   /* in/out: string to prefix   */ 12760000
 )                                                                      12770000
 /********************************************************************* 12780000
 * Prefixes *str3 with a leading 0 if it is only 1 byte long.         * 12790000
 *********************************************************************/ 12800000
 {                                                                      12810000
   /************************ Local variables *************************/ 12820000
                                                                        12830000
   if( strlen( str3 ) == 1 )                                            12840000
     {                                                                  12850000
       str3[1] = str3[0];              /* Right-shift *str3 1 byte   */ 12860000
       str3[0] = *char0;               /* Prefix it with "0"         */ 12870000
       str3[2] = NULLCHAR;             /* And terminate it           */ 12880000
     }                                                                  12890000
                                                                        12900000
 } /* end add0prefix */                                                 12910000
                                                                        12920000
                                                                        12930000
 void remove0prefix                    /* strips leading zeroes      */ 12940000
 ( char        *string                 /* in/out: string to strip    */ 12950000
 )                                                                      12960000
 /********************************************************************* 12970000
 * Strips the leading zero from *string, if it has one.               * 12980000
 *********************************************************************/ 12990000
 {                                                                      13000000
   if( strncmp( string,"0",1 ) == MATCH )                               13010000
     {                                                                  13020000
       string[0] = string[1];          /* Left-shift *string         */ 13030000
       string[1] = NULLCHAR;           /* And terminate it           */ 13040000
     }                                                                  13050000
                                                                        13060000
 } /* end remove0prefix */                                              13070000
                                                                        13080000
                                                                        13090000
 void addCentury                       /* adds century to yearIn     */ 13100000
 ( char        *yearIn                 /* in/out: year               */ 13110000
 )                                                                      13120000
 /********************************************************************* 13130000
 * Prefixes *yearIn with the current century (according to the system * 13140000
 * date) if *yearIn is 2 bytes long.                                  * 13150000
 *********************************************************************/ 13160000
 {                                                                      13170000
   /************************ Local variables *************************/ 13180000
                                                                        13190000
   time_t      t;                      /* receives calendar time     */ 13200000
   struct  tm  *timeptr;               /* recieves local time        */ 13210000
   char        centyear[4];            /* receives current century   */ 13220000
                                                                        13230000
                                                                        13240000
   /******************************************************************* 13250000
   * If *yearIn is 2 bytes long, prefix it with the current century   * 13260000
   *******************************************************************/ 13270000
   if( strlen( yearIn ) == 2 )                                          13280000
     {                                                                  13290000
       t = time(NULL);                 /* Get calendar time from sys */ 13300000
       timeptr = localtime(&t);        /* Convert to local time      */ 13310000
       strftime( centyear,             /* Format current century year*/ 13320000
                 sizeof(centyear)-1,   /* ..sized for receiving field*/ 13330000
                 "%Y",                 /* ..as century year          */ 13340000
                 timeptr );            /* ..from current local time  */ 13350000
                                                                        13360000
                                       /* Prefix *yearIn with century*/ 13370000
       yearIn[3] = yearIn[1];          /* ..Right-shift *yearIn      */ 13380000
       yearIn[2] = yearIn[0];          /* ..by 2 bytes               */ 13390000
       yearIn[1] = centyear[1];        /* ..Place the century portion*/ 13400000
       yearIn[0] = centyear[0];        /* ..in bytes 1-2             */ 13410000
       yearIn[4] = NULLCHAR;           /* ..Terminate the string     */ 13420000
     }                                                                  13430000
                                                                        13440000
 } /* end addCentury */                                                 13450000
                                                                        13460000
                                                                        13470000
 void removeCentury                    /* strip century from yearIn  */ 13480000
 ( char        *yearIn                 /* in/out: year               */ 13490000
 )                                                                      13500000
 /********************************************************************* 13510000
 * Strips the century portion from *yearIn if it consists of 4 bytes. * 13520000
 *********************************************************************/ 13530000
 {                                                                      13540000
   /******************************************************************* 13550000
   * If *yearIn is 4 bytes long, strip off the century portion        * 13560000
   *******************************************************************/ 13570000
   if( strlen( yearIn ) == 4 )                                          13580000
     {                                                                  13590000
       yearIn[0] = yearIn[2];          /* Shift non-century portion  */ 13600000
       yearIn[1] = yearIn[3];          /* of *yearIn to 1st 2 bytes  */ 13610000
       yearIn[2] = NULLCHAR;           /* and terminate string       */ 13620000
     }                                                                  13630000
 } /* end removeCentury */                                              13640000