DSN8DUAT
Returns the current time in one these 8 formats.
/********************************************************************* 00010000
* Module name = DSN8DUAT (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = Current time reformatter (UDF) * 00040000
* * 00050000
* LICENSED MATERIALS - PROPERTY OF IBM * 00060000
* 5675-DB2 * 00170000
* (C) COPYRIGHT 1998, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00180000
* * 00190000
* STATUS = VERSION 7 * 00200000
* * 00210000
* Function: Returns the current time in one these 8 formats: * 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 :now = ALTTIME( "HH:MM:SS AM/PM" ); * 00370000
* * 00380000
* Notes: * 00390000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00400000
* * 00410000
* Restrictions: * 00420000
* * 00430000
* Module type: C program * 00440000
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00450000
* Module size: See linkedit output * 00460000
* Attributes: Re-entrant and re-usable * 00470000
* * 00480000
* Entry Point: DSN8DUAT * 00490000
* Purpose: See Function * 00500000
* Linkage: DB2SQL * 00510000
* Invoked via SQL UDF call * 00520000
* * 00530000
* Input: Parameters explicitly passed to this function: * 00540000
* - *format : pointer to a char[15], null-termi- * 00550000
* nated string having the desired * 00560000
* format for the current time (see * 00570000
* "Function", above, for valid formats)* 00580000
* - *niFormat : pointer to a short integer having * 00590000
* the null indicator variable for * 00600000
* *format. * 00610000
* - *fnName : pointer to a char[138], null-termi- * 00620000
* nated string having the UDF family * 00630000
* name of this function. * 00640000
* - *specificName: pointer to a char[129], null-termi- * 00650000
* nated string having the UDF specific * 00660000
* name of this function. * 00670000
* * 00680000
* * 00690000
* Output: Parameters explicitly passed by this function: * 00700000
* - *timeOut : pointer to a char[12], null-termi- * 00710000
* nated string to receive the current * 00720000
* time in the formatted indicated by * 00730000
* *format. * 00740000
* - *niTimeOut : pointer to a short integer to re- * 00750000
* ceive the null indicator variable * 00760000
* for *timeOut. * 00770000
* - *sqlstate : pointer to a char[06], null-termi- * 00780000
* nated string to receive the SQLSTATE.* 00790000
* - *message : pointer to a char[70], null-termi- * 00800000
* nated string to receive a diagnostic * 00810000
* message if one is generated by this * 00820000
* function. * 00830000
* * 00840000
* Normal Exit: Return Code: SQLSTATE = 00000 * 00850000
* - Message: none * 00860000
* * 00870000
* Error Exit: Return Code: SQLSTATE = 38601 * 00880000
* - Message: DSN8DUAT Error: No format entered * 00890000
* - Message: DSN8DUAT Error: Unknown format specified * 00900000
* * 00910000
* External References: * 00920000
* - Routines/Services: None * 00930000
* - Data areas : None * 00940000
* - Control blocks : None * 00950000
* * 00960000
* * 00970000
* Pseudocode: * 00980000
* DSN8DUAT: * 00990000
* - Verify that a valid format for the current time was received: * 01000000
* - if *format is blank or niFormat is not 0, no format passed: * 01010000
* - issue SQLSTATE 38601 and a diagnostic message * 01020000
* - Call getTime to obtain: * 01030000
* - the current 12-hour clock hour * 01040000
* - the current 24-hour clock hour * 01050000
* - the current minute * 01060000
* - the current second * 01070000
* - Set AM/PM indicator to PM if 24-hour clock hour > 11, else AM * 01080000
* - Call remove0prefix to remove leading zeroes from the hour * 01090000
* component, if appropriate * 01100000
* - Call buildTime to generate the output time using the format to * 01110000
* determine which of the time components, delimiters, and AM/PM * 01120000
* indicator (if any) to pass. * 01130000
* - If no errors, unset null indicators, and return SQLSTATE 00000 * 01140000
* else set null indicator and return null time out. * 01150000
* End DSN8DUAT * 01160000
* * 01170000
* getTime: * 01180000
* - invoke the time() library function to query calendar time. * 01190000
* - invoke the localtime() library function to convert and correct * 01200000
* for local time. * 01210000
* - invoke the strftime() library function to format 12-hour, 24- * 01220000
* hour, minute, and second components from the time vector. * 01230000
* End getTime * 01240000
* * 01250000
* buildTime: * 01260000
* - Concatenate the minutes component to the hours component with * 01270000
* an intervening delimiter (: or .). * 01280000
* - If the seconds component is not null, concatenate it to the * 01290000
* timestring with an intervening delimiter (: or .) * 01300000
* - If the AM/PM indicator is not null, concatenate it to the * 01310000
* timestring * 01320000
* End buildTime * 01330000
* * 01340000
* remove0prefix: * 01350000
* - eliminate leading zeroes from a hour component * 01360000
* End remove0prefix * 01370000
* * 01380000
* * 01390000
*********************************************************************/ 01400000
01410000
#pragma linkage(DSN8DUAT,fetchable) 01414990
01420000
/********************** C library definitions ***********************/ 01430000
#include <stdio.h> 01440000
#include <string.h> 01450000
#include <time.h> 01460000
01470000
/***************************** Equates ******************************/ 01480000
#define NULLCHAR '\0' /* Null character */ 01490000
01500000
#define MATCH 0 /* Comparison status: Equal */ 01510000
#define NOT_OK 0 /* Run status indicator: Error*/ 01520000
#define OK 1 /* Run status indicator: Good */ 01530000
01540000
01550000
/*********************** DSN8DUAT functions *************************/ 01560000
void DSN8DUAT /* main routine */ 01570000
( char *format, /* in: format for timeOut */ 01580000
char *timeOut, /* out: formatted current time*/ 01590000
short int *niFormat, /* in: indic var, format */ 01600000
short int *niTimeOut, /* out: indic var, timeOut */ 01610000
char *sqlstate, /* out: SQLSTATE */ 01620000
char *fnName, /* in: family name of function*/ 01630000
char *specificName, /* in: specific name of func */ 01640000
char *message /* out: diagnostic message */ 01650000
); 01660000
01670000
void getTime /* Get current time */ 01680000
( char *hh12, /* out: hours (12 hour clock) */ 01690000
char *hh24, /* out: hours (24 hour clock) */ 01700000
char *mm, /* out: minutes */ 01710000
char *ss /* out: seconds */ 01720000
); 01730000
01740000
void buildTime /* Format time as specified */ 01750000
( char *timeStr, /* out: reformatted time */ 01760000
char *hh, /* in: hours component */ 01770000
char *mm, /* in: minutes component */ 01780000
char *ss, /* in: seconds component */ 01790000
char *delim, /* in: delimiter of choice */ 01800000
char *suffix /* in: AM/PM suffix (if any) */ 01810000
); 01820000
01830000
void remove0prefix /* Remove leading zeroes */ 01840000
( char *string /* in/out: character string */ 01850000
); 01860000
01870000
/********************************************************************/ 01880000
/*************************** main routine ***************************/ 01890000
/********************************************************************/ 01900000
void DSN8DUAT /* main routine */ 01910000
( char *format, /* in: format for timeOut */ 01920000
char *timeOut, /* out: formatted current time*/ 01930000
short int *niFormat, /* in: indic var, format */ 01940000
short int *niTimeOut, /* out: indic var, timeOut */ 01950000
char *sqlstate, /* out: SQLSTATE */ 01960000
char *fnName, /* in: family name of function*/ 01970000
char *specificName, /* in: specific name of func */ 01980000
char *message /* out: diagnostic message */ 01990000
) 02000000
/********************************************************************* 02010000
* * 02020000
* * 02030000
* Assumptions: * 02040000
* - *format points to a char[15], null-terminated string * 02050000
* - *timeOut points to a char[12], null-terminated string * 02060000
* - *niFormat points to a short integer * 02070000
* - *niTimeOut points to a short integer * 02080000
* - *sqlstate points to a char[06], null-terminated string * 02090000
* - *fnName points to a char[138], null-terminated string * 02105990
* - *specificName points to a char[129], null-terminated string * 02111980
* - *message points to a char[70], null-terminated string * 02120000
*********************************************************************/ 02130000
{ 02140000
/************************ local variables *************************/ 02150000
short int status = OK; /* DSN8DUMN run status */ 02160000
02170000
char hh12[3]; /* current time - hours */ 02180000
char hh24[3]; /* current time - hours */ 02190000
char mm[3]; /* current time - minutes */ 02200000
char ss[3]; /* current time - seconds */ 02210000
char suffix[4]; /* AM/PM indicator */ 02220000
02230000
02240000
/******************************************************************* 02250000
* Verify that a format has been passed in * 02260000
*******************************************************************/ 02270000
if( *niFormat || ( strlen( format ) == 0 ) ) 02280000
{ 02290000
status = NOT_OK; 02300000
strcpy( message, 02310000
"DSN8DUAT Error: No format entered" ); 02320000
strcpy( sqlstate, "38601" ); 02330000
} 02340000
02350000
/******************************************************************* 02360000
* Get current time in the specified format * 02370000
*******************************************************************/ 02380000
if( status == OK ) 02390000
{ 02400000
/*************************************************************** 02410000
* Get the current hour (hh), minute (mm), and second (ss) * 02420000
***************************************************************/ 02430000
getTime( hh12,hh24,mm,ss ); 02440000
02450000
/*************************************************************** 02460000
* Suffix is AM unless it's noon or later on the 24-hour clock * 02470000
***************************************************************/ 02480000
strcpy( suffix," AM" ); 02490000
if( strcmp( hh24,"11" ) > 0 ) 02500000
strcpy( suffix," PM" ); 02510000
02520000
/*************************************************************** 02530000
* Format the current time according to the input format * 02540000
***************************************************************/ 02550000
if( strcmp( format,"H:MM AM/PM" ) == MATCH ) 02560000
{ 02570000
remove0prefix( hh12 ); 02580000
buildTime( timeOut,hh12,mm,"",":",suffix ); 02590000
} 02600000
else if( strcmp( format,"HH:MM AM/PM" ) == MATCH ) 02610000
{ 02620000
buildTime( timeOut,hh12,mm,"",":",suffix ); 02630000
} 02640000
else if( strcmp( format,"HH:MM:SS AM/PM" ) == MATCH ) 02650000
{ 02660000
buildTime( timeOut,hh12,mm,ss,":",suffix ); 02670000
} 02680000
else if( strcmp( format,"HH:MM:SS" ) == MATCH ) 02690000
{ 02700000
buildTime( timeOut,hh24,mm,ss,":","" ); 02710000
} 02720000
else if( strcmp( format,"H.MM" ) == MATCH ) 02730000
{ 02740000
remove0prefix( hh24 ); 02750000
buildTime( timeOut,hh24,mm,"",".","" ); 02760000
} 02770000
else if( strcmp( format,"HH.MM" ) == MATCH ) 02780000
{ 02790000
buildTime( timeOut,hh24,mm,"",".","" ); 02800000
} 02810000
else if( strcmp( format,"H.MM.SS" ) == MATCH ) 02820000
{ 02830000
remove0prefix( hh24 ); 02840000
buildTime( timeOut,hh24,mm,ss,".","" ); 02850000
} 02860000
else if( strcmp( format,"HH.MM.SS" ) == MATCH ) 02870000
{ 02880000
buildTime( timeOut,hh24,mm,ss,".","" ); 02890000
} 02900000
else 02910000
{ 02920000
status = NOT_OK; 02930000
strcpy( message, 02940000
"DSN8DUAT Error: Unknown format specified" ); 02950000
strcpy( sqlstate, "38601" ); 02960000
} 02970000
} /* if( status == OK ) */ 02980000
02990000
/******************************************************************* 03000000
* If operation was successful, clear the message buffer and sql- * 03010000
* state, and unset the SQL null indicator for timeOut. * 03020000
*******************************************************************/ 03030000
if( status == OK ) 03040000
{ 03050000
*niTimeOut = 0; 03060000
message[0] = NULLCHAR; 03070000
strcpy( sqlstate,"00000" ); 03080000
} 03090000
/******************************************************************* 03100000
* If errors occurred, clear the timeOut buffer and set the SQL null* 03110000
* indicator. A diagnostic message and the SQLSTATE have been set * 03120000
* where the error was detected. * 03130000
*******************************************************************/ 03140000
else 03150000
{ 03160000
timeOut[0] = NULLCHAR; 03170000
*niTimeOut = -1; 03180000
} 03190000
03200000
return; 03210000
03220000
} /* end DSN8DUAT */ 03230000
03240000
03250000
/********************************************************************/ 03260000
/***************************** functions ****************************/ 03270000
/********************************************************************/ 03280000
void getTime 03290000
( char *hh12, /* out: hours (12 hour clock) */ 03300000
char *hh24, /* out: hours (24 hour clock) */ 03310000
char *mm, /* out: minutes */ 03320000
char *ss /* out: seconds */ 03330000
) 03340000
/********************************************************************* 03350000
* Obtains the current time from the system and returns the hours in * 03360000
* *hh12 (12-hour clock hours) and *hh24 (24-hour clock hours), the * 03370000
* minutes in *mm, and the seconds in *ss. * 03380000
*********************************************************************/ 03390000
{ 03400000
time_t t; /* buff for system time macro */ 03410000
struct tm *tmptr; /* buffer for time.h tm struct*/ 03420000
char timeBuf[13]; /* buffer to receive sys time */ 03430000
03440000
short int i; /* len of str rtnd by strftime*/ 03450000
char *tokPtr; /* string ptr for token parser*/ 03460000
char hhmmss[10]; /* time in HH:MM:SS format */ 03470000
03480000
/******************************************************************* 03490000
* Use the C function localtime to get the current time from the * 03500000
* system, then use the C function strftime to format it into a * 03510000
* string containing both 12- and 24-hour clock hours and minutes * 03520000
* and seconds, all separated by slashes. * 03530000
*******************************************************************/ 03540000
t = time(NULL); 03550000
tmptr = localtime(&t); 03560000
i = strftime( timeBuf, 03570000
sizeof(timeBuf)-1, 03580000
"%I/%H/%M/%S", /* format as hh12/hh24/mm/ss */ 03590000
tmptr ); 03600000
03610000
/******************************************************************* 03620000
* Use the strtok func to extract time components from time buffer * 03630000
*******************************************************************/ 03640000
tokPtr = strtok( timeBuf,"/" ); /* Parse to first slash */ 03650000
strcpy( hh12,tokPtr ); /* for hours on 12-hour clock */ 03660000
03670000
tokPtr = strtok( NULL,"/" ); /* Parse to 2nd slash */ 03680000
strcpy( hh24,tokPtr ); /* for hours on 24-hour clock */ 03690000
03700000
tokPtr = strtok( NULL,"/" ); /* Parse to 3rd slash */ 03710000
strcpy( mm,tokPtr ); /* for minutes */ 03720000
03730000
tokPtr = strtok( NULL,"/" ); /* Parse remaining bytes */ 03740000
strcpy( ss,tokPtr ); /* for seconds */ 03750000
03760000
} /* end getTime */ 03770000
03780000
03790000
void buildTime 03800000
( char *timeStr, /* out: reformatted time */ 03810000
char *hh, /* in: hours component */ 03820000
char *mm, /* in: minutes component */ 03830000
char *ss, /* in: seconds component */ 03840000
char *delim, /* in: delimiter of choice */ 03850000
char *suffix /* in: AM/PM suffix (if any) */ 03860000
) 03870000
/********************************************************************* 03880000
* Builds *timeStr from hours (*hh), minutes (*mm), and seconds (*ss, * 03890000
* if not null), separated by the value in *delim and suffixed by the * 03900000
* value, if not null, in *suffix. * 03910000
*********************************************************************/ 03920000
{ 03930000
/******************************************************************* 03940000
* Build timeStr from incoming time components * 03950000
*******************************************************************/ 03960000
strcpy( timeStr,hh ); /* Start with hours ... */ 03970000
strcat( timeStr,delim ); /* append the delimiter */ 03980000
strcat( timeStr,mm ); /* append minutes */ 03990000
if( strlen(ss) > 0 ) /* and, if seconds specified, */ 04000000
{ 04010000
strcat( timeStr,delim ); /* ..append the delimiter */ 04020000
strcat( timeStr,ss ); /* ..append seconds */ 04030000
} 04040000
if( strlen(suffix) > 0 ) /* and, if suffix specified, */ 04050000
strcat( timeStr,suffix ); /* ..append it. */ 04060000
04070000
} /* end buildTime */ 04080000
04090000
04100000
void remove0prefix 04110000
( char *string /* in/out: character string */ 04120000
) 04130000
/********************************************************************* 04140000
* Eliminates all leading zeroes from *string. Leaves a single zero * 04150000
* in the first byte of *string if *string is all zeroes. * 04160000
*********************************************************************/ 04170000
{ 04180000
short int i = 0; /* Loop control */ 04190000
short int j = 0; /* Loop control */ 04200000
04210000
/******************************************************************* 04220000
* if leading zero in first byte, skip up to first non-zero * 04230000
*******************************************************************/ 04240000
if( string[0] == '0' ) 04250000
for( i=0; string[i] == '0'; i++ ); 04260000
04270000
/******************************************************************* 04280000
* if at end of string, it was all zeroes: put zero in 1st byte * 04290000
*******************************************************************/ 04300000
if( string[i] == '\0' ) 04310000
strcpy( string,"0" ); 04320000
/******************************************************************* 04330000
* otherwise, left-shift non-zero chars and terminate string * 04340000
*******************************************************************/ 04350000
else 04360000
{ 04370000
for( j=0; string[i] != NULLCHAR; j++ ) 04380000
string[j] = string[i++]; 04390000
string[j] = NULLCHAR; 04400000
} 04410000
} /* end remove0prefix */ 04420000