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