DSN8DUCT
Converts a given time from one to another of these 8 formats.
/********************************************************************* 00010000
* Module name = DSN8DUCT (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = General time reformatter (UDF) * 00040000
* * 00050000
* LICENSED MATERIALS - PROPERTY OF IBM * 00060000
* 5675-DB2 * 00109990
* (C) COPYRIGHT 2000 IBM CORP. ALL RIGHTS RESERVED. * 00149980
* * 00190000
* STATUS = VERSION 7 * 00200000
* * 00210000
* Function: Converts a given time from one to another of these 8 * 00220000
* formats: * 00230000
* * 00240000
* H:MM AM/PM HH:MM AM/PM HH:MM:SS AM/PM HH:MM:SS * 00250000
* H.MM HH.MM H.MM.SS HH.MM.SS * 00260000
* * 00270000
* where: * 00280000
* * 00290000
* H: Suppress leading zero if the hour is less than 10 * 00300000
* HH: Retain leading zero if the hour is less than 10 * 00310000
* M: Suppress leading zero if the minute is less than 10 * 00320000
* MM: Retain leading zero if the minute is less than 10 * 00330000
* AM/PM: Return time in 12-hour clock format, else 24-hour * 00340000
* * 00350000
* Example invocation: * 00360000
* EXEC SQL SET :then = ALTTIME( "01:34:59 PM", * 00370000
* "HH:MM:SS AM/PM", * 00380000
* "H.MM" ); * 00390000
* ==> then = "13.34" * 00400000
* * 00410000
* Notes: * 00420000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00430000
* * 00440000
* Restrictions: * 00450000
* * 00460000
* Module type: C program * 00470000
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00480000
* Module size: See linkedit output * 00490000
* Attributes: Re-entrant and re-usable * 00500000
* * 00510000
* Entry Point: DSN8DUCT * 00520000
* Purpose: See Function * 00530000
* Linkage: DB2SQL * 00540000
* Invoked via SQL UDF call * 00550000
* * 00560000
* Input: Parameters explicitly passed to this function: * 00570000
* - *timeIn : pointer to a char[12], null-termi- * 00580000
* nated string having a time in the * 00590000
* format indicated by *formatIn. * 00600000
* - *formatIn : pointer to a char[15], null-termi- * 00610000
* nated string having the format of * 00620000
* time found in *timeIn (see "Func- * 00630000
* tion", above, for valid formats). * 00640000
* - *formatOut : pointer to a char[15], null-termi- * 00650000
* nated string having the format to * 00660000
* which the time found in *timeIn is * 00670000
* to be converted. See "Function", * 00680000
* above, for valid formats. * 00690000
* - *niTimeIn : pointer to a short integer having * 00700000
* the null indicator variable for * 00710000
* *timeIn. * 00720000
* - *niFormatIn : pointer to a short integer having * 00730000
* the null indicator variable for * 00740000
* *formatIn. * 00750000
* - *niFormatOut : pointer to a short integer having * 00760000
* the null indicator variable for * 00770000
* *formatOut. * 00780000
* - *fnName : pointer to a char[138], null-termi- * 00790000
* nated string having the UDF family * 00800000
* name of this function. * 00810000
* - *specificName: pointer to a char[129], null-termi- * 00820000
* nated string having the UDF specific * 00830000
* name of this function. * 00840000
* * 00850000
* * 00860000
* Output: Parameters explicitly passed by this function: * 00870000
* - *timeOut : pointer to a char[15], null-termi- * 00880000
* nated string to receive the refor- * 00890000
* matted time. * 00900000
* - *niTimeOut : pointer to a short integer to re- * 00910000
* ceive the null indicator variable * 00920000
* for *timeOut. * 00930000
* - *sqlstate : pointer to a char[06], null-termi- * 00940000
* nated string to receive the SQLSTATE.* 00950000
* - *message : pointer to a char[70], null-termi- * 00960000
* nated string to receive a diagnostic * 00970000
* message if one is generated by this * 00980000
* function. * 00990000
* * 01000000
* Normal Exit: Return Code: SQLSTATE = 00000 * 01010000
* - Message: none * 01020000
* * 01030000
* Error Exit: Return Code: SQLSTATE = 38601 * 01040000
* - Message: DSN8DUCT Error: No input time entered * 01050000
* - Message: DSN8DUCT Error: No input format entered * 01060000
* - Message: DSN8DUCT Error: No output format entered * 01070000
* * 01080000
* Return Code: SQLSTATE = 38602 * 01090000
* - Message: DSN8DUCT Error: Unknown input format * 01100000
* specified * 01110000
* - Message: DSN8DUCT Error: Inputted time must indi- * 01120000
* cate either AM or PM * 01130000
* - Message: DSN8DUCT Error: Hour not in expected range * 01140000
* of 1-12 * 01150000
* - Message: DSN8DUCT Error: Hour not in expected range * 01160000
* of 0-23 * 01170000
* - Message: DSN8DUCT Error: Minute must be 2 numerics * 01180000
* between 00 and 59 * 01190000
* to input format * 01200000
* - Message: DSN8DUCT Error: Second must be 2 numerics * 01210000
* between 00 and 59 * 01220000
* to input format * 01230000
* * 01240000
* Return Code: SQLSTATE = 38603 * 01250000
* - Message: DSN8DUCT Error: Unknown output format * 01260000
* specified * 01270000
* * 01280000
* External References: * 01290000
* - Routines/Services: None * 01300000
* - Data areas : None * 01310000
* - Control blocks : None * 01320000
* * 01330000
* * 01340000
* Pseudocode: * 01350000
* DSN8DUCT: * 01360000
* - Issue sqlstate 38601 and a diagnostic message if no input time * 01370000
* was provided. * 01380000
* - Issue sqlstate 38601 and a diagnostic message if no input for- * 01390000
* mat was provided. * 01400000
* - Issue sqlstate 38601 and a diagnostic message if no output * 01410000
* format was provided. * 01420000
* - Call decontime to deconstruct the input time into hour, minute,* 01430000
* and, if either, second and AM/PM indicator, according to the * 01440000
* input format. * 01450000
* - Call recontime to create an output time from the hour, minute, * 01460000
* and, if either, second and AM/PM indicator, according to the * 01470000
* output format. * 01480000
* - If no errors, unset null indicators, and return SQLSTATE 00000 * 01490000
* else set null indicator and return null time out. * 01500000
* End DSN8DUCT * 01510000
* * 01520000
* deconTime * 01530000
* - Parse hour, minute, and, if either, second and AM/PM indicator * 01540000
* from the input time by breaking on delimiters (: and .). * 01550000
* - Use the input format to determine sequence of time components. * 01560000
* - if format invalid, issue SQLSTATE 38602 and a diag. message * 01570000
* - Call checkHour to validate the hour component and to standard- * 01580000
* ize it (if required) from a 12-hour clock to a 24-hour clock. * 01590000
* - if not valid hour, issue SQLSTATE 38602 and a diag. message * 01600000
* - Call checkMinute to validate the minute component * 01610000
* - if not valid minute, issue SQLSTATE 38602 and a diag. msg. * 01620000
* - If applicable, call checkSecond to validate the second comp. * 01630000
* - if not valid second, issue SQLSTATE 38602 and a diag. msg. * 01640000
* - If applicable, call checkAMPMindicator to validate the AM/PM * 01650000
* indicator * 01660000
* - if not valid indicator, issue SQLSTATE 38602 and a diag. msg.* 01670000
* End deconTime * 01680000
* * 01690000
* reconTime * 01700000
* - Use the output format to edit the time components * 01710000
* - call set12HrClock to convert the hours component from 24- * 01720000
* hour clock format, as appropriate * 01730000
* - call remove0prefix to strip the leading 0 from the hour com- * 01740000
* ponent, if appropriate * 01750000
* - if output format is invalid, issue SQLSTATE 38603 and a * 01760000
* diagnostic message * 01770000
* - Call buildTime to create the output time from the edited time * 01780000
* components * 01790000
* End reconTime * 01800000
* * 01810000
* buildTime * 01820000
* - Generate the time out by concatenating the time componentents * 01830000
* (hour, minute, and, optionally, second and/or AM/PM indicator) * 01840000
* with intervening delimiters (: or .). * 01850000
* End buildTime * 01860000
* * 01870000
* checkHour * 01880000
* - Verify that the hour component of the input time is: * 01890000
* - in the range 01 - 12 if the input format carries an AM/PM * 01900000
* indicator * 01910000
* - call set24HrClock to standardize the hour to a 24-hour * 01920000
* clock format. * 01930000
* - in the range 00 - 23 if the input format does not carry an * 01940000
* AM/PM indicator * 01950000
* - If not valid, set error flag and return null value for hour * 01960000
* End checkHour * 01970000
* * 01980000
* checkMinute * 01990000
* - Verify the minute component is 2 digits ranging from 00 - 59. * 02000000
* - If not valid, set error flag and return null value for minute * 02010000
* End checkMinute * 02020000
* * 02030000
* checkSecond * 02040000
* - Verify the second component is 2 digits ranging from 00 - 59. * 02050000
* - If not valid, set error flag and return null value for second * 02060000
* End checkSecond * 02070000
* * 02080000
* checkAMPMindicator * 02090000
* - Verify the AM/PM indicator is either "AM" or "PM" * 02100000
* - If not valid, set error flag and return null value for * 02110000
* AM/PM indicator * 02120000
* End checkAMPMindicator * 02130000
* * 02140000
* set12HrClock * 02150000
* - Convert a 24-hour clock hour to a 12-hour clock hour * 02160000
* End set12HrClock * 02170000
* * 02180000
* set24HrClock * 02190000
* - Convert a 12-hour clock hour to a 24-hour clock hour * 02200000
* End set24HrClock * 02210000
* * 02220000
* add0prefix * 02230000
* - prepend an hour with a leading 0 if it is less than 10 * 02240000
* End add0prefix * 02250000
* * 02260000
* remove0prefix * 02270000
* - strip leading zero from an hour if it is less than 10 * 02280000
* End remove0prefix * 02290000
* * 02300000
* * 02310000
*********************************************************************/ 02320000
02321990
#pragma linkage(DSN8DUCT,fetchable) 02323980
02325970
/********************** C library definitions ***********************/ 02330000
#include <stdio.h> 02340000
#include <string.h> 02350000
#include <time.h> 02360000
#include <ctype.h> 02370000
02380000
/***************************** Equates ******************************/ 02390000
#define NULLCHAR '\0' /* Null character */ 02400000
#define MATCH 0 /* Comparison status: Equal */ 02410000
#define NOT_OK 1 /* Run status indicator: Error*/ 02420000
#define OK 0 /* Run status indicator: Good */ 02430000
02440000
/************************ Global constants **************************/ 02450000
char *clock12[24] /* map of 12-hour clock */ 02460000
= { "12", "01", "02", "03", "04", "05", 02470000
"06", "07", "08", "09", "10", "11" }; 02480000
02490000
char *clock24[24] /* map of 24-hour clock */ 02500000
= { "00", "01", "02", "03", "04", "05", 02510000
"06", "07", "08", "09", "10", "11", 02520000
"12", "13", "14", "15", "16", "17", 02530000
"18", "19", "20", "21", "22", "23" }; 02540000
02550000
char *char0 = "0"; /* string with character "0" */ 02560000
02570000
02580000
/*********************** DSN8DUCT functions *************************/ 02590000
02600000
void DSN8DUCT /* main routine */ 02610000
( char *timeIn, /* in: time to be converted */ 02620000
char *formatIn, /* in: format of timeIn */ 02630000
char *formatOut, /* in: format for timeOut */ 02640000
char *timeOut, /* out: reformatted time */ 02650000
short int *nullTimeIn, /* in: indic var for timeIn */ 02660000
short int *nullFormatIn, /* in: indic var for formatIn */ 02670000
short int *nullFormatOut, /* in: indic var, formatOut */ 02680000
short int *nullTimeOut, /* out: indic var for timeOut */ 02690000
char *sqlstate, /* out: SQLSTATE */ 02700000
char *fnName, /* in: family name of function*/ 02710000
char *specificName, /* in: specific name of func */ 02720000
char *message /* out: diagnostic message */ 02730000
); 02740000
02750000
int deconTime /* get hr,min,sec from timeIn */ 02760000
( char *hour, /* out: hour component */ 02770000
char *minute, /* out: minute component */ 02780000
char *second, /* out: second component */ 02790000
char *message, /* out: diagnostic message */ 02800000
char *sqlstate, /* out: SQLSTATE */ 02810000
char *timeIn, /* in: time to deconstruct */ 02820000
char *formatIn /* in: format of timeIn */ 02830000
); 02840000
02850000
int reconTime /* get timeOut from hr,min,sec*/ 02860000
( char *timeOut, /* out: reformatted time */ 02870000
char *message, /* out: diagnostic message */ 02880000
char *sqlstate, /* out: SQLSTATE */ 02890000
char *hour, /* in: hour component */ 02900000
char *minute, /* in: minute component */ 02910000
char *second, /* in: second component */ 02920000
char *formatOut /* in: format for timeOut */ 02930000
); 02940000
02950000
void buildTime /* bld timeOut from hr,min,sec*/ 02960000
( char *timeOut, /* out: reformatted time */ 02970000
char *hour, /* in: hour component */ 02980000
char *minute, /* in: minute component */ 02990000
char *second, /* in: second component */ 03000000
char *delim, /* in: delimiter */ 03010000
char *AMPMind /* in: AM/PM indic. (if any) */ 03020000
); 03030000
03040000
int checkHour /* verify/standardize hourIn */ 03050000
( char *hourOut, /* out: hour (24 hour clock) */ 03060000
char *hourIn, /* in: hour (12- or 24-hr clk)*/ 03070000
char *AMPMind /* in: AM/PM indicator */ 03080000
); 03090000
03100000
int checkMinute /* verify minute from timeIn */ 03110000
( char *minOut, /* out: minute, validated */ 03120000
char *minIn /* in: minute, unvalidated */ 03130000
); 03140000
03150000
int checkSecond /* verify second from timeIn */ 03160000
( char *secOut, /* out: second, validated */ 03170000
char *secIn /* in: second, unvalidated */ 03180000
); 03190000
03200000
int checkAMPMindicator /* verify AM/PM ind. of timeIn*/ 03210000
( char *indOut, /* out: AM/PM indic, validated*/ 03220000
char *indIn /* in: AM/PM ind, unvalidated */ 03230000
); 03240000
03250000
int set12HrClock /* hour to 12-hr clock format */ 03260000
( char *hour, /* in/out: hour */ 03270000
char *AMPMind /* out: AM/PM indicator */ 03280000
); 03290000
03300000
int set24HrClock /* hour to 24-hr clock format */ 03310000
( char *hour, /* in/out: hour */ 03320000
char *AMPMind /* in: AM/PM indicator */ 03330000
); 03340000
03350000
void add0Pref /* add leading zero to string */ 03360000
( char *str3 /* in/out: string to prefix */ 03370000
); 03380000
03390000
void remove0prefix /* strip leading zeroes */ 03400000
( char *string /* in/out: character string */ 03410000
); 03420000
03430000
/********************************************************************/ 03440000
/*************************** main routine ***************************/ 03450000
/********************************************************************/ 03460000
void DSN8DUCT 03470000
( char *timeIn, /* in: time to be converted */ 03480000
char *formatIn, /* in: format of timeIn */ 03490000
char *formatOut, /* in: format for timeOut */ 03500000
char *timeOut, /* out: reformatted time */ 03510000
short int *nullTimeIn, /* in: indic var for timeIn */ 03520000
short int *nullFormatIn, /* in: indic var for formatIn */ 03530000
short int *nullFormatOut, /* in: indic var, formatOut */ 03540000
short int *nullTimeOut, /* out: indic var for timeOut */ 03550000
char *sqlstate, /* out: SQLSTATE */ 03560000
char *fnName, /* in: family name of function*/ 03570000
char *specificName, /* in: specific name of func */ 03580000
char *message /* out: diagnostic message */ 03590000
) 03600000
/********************************************************************* 03610000
* * 03620000
* Assumptions: * 03630000
* - *timeIn points to a char[12], null-terminated string * 03640000
* - *formatIn, points to a char[15], null-terminated string * 03650000
* - *formatOut points to a char[15], null-terminated string * 03660000
* - *timeOut points to a char[12], null-terminated string * 03670000
* - *nullTimeIn points to a short integer * 03680000
* - *nullFormatIn points to a short integer * 03690000
* - *nullFormatOut points to a short integer * 03700000
* - *nullTimeOut points to a short integer * 03710000
* - *sqlstate points to a char[06], null-terminated string * 03720000
* - *fnName points to a char[138], null-terminated string * 03735990
* - *specificName points to a char[129], null-terminated string * 03741980
* - *message points to a char[70], null-terminated string * 03750000
*********************************************************************/ 03760000
{ 03770000
/************************ Local variables *************************/ 03780000
short int i; /* loop control */ 03790000
char hour[3]; /* gets hour from timeIn */ 03800000
char minute[3]; /* gets minute from timeIn */ 03810000
char second[3]; /* gets second from timeIn */ 03820000
03830000
short int status = OK; /* DSN8DUCT run status */ 03840000
03850000
03860000
/******************************************************************* 03870000
* Verify that an input time, its current format, and its new format* 03880000
* have been passed in. * 03890000
*******************************************************************/ 03900000
if( *nullTimeIn || ( strlen( timeIn ) == 0 ) ) 03910000
{ 03920000
status = NOT_OK; 03930000
strcpy( message, 03940000
"DSN8DUCT Error: No input time entered" ); 03950000
strcpy( sqlstate, "38601" ); 03960000
} 03970000
else if( *nullFormatIn || ( strlen( formatIn ) == 0 ) ) 03980000
{ 03990000
status = NOT_OK; 04000000
strcpy( message, 04010000
"DSN8DUCT Error: No input format entered" ); 04020000
strcpy( sqlstate, "38601" ); 04030000
} 04040000
else if( *nullFormatOut || ( strlen( formatOut ) == 0 ) ) 04050000
{ 04060000
status = NOT_OK; 04070000
strcpy( message, 04080000
"DSN8DUCT Error: No output format entered" ); 04090000
strcpy( sqlstate, "38601" ); 04100000
} 04110000
04120000
/******************************************************************* 04130000
* Use formatIn to deconstruct timeIn into hour and minute and, if * 04140000
* applicable, second. * 04150000
*******************************************************************/ 04160000
if( status == OK ) 04170000
status = deconTime( hour, minute, second, message, sqlstate, 04180000
timeIn, formatIn ); 04190000
04200000
/******************************************************************* 04210000
* Use formatOut to reconstruct timeOut from ours and minute and, * 04220000
* if applicable, second. * 04230000
*******************************************************************/ 04240000
if( status == OK ) 04250000
status = reconTime( timeOut, message, sqlstate, 04260000
hour, minute, second, formatOut ); 04270000
04280000
/******************************************************************* 04290000
* If conversion was successful, clear the message buffer and sql- * 04300000
* state, and unset the SQL null indicator for timeOut. * 04310000
*******************************************************************/ 04320000
if( status == OK ) 04330000
{ 04340000
*nullTimeOut = 0; 04350000
message[0] = NULLCHAR; 04360000
strcpy( sqlstate,"00000" ); 04370000
} 04380000
/******************************************************************* 04390000
* If errors occurred, clear the timeOut buffer and set the SQL null* 04400000
* indicator. A diagnostic message and the SQLSTATE have been set * 04410000
* where the error was detected. * 04420000
*******************************************************************/ 04430000
else 04440000
{ 04450000
timeOut[0] = NULLCHAR; 04460000
*nullTimeOut = -1; 04470000
} 04480000
04490000
return; 04500000
04510000
} /* end DSN8DUCT */ 04520000
04530000
04540000
/********************************************************************/ 04550000
/**************************** functions *****************************/ 04560000
/********************************************************************/ 04570000
int deconTime 04580000
( char *hour, /* out: hour component */ 04590000
char *minute, /* out: minute component */ 04600000
char *second, /* out: second component */ 04610000
char *message, /* out: diagnostic message */ 04620000
char *sqlstate, /* out: SQLSTATE */ 04630000
char *timeIn, /* in: time to deconstruct */ 04640000
char *formatIn /* in: format of timeIn */ 04650000
) 04660000
/********************************************************************* 04670000
* Deconstructs *timeIn into *hour and *minute and, if applicable, * 04680000
* *second. The deconstruction is done according to the value in * 04690000
* formatIn. Returns OK if deconstruction succeeds, otherwise places * 04700000
* diagnostic text in *message and returns NOT_OK. * 04710000
*********************************************************************/ 04720000
{ 04730000
char AMPMind[3]; /* AM/PM indicator */ 04740000
04750000
char workTimeIn[12]; /* work copy of timeIn */ 04760000
char *token; /* string ptr for token parser*/ 04770000
char tok1[3]; /* holds 1st time component */ 04780000
char tok2[3]; /* holds 2nd time component */ 04790000
char tok3[3]; /* holds 3rd time component */ 04800000
char tok4[3]; /* holds 4th time component */ 04810000
04820000
short int func_status = OK; /* function status indicator */ 04830000
short int fmtStatus = OK; /* indicates if format is OK */ 04840000
short int hrStatus = OK; /* indicates if hour is OK */ 04850000
short int minStatus = OK; /* indicates if minute is OK */ 04860000
short int secStatus = OK; /* indicates if second is OK */ 04870000
short int indStatus = OK; /* indicates if AMPMind is OK */ 04880000
04890000
/******************************************************************* 04900000
* Use C strtok function to parse the hour and minute from timeIn * 04910000
*******************************************************************/ 04920000
strcpy( workTimeIn,timeIn ); 04930000
token = strtok( workTimeIn,".: " ); 04940000
strcpy( tok1,token ); 04950000
token = strtok( NULL,".: " ); 04960000
strcpy( tok2,token ); 04970000
04980000
/******************************************************************* 04990000
* Parse second, if any, and AM/PM indicator, if any, from timeIn * 05000000
*******************************************************************/ 05010000
token = strtok( NULL,".: " ); 05020000
strcpy( tok3,token ); 05030000
token = strtok( NULL," " ); 05040000
strcpy( tok4,token ); 05050000
05060000
/******************************************************************* 05070000
* Use formatIn to check and set hour, minute, etc. * 05080000
*******************************************************************/ 05090000
if( ( strcmp( formatIn,"H:MM AM/PM" ) == MATCH ) 05100000
|| ( strcmp( formatIn,"HH:MM AM/PM" ) == MATCH ) ) 05110000
{ 05120000
indStatus = checkAMPMindicator( AMPMind,tok3 ); 05130000
hrStatus = checkHour( hour,tok1,AMPMind ); 05140000
minStatus = checkMinute( minute,tok2 ); 05150000
strcpy( second,"00" ); 05160000
} 05170000
else if( strcmp( formatIn,"HH:MM:SS AM/PM" ) == MATCH ) 05180000
{ 05190000
indStatus = checkAMPMindicator( AMPMind,tok4 ); 05200000
hrStatus = checkHour( hour,tok1,AMPMind ); 05210000
minStatus = checkMinute( minute,tok2 ); 05220000
secStatus = checkSecond( second,tok3 ); 05230000
} 05240000
else if( ( strcmp( formatIn,"HH:MM:SS" ) == MATCH ) 05250000
|| ( strcmp( formatIn,"H.MM.SS" ) == MATCH ) 05260000
|| ( strcmp( formatIn,"HH.MM.SS" ) == MATCH ) ) 05270000
{ 05280000
hrStatus = checkHour( hour,tok1,"" ); 05290000
minStatus = checkMinute( minute,tok2 ); 05300000
secStatus = checkSecond( second,tok3 ); 05310000
} 05320000
else if( ( strcmp( formatIn,"H.MM" ) == MATCH ) 05330000
|| ( strcmp( formatIn,"HH.MM" ) == MATCH ) ) 05340000
{ 05350000
hrStatus = checkHour( hour,tok1,"" ); 05360000
minStatus = checkMinute( minute,tok2 ); 05370000
strcpy( second,"00" ); 05380000
} 05390000
else 05400000
fmtStatus = NOT_OK; 05410000
05420000
/******************************************************************* 05430000
* set up error handling * 05440000
*******************************************************************/ 05450000
func_status = NOT_OK; 05460000
strcpy( message,"DSN8DUCT Error: " ); 05470000
strcpy( sqlstate, "38602" ); 05480000
05490000
/******************************************************************* 05500000
* if error detected, issue diagnostic message and return NOT_OK * 05510000
*******************************************************************/ 05520000
if( fmtStatus != OK ) 05530000
strcat( message,"Unknown input format specified" ); 05540000
05550000
else if( indStatus != OK ) 05560000
strcat( message,"Inputted time must indicate either AM or PM" ); 05570000
05580000
else if( hrStatus != OK ) 05590000
if( strcmp( AMPMind,"AM" ) == MATCH 05600000
|| strcmp( AMPMind,"PM" ) == MATCH ) 05610000
strcat( message,"Hour not in expected range of 1-12" ); 05620000
else 05630000
strcat( message,"Hour not in expected range of 0-23" ); 05640000
05650000
else if( minStatus != OK ) 05660000
strcat( message,"minute must be 2 numerics between 00 and 59" ); 05670000
05680000
else if( secStatus != OK ) 05690000
strcat( message,"second must be 2 numerics between 00 and 59" ); 05700000
05710000
/******************************************************************* 05720000
* if no error detected, clear message and sqlstate and return OK * 05730000
*******************************************************************/ 05740000
else 05750000
{ 05760000
*message = NULLCHAR; 05770000
func_status = OK; 05780000
strcpy( sqlstate, "00000" ); 05790000
} 05800000
05810000
return( func_status ); 05820000
05830000
} /* end deconTime */ 05840000
05850000
05860000
int reconTime 05870000
( char *timeOut, /* out: reformatted time */ 05880000
char *message, /* out: diagnostic message */ 05890000
char *sqlstate, /* out: SQLSTATE */ 05900000
char *hour, /* in: hour component */ 05910000
char *minute, /* in: minute component */ 05920000
char *second, /* in: second component */ 05930000
char *formatOut /* in: format for timeOut */ 05940000
) 05950000
/********************************************************************* 05960000
* Reconstructs *timeOut from *hour and *minute and, if applicable, * 05970000
* *second. The reconstruction is done according to the value in * 05980000
* formatOut. Returns OK if reconstruction succeeds, otherwise * 05990000
* places diagnostic text in *message and returns NOT_OK. * 06000000
*********************************************************************/ 06010000
{ 06020000
short int func_status = OK; /* function status indicator */ 06030000
char AMPMind[3]; /* AM/PM indicator */ 06040000
06050000
06060000
/******************************************************************* 06070000
* Use formatOut to reformat time from hour, minute, second * 06080000
*******************************************************************/ 06090000
if( strcmp( formatOut,"H:MM AM/PM" ) == MATCH ) 06100000
{ 06110000
set12HrClock( hour,AMPMind ); 06120000
remove0prefix( hour ); 06130000
buildTime( timeOut, hour, minute, "", ":", AMPMind ); 06140000
} 06150000
else if( strcmp( formatOut,"HH:MM AM/PM" ) == MATCH ) 06160000
{ 06170000
set12HrClock( hour,AMPMind ); 06180000
buildTime( timeOut, hour, minute, "", ":", AMPMind ); 06190000
} 06200000
else if( strcmp( formatOut,"HH:MM:SS AM/PM" ) == MATCH ) 06210000
{ 06220000
set12HrClock( hour,AMPMind ); 06230000
buildTime( timeOut, hour, minute, second, ":", AMPMind ); 06240000
} 06250000
else if( strcmp( formatOut,"HH:MM:SS" ) == MATCH ) 06260000
{ 06270000
buildTime( timeOut, hour, minute, second, ":", "" ); 06280000
} 06290000
else if( strcmp( formatOut,"H.MM.SS" ) == MATCH ) 06300000
{ 06310000
remove0prefix( hour ); 06320000
buildTime( timeOut, hour, minute, second, ".", "" ); 06330000
} 06340000
else if( strcmp( formatOut,"HH.MM.SS" ) == MATCH ) 06350000
{ 06360000
buildTime( timeOut, hour, minute, second, ".", "" ); 06370000
} 06380000
else if( strcmp( formatOut,"H.MM" ) == MATCH ) 06390000
{ 06400000
remove0prefix( hour ); 06410000
buildTime( timeOut, hour, minute, "", ".", "" ); 06420000
} 06430000
else if( strcmp( formatOut,"HH.MM" ) == MATCH ) 06440000
{ 06450000
buildTime( timeOut, hour, minute, "", ".", "" ); 06460000
} 06470000
else 06480000
{ 06490000
func_status = NOT_OK; 06500000
strcpy( message,"DSN8DUCT Error: " ); 06510000
strcat( message,"Unknown output format specified" ); 06520000
strcpy( sqlstate, "38603" ); 06530000
} 06540000
06550000
return( func_status ); 06560000
06570000
} /* end reconTime */ 06580000
06590000
06600000
void buildTime 06610000
( char *timeOut, /* out: reformatted time */ 06620000
char *hour, /* in: hour component */ 06630000
char *minute, /* in: minute component */ 06640000
char *second, /* in: second component */ 06650000
char *delim, /* in: delimiter */ 06660000
char *AMPMind /* in: AM/PM indic. (if any) */ 06670000
) 06680000
/********************************************************************* 06690000
* Builds *timeOut from *hour, *minute, and (if specified) *second, * 06700000
* separated by the value in *delim and, if specified, suffixed by the* 06710000
* value in *AMPMind. * 06720000
*********************************************************************/ 06730000
{ 06740000
/******************************************************************* 06750000
* Build timeOut from incoming time components * 06760000
*******************************************************************/ 06770000
strcpy( timeOut,hour ); /* Start with hour ... */ 06780000
strcat( timeOut,delim ); /* append the delimiter */ 06790000
strcat( timeOut,minute ); /* append minute */ 06800000
if( strlen(second) > 0 ) /* and, if second specified, */ 06810000
{ 06820000
strcat( timeOut,delim ); /* ..append the delimiter */ 06830000
strcat( timeOut,second ); /* ..append second */ 06840000
} 06850000
if( strlen(AMPMind) > 0 ) /* and, if AM/PM ind. spec'd */ 06860000
{ 06870000
strcat( timeOut," " ); /* ..append separator blank */ 06880000
strcat( timeOut,AMPMind ); /* ..append AM/PM indicator */ 06890000
} 06900000
06910000
} /* end buildTime */ 06920000
06930000
06940000
int checkHour 06950000
( char *hourOut, /* out: hour (24-hour clock) */ 06960000
char *hourIn, /* in: hour (12- or 24-hr clk)*/ 06970000
char *AMPMind /* in: AM/PM indicator */ 06980000
) 06990000
/********************************************************************* 07000000
* Verifies that *hourIn meets one of these criteria: * 07010000
* - if *AMPMind is "AM" or "PM", *hourIn ranges from "01" to "12" * 07020000
* - otherwise, *hourIn ranges from "0" to "23" * 07030000
* * 07040000
* If the appropriate criterion is met, *hourOut is assigned as * 07050000
* follows: * 07060000
* - if *AMPMind is "AM" or "PM", *hourOut is assigned the 24-hour * 07070000
* clock equivalent of *hourIn. * 07080000
* - otherwise, *hourIn is copied to *hourOut * 07090000
* and checkHour returns OK. * 07100000
* * 07110000
* If the appropriate critierion is not met, *hourOut is assigned * 07120000
* NULLCHAR, and checkHour returns NOT_OK. * 07130000
*********************************************************************/ 07140000
{ 07150000
short int i; /* loop control */ 07160000
short int func_status = OK; /* function status indicator */ 07170000
07180000
/******************************************************************* 07190000
* add leading 0, if needed, to *hourIn * 07200000
*******************************************************************/ 07210000
add0Pref( hourIn ); 07220000
07230000
/******************************************************************* 07240000
* if AMPMind is AM or PM, convert *hourIn to 24-clock format * 07250000
*******************************************************************/ 07260000
if( strcmp( AMPMind,"AM" ) == MATCH 07270000
|| strcmp( AMPMind,"PM" ) == MATCH ) 07280000
func_status = set24HrClock( hourIn,AMPMind ); 07290000
07300000
/******************************************************************* 07310000
* if AMPMind not "AM" or "PM", verify hourIn ranges from 00 to 23 * 07320000
*******************************************************************/ 07330000
else 07340000
{ 07350000
for( i=0; i<24 && strcmp( hourIn,clock24[i] ) != MATCH; i++ ); 07360000
if( i >= 24 ) /* if hourIn < 00 & > 23 */ 07370000
func_status = NOT_OK; /* ..set error flag */ 07380000
} 07390000
07400000
/******************************************************************* 07410000
* if *hourIn is valid, copy it to *hourOut else set *hourOut to * 07420000
* NULLCHAR * 07430000
*******************************************************************/ 07440000
if( func_status == OK ) 07450000
strcpy( hourOut,hourIn ); 07460000
else 07470000
hourOut[0] = NULLCHAR; 07480000
07490000
return( func_status ); 07500000
} /* end checkHour */ 07510000
07520000
07530000
int checkMinute 07540000
( char *minOut, /* out: minute, validated */ 07550000
char *minIn /* in: minute, unvalidated */ 07560000
) 07570000
/********************************************************************* 07580000
* Verifies that *minIn is 2 bytes of numeric characters between "00" * 07590000
* and "59". * 07600000
* * 07610000
* If so, minIn is copied to minOut and checkMinute returns OK. * 07620000
* If not, NULLCHAR is copied to minOut and checkMinute returns * 07630000
* NOT_OK. * 07640000
*********************************************************************/ 07650000
{ 07660000
short int i; /* loop control */ 07670000
short int func_status = OK; /* function status indicator */ 07680000
07690000
/******************************************************************* 07700000
* verify that *minIn is 2 numeric characters between "00" and "59" * 07710000
*******************************************************************/ 07720000
if( strlen( minIn ) != 2 ) 07730000
func_status = NOT_OK; 07740000
else if( isdigit(minIn[0]) == MATCH || isdigit(minIn[1]) == MATCH ) 07750000
func_status = NOT_OK; 07760000
else if( strcmp( minIn,"00" ) < 0 || strcmp( minIn,"59" ) > 0 ) 07770000
func_status = NOT_OK; 07780000
07790000
/******************************************************************* 07800000
* if minIn is valid, assign it to minOut * 07810000
*******************************************************************/ 07820000
if( func_status == OK ) 07830000
strcpy( minOut,minIn ); 07840000
else 07850000
minOut[0] = NULLCHAR; 07860000
07870000
return( func_status ); 07880000
} /* end checkMinute */ 07890000
07900000
07910000
int checkSecond 07920000
( char *secOut, /* out: second, validated */ 07930000
char *secIn /* in: second, unvalidated */ 07940000
) 07950000
/********************************************************************* 07960000
* Verifies that *secIn is 2 bytes of numeric characters between "00" * 07970000
* and "59". * 07980000
* * 07990000
* If so, secIn is copied to secOut and checkSecond returns OK. * 08000000
* If not, NULLCHAR is copied to secOut and checkSecond returns * 08010000
* NOT_OK. * 08020000
*********************************************************************/ 08030000
{ 08040000
short int i; /* loop control */ 08050000
short int func_status = OK; /* function status indicator */ 08060000
08070000
/******************************************************************* 08080000
* verify that *secIn is 2 numeric characters between "00" and "59" * 08090000
*******************************************************************/ 08100000
if( strlen( secIn ) != 2 ) 08110000
func_status = NOT_OK; 08120000
else if( isdigit(secIn[0]) == MATCH || isdigit(secIn[1]) == MATCH ) 08130000
func_status = NOT_OK; 08140000
else if( strcmp( secIn,"00" ) < 0 || strcmp( secIn,"59" ) > 0 ) 08150000
func_status = NOT_OK; 08160000
08170000
/******************************************************************* 08180000
* if secIn is valid, assign it to secOut * 08190000
*******************************************************************/ 08200000
if( func_status == OK ) 08210000
strcpy( secOut,secIn ); 08220000
else 08230000
secOut[0] = NULLCHAR; 08240000
08250000
return( func_status ); 08260000
} /* end checkSecond */ 08270000
08280000
08290000
int checkAMPMindicator 08300000
( char *indOut, /* out: AM/PM indic, validated*/ 08310000
char *indIn /* in: AM/PM ind, unvalidated */ 08320000
) 08330000
/********************************************************************* 08340000
* Verifies that *indIn is 2 bytes, containing either "AM" or "PM". * 08350000
* * 08360000
* If so, indIn is copied to indOut and checkAMPMindicator returns * 08370000
* OK. * 08380000
* If not, NULLCHAR is copied to indOut and checkAMPMindicator re- * 08390000
* turns NOT_OK. * 08400000
*********************************************************************/ 08410000
{ 08420000
short int i; /* loop control */ 08430000
short int func_status = OK; /* function status indicator */ 08440000
08450000
/******************************************************************* 08460000
* verify that *indIn is 2 bytes containing either "AM" or "PM" * 08470000
*******************************************************************/ 08480000
if( strlen( indIn ) != 2 ) 08490000
func_status = NOT_OK; 08500000
else if( strcmp(indIn,"AM") != MATCH && strcmp(indIn,"PM") != MATCH )08510000
func_status = NOT_OK; 08520000
08530000
/******************************************************************* 08540000
* if indIn is valid, assign it to indOut * 08550000
*******************************************************************/ 08560000
if( func_status == OK ) 08570000
strcpy( indOut,indIn ); 08580000
else 08590000
indOut[0] = NULLCHAR; 08600000
08610000
return( func_status ); 08620000
} /* end checkAMPMindicator */ 08630000
08640000
08650000
int set12HrClock 08660000
( char *hour, /* in/out: hour */ 08670000
char *AMPMind /* out: AM/PM indicator */ 08680000
) 08690000
/********************************************************************* 08700000
* Changes *hour from 24-hour clock format to 12-hour clock format. * 08710000
* * 08720000
* If the incoming value for *hour is: * 08730000
* - between "00" and "11", *hour is assigned the 12-hour clock * 08740000
* equivalent ("12" - "11"), *AMPMind is assigned "AM", and * 08750000
* set12HrClock returns OK. * 08760000
* - between "12" and "23", *hour is assigned the 12-hour clock * 08770000
* equivalent ("12" - "11"), *AMPMind is assigned "PM", and * 08780000
* set12HrClock returns OK. * 08790000
* - any other value, *hour is unchanged, *AMPMind is assigned * 08800000
* NULLCHAR, and set12HrClock returns NOT_OK. * 08810000
*********************************************************************/ 08820000
{ 08830000
short int i; /* loop control */ 08840000
short int func_status = OK; /* function status indicator */ 08850000
08860000
/******************************************************************* 08870000
* locate *hour in the 24-hour clock map * 08880000
*******************************************************************/ 08890000
for( i=0; i<24 && strcmp( hour,clock24[i] ) != MATCH; i++ ); 08900000
08910000
/******************************************************************* 08920000
* assign *hour its 12-hour clock equivalent * 08930000
*******************************************************************/ 08940000
if( i < 12 ) /* if hour betw/ "00" & "11" */ 08950000
{ 08960000
strcpy( hour,clock12[i] ); /* ..set hour in 12-hour fmt */ 08970000
strcpy( AMPMind,"AM" ); /* ..set AM/PM indic to AM */ 08980000
} 08990000
else if( i < 24 ) /* if hour betw/ "12" & "23" */ 09000000
{ 09010000
strcpy( hour,clock12[i-12] ); /* ..set hour in 12-hour fmt */ 09020000
strcpy( AMPMind,"PM" ); /* ..set AM/PM indic to PM */ 09030000
} 09040000
else /* otherwise .. */ 09050000
{ 09060000
func_status = NOT_OK; /* ..set error flag */ 09070000
AMPMind[0] = NULLCHAR; /* ..null out AM/PM indicator */ 09080000
} 09090000
09100000
return( func_status ); /* return function status */ 09110000
} /* end set12HrClock */ 09120000
09130000
09140000
int set24HrClock 09150000
( char *hour, /* in/out: hour */ 09160000
char *AMPMind /* in: AM/PM indicator */ 09170000
) 09180000
/********************************************************************* 09190000
* Changes *hour from 12-hour clock format to 24-hour clock format. * 09200000
* * 09210000
* If the incoming value for *hour is not between "01" and "12", * 09220000
* then *hour is unchanged and set24HrClock returns NOT_OK. * 09230000
* * 09240000
* Otherwise: * 09250000
* - if *AMPMind is "AM", then *hour is assigned the 24-hour equiva- * 09260000
* lent of morning hour ("00"-"11") and set24HrClock returns OK. * 09270000
* - else *hour is assigned the 24-hour equivalent of afternoon * 09280000
* hour ("12"-"23") and set24HrClock returns OK. * 09290000
*********************************************************************/ 09300000
{ 09310000
short int i; /* loop control */ 09320000
short int func_status = OK; /* function status indicator */ 09330000
09340000
/******************************************************************* 09350000
* locate *hour in the 12-hour clock map * 09360000
*******************************************************************/ 09370000
for( i=0; i<12 && strcmp( hour,clock12[i] ) != MATCH; i++ ); 09380000
09390000
/******************************************************************* 09400000
* assign *hour its 24-hour clock equivalent * 09410000
*******************************************************************/ 09420000
if( i > 11 ) /* if hour not betw/ 01 & 12 */ 09430000
func_status = NOT_OK; /* ..set error flag */ 09440000
else if(strcmp(AMPMind,"AM")==MATCH)/* else if betw/ 12 AM - 11 AM*/ 09450000
strcpy( hour,clock24[i] ); /* ..set hour in 12-hour fmt */ 09460000
else /* else betw/ 12 PM - 11 PM */ 09470000
strcpy( hour,clock24[i+12] ); /* ..set hour in 12-hour fmt */ 09480000
09490000
return( func_status ); /* return function status */ 09500000
} /* end set24HrClock */ 09510000
09520000
09530000
void add0Pref 09540000
( char *str3 /* in/out: string to prefix */ 09550000
) 09560000
/********************************************************************* 09570000
* Prefixes *str3 with a leading 0 if it is only 1 byte long * 09580000
*********************************************************************/ 09590000
{ 09600000
/******************************************************************* 09610000
* if str3 is just 1 byte long, prefix it with a "0" * 09620000
*******************************************************************/ 09630000
if( strlen( str3 ) == 1 ) 09640000
{ 09650000
str3[1] = str3[0]; /* Right-shift *str3 1 byte */ 09660000
str3[0] = *char0; /* Prefix it with "0" */ 09670000
str3[2] = NULLCHAR; /* And terminate it */ 09680000
} 09690000
} /* end add0Pref */ 09700000
09710000
09720000
void remove0prefix 09730000
( char *string /* in/out: character string */ 09740000
) 09750000
/********************************************************************* 09760000
* Eliminates all leading zeroes from *str3. Leaves a single zero in * 09770000
* the first byte of *str3 if *str3 is all zeroes. * 09780000
*********************************************************************/ 09790000
{ 09800000
short int i = 0; /* Loop control */ 09810000
short int j = 0; /* Loop control */ 09820000
09830000
/******************************************************************* 09840000
* if leading zero in first byte, skip up to first non-zero * 09850000
*******************************************************************/ 09860000
if( string[0] == '0' ) 09870000
for( i=0; string[i] == '0'; i++ ); 09880000
09890000
/******************************************************************* 09900000
* if at end of string, it was all zeroes: put zero in 1st byte * 09910000
*******************************************************************/ 09920000
if( string[i] == '\0' ) 09930000
strcpy( string,"0" ); 09940000
/******************************************************************* 09950000
* otherwise, left-shift non-zero chars and terminate string * 09960000
*******************************************************************/ 09970000
else 09980000
{ 09990000
for( j=0; string[i] != NULLCHAR; j++ ) 10000000
string[j] = string[i++]; 10010000
string[j] = NULLCHAR; 10020000
} 10030000
} /* end remove0prefix */ 10040000