#! /bin/sh # This is a shell archive. Type 'sh ' to unpack. echo x - mydates.doc cat >mydates.doc <<'MKSHAR_EOF' Mydates - Functions for Informix, UNIX, and Mydate date formats. This document describes the functions provided and the datatypes manipulated by the Mydates.c and getdates.y modules. These include functions to convert between Informix DATE, Informix DATETIME, various UNIX date and time formats, and some new date and time formats that these modules provide. _DD_aa_tt_aa  _TT_yy_pp_ee_ss_:: Idate_t is a 'C' typedef of Informix's DATE data type which stores the number of days since December 31, 1899 (ie a value of 1 == 1/1/1900): This library describes four date formats which are useful for various sorting and processing dates and times, these are: Mydate4_t Date, stored in a long integer, as CCYYMMDD (ie as CC*1000000 + YY*10000 + MM * 100 + DD) Mydate6_t Date stored as a structure containing 3 shorts MM, DD, & CCYY. My_Datetime Data structure, similar to timeval, which qstores date and time accurate to the nearest microsecond (1/10^6). The structure contains a Mydate4_t and two longs containing the number of seconds since midnight and number of microseconds since the last second. The structure is kept normalized. gdt_t This is a struct tm plus a nanoseconds field and a timezone. Normally UTC/GMT is stored with the timesome set to local minutes west of UTC. Defined in getdateandtime.h. _FF_uu_nn_cc_tt_ii_oo_nn_ss_:: _SS_tt_rr_ii_nn_gg  _cc_oo_nn_vv_ee_rr_ss_ii_oo_nn  _ff_uu_nn_cc_tt_ii_oo_nn_ss_:: getdateandtime The underlying string to date function all the others use. Returns a success/error code and fills a gdt_t structure. strtodate4 Convert character string to a Mydate4_t date. Accepts a pointer to a char array and returns a Mydate4_t; strtodate6 Convert character string to a Mydate6_t date. Accepts a pointer to a char array and a pointer to a Mydate6_t to hold the result. strtoidate Convert string in format to Informix DATE type. Accepts a char array and returns a Idate_t. strtomydt Convert string to My_Datetime structure. Accepts a pointer to a character string and a pointer to a My_Datetime_t to hold the result. Uses an enhanced version of the EMACS getdate function, can convert anything sensible (like "3 hours ago yesterday" or "1998-05-19 3:15:52.582347"). _CC_oo_nn_vv_ee_rr_tt  _bb_ee_tt_ww_ee_ee_nn  _vv_aa_rr_ii_oo_uu_ss  _dd_aa_tt_ee_//_tt_ii_mm_ee  _ff_oo_rr_mm_aa_tt_ss _B_e_t_w_e_e_n _v_a_r_i_o_u_s _m_y_d_a_t_e_s _l_i_b_r_a_r_y _f_o_r_m_a_t_s gdttomydt Convert gdt_t date/time to My_Datetime_t. Mydate4to6 Convert Mydate4_t date to a Mydate6_t date. Accepts a pointer to a Mydate6_t to hold the result and a Mydate4_t. Mydate6to4 Convert Mydate6_t date to Mydate4_t date. Accepts a Mydate6_t and returns a Mydate4_t. _B_e_t_w_e_e_n _v_a_r_i_o_u_s _m_y_d_a_t_e_s _f_o_r_m_a_t_s _a_n_d _I_n_f_o_r_m_i_x _d_a_t_e_/_t_i_m_e _f_o_r_m_a_t_s Mydate6toidate Convert Mydate6_t date to Informix DATE type. Accepts a Mydate6_t and returns an Idate_t. Mydate4toidate Convert Mydate4_t date to Informix DATE type. Accepts a Mydate4_t and returns an Idate_t. idatetoMydate6 Convert Informix DATE type to Mydate6_t date. Accepts a pointer to a Mydate6_t to hold the result and an Idate_t. idatetoMydate4 Convert Informix DATE type toMydate4_t date. Accepts an Idate_t and returns an Mydate4_t. idttomydt Convert Informix DATETIME type to My_Datetime structure. Accepts a dtime_t and a pointer to a My_Datetime_t to hold the result. ivltomydt Convert Informix INTERVAL type to My_Datetime structure. Accepts an intrvl_t and a pointer to a My_Datetime_t to hold the result. My_Datetime_t is treated as holding an interval as a normalized number of centuries, years, months, days, seconds, microseconds. Not tested for non-default precision of the starting range value. mydttoidt Convert My_Datetime date to Informix DATETIME type. Accepts a My_Datetime_t, a pointer to a dtime_t to hold the result, and an integer containing the encoded precision for the result. _C_o_n_v_e_r_t _b_e_t_w_e_e_n _v_a_r_i_o_u_s _I_n_f_o_r_m_i_x _a_n_d _U_N_I_X _d_a_t_e_/_t_i_m_e _f_o_r_m_a_t_s_. idatetotime Convert Informix DATE to UNIX time_t based at midnight. Accepts and Idate_t and returns a time_t. timetoidate Convert Informix UNIX time_t to Informix DATE. Accepts a time_t and returns an Idate_t. _C_o_n_v_e_r_t _b_e_t_w_e_e_n _m_y_d_a_t_e_s _f_o_r_m_a_t_s _a_n_d _U_N_I_X _d_a_t_e_/_t_i_m_e _f_o_r_m_a_t_s_. (Note that My_Datetime_t can hold dates after Jan 18, 2038 22:14:07 (UNIX max time) timetomydt Convert UNIX time_t to My_Datetime_t. Accepts a time_t and a pointer to a My_Datetime_t to hold the result. timevaltomydt Convert UNIX timeval structure to My_Datetime structure. Accepts a struct timeval and a pointer to a My_Datetime_t to hold the result. mydttotime Convert My_Datetime structure to UNIX time_t. Accepts a My_Datetime_t and a pointer to a time_t to hold the result. mydttotimeval Convert My_Datetime structure to UNIX timeval structure. Accepts a My_Datetime_t and a opinter to a struct timeval to hold the result. _C_o_n_v_e_r_t _v_a_r_i_o_u_s _f_o_r_m_a_t_s _t_o _U_N_I_X _s_t_a_n_d_a_r_d _d_a_t_e_/_t_i_m_e _s_t_r_i_n_g_. mydttostr Convert My_Datetime structure to a String assuming local time. mydttostrlcl Convert My_Datetime structure to String assuming My_Datetime contains UTC, timezone can be specified. *gdt_format Format a gdt_t in UNIX standard string format as either UTC or local time. _U_t_i_l_i_t_y _f_u_n_c_t_i_o_n_s gdt_Validate_Tm Validate a tm structure for internal consistency. (Structures produced by some UNIX library functions are not internally consistent neccessarily, this checks as mydates assumes the gdt_t structure is internally consistent. MKSHAR_EOF echo x - getdateandtime.h cat >getdateandtime.h <<'MKSHAR_EOF' /* * $Header: getdateandtime.h,v 1.3 2002/10/10 21:23:57 kagel Exp $ * */ #ifndef RCSID_getdateandtime_H #define RCSID_getdateandtime_H static char RCSid_getdateandtime_h[] = "$Id: getdateandtime.h,v 1.3 2002/10/10 21:23:57 kagel Exp $"; /* getdateandtime.h - Support for getdateandtime.c in datelib. */ /* RCS Header: ----------- $Header: getdateandtime.h,v 1.3 2002/10/10 21:23:57 kagel Exp $ RCS Log: -------- $Log: getdateandtime.h,v $ */ #if !defined( getdateandtimeHEADER ) #define getdateandtimeHEADER 1 static const char getdateandtimeRCSHeader[] = "@(#)$Header: getdateandtime.h,v 1.3 2002/10/10 21:23:57 kagel Exp $"; static const char getdateandtimeRCSWhat[] = "$What: <@(#) getdateandtime.h,v 1.3 > $ $Date: 2002/10/10 21:23:57 $"; #include #define TIME_WITH_SYS_TIME 1 #define HAVE_SYS_TIMEB_H 1 #define HAVE_TIMEVAL 1 #ifdef TIME_WITH_SYS_TIME #include #include #else #ifdef HAVE_SYS_TIME_H #include #else #include #endif #endif #ifdef timezone #undef timezone /* needed for sgi */ #endif /* Data structure returned by get_date_and_time. Basically a struct tm plus a field to hold nanoseconds and one for timezone. */ typedef struct gdt { struct tm tm; long nsecs; /* Nanoseconds after the last second */ long tz; /* Minutes west of UTC/GMT */ } gdt_t; long get_date_and_time(char *p, gdt_t **now); char *gdt_format( gdt_t tm, char *result, int local ); long gdt_Validate_Tm( struct tm *tm ); /* Error values of get_date_err after call to get_date_and_time() */ /* Multiple errors are indicated by OR'in these together. */ enum get_date_err_values { GDT_NoError = 0, /* No problems found. */ GDT_ParsBad = 1, /* Could not parse date string. */ GDT_SecsBad = 2, /* Bad second */ GDT_MinsBad = 4, /* Bad minute */ GDT_HourBad = 8, /* Bad hour */ GDT_YearBad = 16, /* Bad year, ie prior to 1/1/1800 */ GDT_MonBad = 32, /* Bad month number */ GDT_MDayBad = 64, /* Bad day of the month, ie Jan. 45, 2002 */ GDT_WDayBad = 128, /* Bad day of the week -- unlikely error */ GDT_YDayBad = 256, /* Bad Julian Day */ GDT_BaseBad = 512 /* An error was encountered getting current time/date */ }; enum gdt_format_outtypes { GDT_UTC = 0, GDT_Local = 1 }; #endif #endif /* RCSID_getdateandtime_H */ MKSHAR_EOF echo x - mydates.h cat >mydates.h <<'MKSHAR_EOF' /* * $Header: mydates.h,v 1.11 2002/10/14 20:45:40 kagel Exp $ * */ /* mydates.h - Header for types and functions for comverting between Informix * other date formats. */ #ifndef RCSID_mydates_H #define RCSID_mydates_H static char RCSid_mydates_h[] = "$Id: mydates.h,v 1.11 2002/10/14 20:45:40 kagel Exp $"; #ifndef lint static char RCSHeader_mydates_h[] = "$Header: mydates.h,v 1.11 2002/10/14 20:45:40 kagel Exp $"; static char RCSWhat_mydates_h[] = "$What: <@(#) mydates.h,v 1.11 > $ $Date: 2002/10/14 20:45:40 $"; #endif /* RCS Header: ----------- $Header: mydates.h,v 1.11 2002/10/14 20:45:40 kagel Exp $ RCS Log: -------- $Log: mydates.h,v $ */ #include #include #include #include #include typedef long Idate_t; /* Typedef for Informix 'DATE' type values. */ typedef long Mydate4_t; /* Typedef for integer w/ YYYYMMDD as a # */ typedef struct Mydate6 { short month, day, year; /* Typedef for array as described. */ } Mydate6_t; typedef struct My_Datetime { Mydate4_t MY_Date; /* Date in Mydate4_t format */ long MY_Secs; /* Time in seconds since midnight */ long MY_USec; /* Microseconds (1/1MM) since last second */ } My_Datetime_t; #endif /* RCSID_mydates_H */ /* Convert gdt_t to MyDatetime_t */ void gdttomydt( gdt_t *date, My_Datetime_t *mydt ); /* Convert an Informix DATE Type to an ANSI format date string - YYYY-MM-DD */ void idatetostr( long idate, char *target, size_t len ); /* Convert character string to a Mydate6_t date. */ void strtodate6( Mydate6_t *target, char *source ); /* Convert character string to a Mydate4_t date. */ Mydate4_t strtodate4( char *source ); /* Convert Mydate4_t date to Mydate6_t date. */ void Mydate4to6( Mydate6_t *target, Mydate4_t source ); /* Convert Mydate4_t date to Mydate6_t date dropping century if present. */ void Mydate4to6x( Mydate6_t *target, Mydate4_t source ); /* Convert Mydate6_t date to Mydate4_t date with century */ Mydate4_t Mydate6to4( Mydate6_t source ); /* Convert Mydate6_t date to Informix Date type */ Idate_t Mydate6toidate( Mydate6_t source ); /* Convert Mydate4_t date to Informix Date type */ Idate_t Mydate4toidate( Mydate4_t source ); /* Convert Informix Date type to Mydate6_t date */ void idatetoMydate6( Mydate6_t *target, Idate_t source ); /* Convert Informix Date type to Mydate4_t date */ Mydate4_t idatetoMydate4( Idate_t source ); /* Convert string in format: to Informix Date type */ Idate_t strtoidate( char *source ); /* Convert Informix Date to UNIX time_t */ time_t idatetotime( Idate_t source ); /* Convert Informix UNIX time_t to Date */ Idate_t timetoidate( time_t source ); /* Convert Informix DateTime type to My_DateTime_t structure. */ void idttomydt( struct dtime idt, My_Datetime_t *mydt ); /* Convert Informix Interval type to My_DateTime_t structure. */ void ivltomydt( struct intrvl idt, My_Datetime_t *mydt ); /* Convert My_DateTime_t structure to Informix DateTime type of precision prec. */ void mydttoidt( My_Datetime_t mydt, struct dtime *idt, int prec ); void timetomydt( My_Datetime_t *mydt, time_t tim ); /* Convert UNIX timeval structure to My_DateTime_t structure. */ void timevaltomydt( My_Datetime_t *mydt, struct timeval tv ); /* Convert My_DateTime_t structure to UNIX time_t. */ void mydttotime( time_t *tm, My_Datetime_t mydt ); /* Convert My_DateTime_t structure to UNIX timeval structure. */ void mydttotimeval( struct timeval *tv, My_Datetime_t mydt ); /* Convert string to My_DateTime_t structure. */ void strtomydt( char *DTStr, My_Datetime_t *mydt ); /* Convert My_DateTime_t structure to a String assuming local time. */ void mydttostr( My_Datetime_t mydt, char *Str, size_t len ); /* Convert My_DateTime_t structure to local time String assuming My_Datetime contains UCT. */ void mydttostrlcl( My_Datetime_t mydt, char *Str, size_t len, long MinWest ); MKSHAR_EOF echo x - mydates.c cat >mydates.c <<'MKSHAR_EOF' /* $Header: Mydates.c,v 1.11 2002/10/14 20:47:46 robocop Exp $ */ #ifndef lint static char RCSident[] = "$Id: Mydates.c,v 1.11 2002/10/14 20:47:46 robocop Exp $"; #endif /* Mydates.c - Functions to convert between UNIX/Informix/Mydate/string date formats. */ /* RCS Header: ----------- $Header: Mydates.c,v 1.11 2002/10/14 20:47:46 robocop Exp $ RCS Log: -------- */ static char RCSHeader[] = "$Header: Mydates.c,v 1.11 2002/10/14 20:47:46 robocop Exp $"; static char RCSWhat[] = "$What: <@(#) Mydates.c,v 1.11 > $ $Date: 2002/10/14 20:47:46 $"; #include #include #include #include #include #include #include #include #include #include "getdateandtime.h" #include "mydates.h" static char src[2048]; static int OneMonthDays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static int OneMonthDaysLeap[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /* Convert Informix DATE type to an ISO 8601 format date string: YYYY-MM-DD */ void idatetostr( long idate, char *target, size_t len ) { long day, month, year; int *MDays; year = 1899; month = 12; day = 31; if (idate > 0) { while (idate--) { day++; if ((year % 400) == 0 || ((year % 100) != 0 && (year % 4) == 0)) MDays = OneMonthDaysLeap; else MDays = OneMonthDays; if (day > MDays[month-1]) { day -= MDays[month-1]; month++; } if (month > 12) { year++; month -= 12; } } } else if (idate < 0) { while (idate++) { day--; if ((year % 400) == 0 || ((year % 100) != 0 && (year % 4) == 0)) MDays = OneMonthDaysLeap; else MDays = OneMonthDays; if (day <= 0) { month--; } if (month <= 0) { year--; month += 12; } if (day <= 0) { day = MDays[month-1]; } } } snprintf( target, len, "%4d-%02.2d-%02.2d", year, month, day ); } /* Convert a date string to Mydate6_t date */ void strtodate6( Mydate6_t *target, char *source ) { Mydate4_t bdt4; bdt4 = strtodate4( source ); Mydate4to6( target, bdt4 ); } /* Convert Mydate4_t date to Mydate6_t date. */ void Mydate4to6( Mydate6_t *target, Mydate4_t source ) { target->year = source / 10000; target->month = (source % 10000) / 100; target->day = source % 100; } /* Convert Mydate4_t date to Mydate6_t date dropping century if present. */ void Mydate4to6x( Mydate6_t *target, Mydate4_t source ) { target->year = (source / 10000) % 100; target->month = (source % 10000) / 100; target->day = source % 100; } /* Convert Mydate6_t date to Mydate4_t date with century. */ Mydate4_t Mydate6to4( Mydate6_t source ) { Mydate4_t target; if (source.year < 60) source.year += 2000; else if (source.year < 1900) source.year += 1900; target = source.year * 10000 + source.month * 100 + source.day; return target; } /* Convert a date string to Mydate4_t date */ Mydate4_t strtodate4( char *source ) { My_Datetime_t mydt; strtomydt( source, &mydt ); return mydt.MY_Date; } static long days_in_mo[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; static long days_in_lp[12] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; /* Convert Mydate6_t date to Informix Date type */ Idate_t Mydate6toidate( Mydate6_t source ) { return Mydate4toidate( Mydate6to4( source ) ); } /* Convert Mydate4_t date to Informix Date type */ Idate_t Mydate4toidate( Mydate4_t source ) { long years, leaps, day, month, year; Idate_t target; year = (source / 10000); years = year % 1900; month = (source % 10000) / 100; day = (source % 100); leaps = ((year-1) / 4) - ((year-1) / 100) + ((year-1) / 400) - 460; if ((((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) && (((month == 2 && day > 29) || month > 2))) leaps++; target = years * 365 + leaps + days_in_mo[month - 1] + day; return target; } /* Convert Informix Date type to Mydate6_t date */ void idatetoMydate6( Mydate6_t *target, Idate_t source ) { char str[12]; My_Datetime_t mydt; idatetostr( source, str, 12 ); strtomydt( str, &mydt ); target->year = mydt.MY_Date / 10000; target->month = (mydt.MY_Date / 100) % 100; target->day = (mydt.MY_Date % 100); } /* Convert Informix Date type to Mydate4_t date */ Mydate4_t idatetoMydate4( Idate_t source ) { Mydate6_t temp; idatetoMydate6( &temp, source ); return Mydate6to4( temp ); } /* Convert string to Informix Date type */ Idate_t strtoidate( char *source ) { Mydate6_t temp; strtodate6( &temp, source ); return Mydate6toidate( temp ); } /* Convert Informix Date to UNIX time_t */ time_t idatetotime( Idate_t source ) { return ((source - 25567) * 86400); } /* Convert UNIX time_t to Informix Date */ Idate_t timetoidate( time_t source ) { return ((source / 86400) + 25567); } /* Convert Informix DateTime type to My_Datetime_t structure. */ void idttomydt( dtime_t idt, My_Datetime_t *mydt ) { int strt, end; int year, month, day, hour, minute, second, fraction, multi; int index = 0, tmp; time_t tim; strt = TU_START( idt.dt_qual ); end = TU_END( idt.dt_qual ); tim = time( NULL ); if (strt == TU_YEAR) { year = ((long)idt.dt_dec.dec_dgts[index]) * 100 + ((long)idt.dt_dec.dec_dgts[index+1]); index += 2; } else { /* Assume this year! */ year = tim / 31536000; year += 1970; } tmp = (tim % 31536000) / 86400; tmp -= (tmp - 2) / 4; /* Adjust for leap years since 1970! */ if (strt <= TU_MONTH && end >= TU_MONTH) month = ((long)idt.dt_dec.dec_dgts[index++]); else { month = 0; while (days_in_mo[month+1] < tmp) month++; } if (strt <= TU_DAY && end >= TU_DAY) { day = ((long)idt.dt_dec.dec_dgts[index++]); } else { day = tmp - days_in_mo[month]; } if (strt <= TU_HOUR && end >= TU_HOUR) { hour = ((long)idt.dt_dec.dec_dgts[index++]); } else { hour = (tim % 86400) / 3600; } if (strt <= TU_MINUTE && end >= TU_MINUTE) { minute = ((long)idt.dt_dec.dec_dgts[index++]); } else { minute = (tim % 3600) / 60; } if (strt <= TU_SECOND && end >= TU_SECOND) { second = ((long)idt.dt_dec.dec_dgts[index++]); } else { second = tim % 60; } if (end >= TU_F1) { switch (end) { case TU_F5: fraction = (long)idt.dt_dec.dec_dgts[index++]; fraction = fraction * 100 + (long)idt.dt_dec.dec_dgts[index++]; fraction = fraction * 100 + (long)idt.dt_dec.dec_dgts[index++]; multi = 1; break; case TU_F4: case TU_F3: fraction = (long)idt.dt_dec.dec_dgts[index++]; fraction = fraction * 100 + (long)idt.dt_dec.dec_dgts[index++]; multi = 100; break; case TU_F2: case TU_F1: fraction = (long)idt.dt_dec.dec_dgts[index++]; multi = 10000; break; default: fraction = 0; multi = 1; break; } } else { fraction = 0; multi = 1; } mydt->MY_Date = year * 10000 + month * 100 + day; mydt->MY_Secs = hour * 3600 + minute * 60 + second; mydt->MY_USec = fraction * multi; } /* Convert Informix Interval type to My_Datetime_t structure. */ void ivltomydt( struct intrvl idt, My_Datetime_t *mydt ) { int strt, end, ndigs; int year, month, day, hour, minute, second, fraction, multi; int index = 0; strt = TU_START( idt.in_qual ); end = TU_END( idt.in_qual ); ndigs = end - strt; if (end % 2) ndigs += 1; ndigs = idt.in_dec.dec_ndgts - (ndigs >> 1); if (strt == TU_YEAR) { year = 0; while (ndigs--) year = year * 100 + (long)idt.in_dec.dec_dgts[index++]; } else { year = 0; } if (strt == TU_MONTH) { month = 0; while (ndigs--) month = month * 100 + (long)idt.in_dec.dec_dgts[index++]; } else if (strt < TU_MONTH && end >= TU_MONTH) { month = ((long)idt.in_dec.dec_dgts[index++]); } else { month = 0; } if (strt == TU_DAY) { day = 0; while (ndigs--) day = day * 100 + (long)idt.in_dec.dec_dgts[index++]; } else if (strt < TU_DAY && end >= TU_DAY) { day = ((long)idt.in_dec.dec_dgts[index++]); } else { day = 0; } if (strt == TU_HOUR) { hour = 0; while (ndigs--) hour = hour * 100 + (long)idt.in_dec.dec_dgts[index++]; } else if (strt < TU_HOUR && end >= TU_HOUR) { hour = ((long)idt.in_dec.dec_dgts[index++]); } else { hour = 0; } if (strt == TU_MINUTE) { minute = 0; while (ndigs--) minute = minute * 100 + (long)idt.in_dec.dec_dgts[index++]; } else if (strt < TU_MINUTE && end >= TU_MINUTE) { minute = ((long)idt.in_dec.dec_dgts[index++]); } else { minute = 0; } if (strt == TU_SECOND) { second = 0; while (ndigs--) second = second * 100 + (long)idt.in_dec.dec_dgts[index++]; } else if (strt < TU_SECOND && end >= TU_SECOND) { second = ((long)idt.in_dec.dec_dgts[index++]); } else { second = 0; } if (end >= TU_F1) { switch (end) { case TU_F5: fraction = (long)idt.in_dec.dec_dgts[index++]; fraction = fraction * 100 + (long)idt.in_dec.dec_dgts[index++]; fraction = fraction * 100 + (long)idt.in_dec.dec_dgts[index++]; multi = 1; break; case TU_F4: case TU_F3: fraction = (long)idt.in_dec.dec_dgts[index++]; fraction = fraction * 100 + (long)idt.in_dec.dec_dgts[index++]; multi = 100; break; case TU_F2: case TU_F1: fraction = (long)idt.in_dec.dec_dgts[index++]; multi = 10000; break; default: fraction = 0; multi = 1; break; } } else { fraction = 0; multi = 1; } mydt->MY_Date = year * 10000 + month * 100 + day; mydt->MY_Secs = hour * 3600 + minute * 60 + second; mydt->MY_USec = fraction * multi; } /* Convert MY_Datetime_t structure to Informix DateTime type of precision prec. */ void mydttoidt( My_Datetime_t mydt, dtime_t *idt, int prec ) { int strt, end; int year, month, day, hour, minute, second, fraction; int index = 0; time_t tim; tim = time( NULL ); idt->dt_qual = prec; idt->dt_dec.dec_ndgts = 8; idt->dt_dec.dec_exp = 7; idt->dt_dec.dec_pos = 1; strt = TU_START( idt->dt_qual ); end = TU_END( idt->dt_qual ); year = mydt.MY_Date / 10000; month = (mydt.MY_Date % 10000) / 100; day = mydt.MY_Date % 100; hour = mydt.MY_Secs / 3600; minute = (mydt.MY_Secs % 3600) / 60; second = mydt.MY_Secs % 60; fraction = mydt.MY_USec; if (fraction >= 1000000) { second += fraction / 1000000; fraction %= 1000000; } if (strt == TU_YEAR) { idt->dt_dec.dec_dgts[index++] = year / 100; idt->dt_dec.dec_dgts[index++] = year % 100; } if (strt <= TU_MONTH && end >= TU_MONTH) { idt->dt_dec.dec_dgts[index++] = month; } if (strt <= TU_DAY && end >= TU_DAY) { idt->dt_dec.dec_dgts[index++] = day; } if (strt <= TU_HOUR && end >= TU_HOUR) { idt->dt_dec.dec_dgts[index++] = hour; } if (strt <= TU_MINUTE && end >= TU_MINUTE) { idt->dt_dec.dec_dgts[index++] = minute; } if (strt <= TU_SECOND && end >= TU_SECOND) { idt->dt_dec.dec_dgts[index++] = second; } if (end >= TU_F1) { switch (end) { case TU_F5: fraction -= fraction % 10; /* strip off 1/1000000ths digit */ idt->dt_dec.dec_dgts[index++] = (fraction / 10000) % 100; idt->dt_dec.dec_dgts[index++] = (fraction / 100) % 100; idt->dt_dec.dec_dgts[index++] = fraction % 100; break; case TU_F3: fraction -= fraction % 1000; /* strip off 1/10000ths digit */ case TU_F4: idt->dt_dec.dec_dgts[index++] = (fraction / 10000) % 100; idt->dt_dec.dec_dgts[index++] = (fraction / 100) % 100; break; case TU_F1: fraction -= fraction % 100000; /* strip the 10ths digit */ case TU_F2: idt->dt_dec.dec_dgts[index++] = fraction / 10000; break; } } } /* Convert time_t to My_Datetime_t */ void timetomydt( My_Datetime_t *mydt, time_t tim ) { long idate; idate = timetoidate( tim ); mydt->MY_Date = idatetoMydate4( idate ); mydt->MY_Secs = tim % 86400; mydt->MY_USec = 0; } /* Convert struct timeval to My_Datetime_t */ void timevaltomydt( My_Datetime_t *mydt, struct timeval tv ) { timetomydt( mydt, tv.tv_sec ); mydt->MY_USec = tv.tv_usec; } /* Convert My_Datetime_t to a time_t */ void mydttotime( time_t *tm, My_Datetime_t mydt ) { int leaps, month, year; year = *tm = (mydt.MY_Date / 10000); leaps = (*tm - 1970 + 1) / 4; *tm = (((*tm - 1970) * 365) + leaps) * 86400; month = ((mydt.MY_Date % 10000) / 100); *tm += (days_in_mo[month - 1] * 86400) + ((month > 2 && (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0)) ? 86400 : 0); *tm += (((mydt.MY_Date % 100) - 1) * 86400); *tm += mydt.MY_Secs; } /* Convert My_Datetime_t to a struct timeval */ void mydttotimeval( struct timeval *tv, My_Datetime_t mydt ) { tv->tv_usec = mydt.MY_USec; mydttotime( &tv->tv_sec, mydt ); } /* Convert gdt_t to MyDatetime_t */ void gdttomydt( gdt_t *date, My_Datetime_t *mydt ) { mydt->MY_Date = (((date->tm.tm_year + 1900) * 10000) + ((date->tm.tm_mon+1) * 100) + date->tm.tm_mday); mydt->MY_Secs = ((date->tm.tm_hour * 3600) + (date->tm.tm_min * 60) + date->tm.tm_sec); mydt->MY_USec = date->nsecs; } /* Convert a string to My_Datetime_t */ void strtomydt( char *DTStr, My_Datetime_t *mydt ) { long d; gdt_t *date; date = (gdt_t *)NULL; d = get_date_and_time( DTStr, &date ); gdttomydt( date, mydt ); } /* Convert My_Datetime_t to a string assuming time is local. */ void mydttostr( My_Datetime_t mydt, char *Str, size_t len ) { snprintf( Str, len, "%2.2ld-%2.2ld-%2.2ld %2.2ld:%2.2ld:%2.2ld.%6.6ld", mydt.MY_Date / 10000, (mydt.MY_Date % 10000) / 100, (mydt.MY_Date % 100), (mydt.MY_Secs / 3600), (mydt.MY_Secs % 3600) / 60, mydt.MY_Secs % 60, mydt.MY_USec ); } /* Convert My_Datetime_t to a string in local TZ, assumes mydt contains UCT */ void mydttostrlcl( My_Datetime_t mydt, char *Str, size_t len, long MinWest ) { mydt.MY_Secs -= MinWest * 60; if (mydt.MY_Secs < 0) { mydt.MY_Secs += 86400; mydt.MY_Date -= 1; } mydttostr( mydt, Str, len ); } MKSHAR_EOF echo x - getdateandtime.y cat >getdateandtime.y <<'MKSHAR_EOF' %{ /* ** Originally written by Steven M. Bellovin while ** at the University of North Carolina at Chapel Hill. Later tweaked by ** a couple of people on Usenet. Completely overhauled by Rich $alz ** and Jim Berets in August, 1990; ** send any email to Rich. ** ** This grammar has 10 shift/reduce conflicts. ** ** This code is in the public domain and has no copyright. ** ** Art S. Kagel, 2/28/1995 - enhanced to handle dates between 1902-01-01 ** and 2037-12-31. Also enhanced to accept hh:mm:ss.fff, times with fractions ** of a second (requires 24-hour time format). Also enhanced error handling. ** since there are now valid dates <0 returned, now returns LONG_MIN on error ** and places an error code into a global variable: get_date_err, similar to ** UNIX getdate(). ** ** Marco Greco, 12/18/1997 - moved time.h, sys/time.h, sys/timeb.h inclusion ** into an include file in common w/4gl interface. Created os dependent ** includes. Pass thru bison/yacc with the -l flag, or cbuild barfs! ** A couple of other changes in the way - now yacc doesn't barf ;-) ** ** Art S. Kagel, 10/10/2002 - Recoded to use new data structure gdt_t, defined ** in the getdateandtime.h header file for all intermediate work and as a ** return type. This to permi