mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-04 06:01:23 -05:00
Move time parsers from ppolicy.c to liblutil; preserve greater precision
This commit is contained in:
parent
36b0611404
commit
1ca9556c1b
2 changed files with 149 additions and 0 deletions
|
|
@ -147,6 +147,30 @@ lutil_progname LDAP_P((
|
|||
int argc,
|
||||
char *argv[] ));
|
||||
|
||||
struct slap_tm {
|
||||
int tm_sec; /* seconds 0-60 (1 leap second) */
|
||||
int tm_min; /* minutes 0-59 */
|
||||
int tm_hour; /* hours 0-23 */
|
||||
int tm_mday; /* day 1-31 */
|
||||
int tm_mon; /* month 0-11 */
|
||||
int tm_year; /* year - 1900 */
|
||||
int tm_usec; /* microseconds */
|
||||
} slap_tm;
|
||||
|
||||
struct slap_timet {
|
||||
unsigned int tt_sec; /* seconds since 1900 */
|
||||
int tt_gsec; /* seconds since 1900, high 7 bits */
|
||||
unsigned int tt_usec; /* microseconds */
|
||||
} slap_timet;
|
||||
|
||||
LDAP_LUTIL_F( int )
|
||||
lutil_parsetime LDAP_P((
|
||||
char *atm, struct slap_tm * ));
|
||||
|
||||
LDAP_LUTIL_F( int )
|
||||
lutil_tm2time LDAP_P((
|
||||
struct slap_tm *, struct slap_timet * ));
|
||||
|
||||
#ifdef _WIN32
|
||||
LDAP_LUTIL_F( void )
|
||||
lutil_slashpath LDAP_P(( char* path ));
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <stdio.h>
|
||||
#include <ac/stdlib.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/ctype.h>
|
||||
#include <ac/unistd.h>
|
||||
#include <ac/time.h>
|
||||
#ifdef HAVE_IO_H
|
||||
|
|
@ -135,6 +136,130 @@ size_t lutil_localtime( char *s, size_t smax, const struct tm *tm, long delta )
|
|||
return ret + 5;
|
||||
}
|
||||
|
||||
int lutil_tm2time( struct slap_tm *tm, struct slap_timet *tt )
|
||||
{
|
||||
static int moffset[12] = {
|
||||
0, 31, 59, 90, 120,
|
||||
151, 181, 212, 243,
|
||||
273, 304, 334 };
|
||||
int sec;
|
||||
|
||||
tt->tt_usec = tm->tm_usec;
|
||||
|
||||
/* special case 0000/01/01+00:00:00 is returned as zero */
|
||||
if ( tm->tm_year == -1900 && tm->tm_mon == 0 && tm->tm_mday == 1 &&
|
||||
tm->tm_hour == 0 && tm->tm_min == 0 && tm->tm_sec == 0 ) {
|
||||
tt->tt_sec = 0;
|
||||
tt->tt_gsec = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* tm->tm_year is years since 1900 */
|
||||
/* calculate days from years since 1970 (epoch) */
|
||||
tt->tt_sec = tm->tm_year - 70;
|
||||
tt->tt_sec *= 365L;
|
||||
|
||||
/* count leap days in preceding years */
|
||||
tt->tt_sec += ((tm->tm_year -69) >> 2);
|
||||
|
||||
/* calculate days from months */
|
||||
tt->tt_sec += moffset[tm->tm_mon];
|
||||
|
||||
/* add in this year's leap day, if any */
|
||||
if (((tm->tm_year & 3) == 0) && (tm->tm_mon > 1)) {
|
||||
tt->tt_sec ++;
|
||||
}
|
||||
|
||||
/* add in days in this month */
|
||||
tt->tt_sec += (tm->tm_mday - 1);
|
||||
|
||||
/* 86400 seconds in a day, divided by 128 = 675 */
|
||||
tt->tt_sec *= 675;
|
||||
tt->tt_gsec = tt->tt_sec >> 25;
|
||||
tt->tt_sec -= tt->tt_gsec << 25;
|
||||
|
||||
/* convert to hours */
|
||||
sec = tm->tm_hour;
|
||||
|
||||
/* convert to minutes */
|
||||
sec *= 60L;
|
||||
sec += tm->tm_min;
|
||||
|
||||
/* convert to seconds */
|
||||
sec *= 60L;
|
||||
sec += tm->tm_sec;
|
||||
|
||||
tt->tt_sec <<= 7;
|
||||
tt->tt_sec += sec;
|
||||
|
||||
/* return success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lutil_parsetime( char *atm, struct slap_tm *tm )
|
||||
{
|
||||
while (atm && tm) {
|
||||
char *ptr = atm;
|
||||
int i, fracs;
|
||||
|
||||
/* Is the stamp reasonably long? */
|
||||
for (i=0; isdigit(atm[i]); i++);
|
||||
if (i < sizeof("00000101000000")-1)
|
||||
break;
|
||||
|
||||
/*
|
||||
* parse the time into a struct tm
|
||||
*/
|
||||
/* 4 digit year to year - 1900 */
|
||||
tm->tm_year = *ptr++ - '0';
|
||||
tm->tm_year *= 10; tm->tm_year += *ptr++ - '0';
|
||||
tm->tm_year *= 10; tm->tm_year += *ptr++ - '0';
|
||||
tm->tm_year *= 10; tm->tm_year += *ptr++ - '0';
|
||||
tm->tm_year -= 1900;
|
||||
/* month 01-12 to 0-11 */
|
||||
tm->tm_mon = *ptr++ - '0';
|
||||
tm->tm_mon *=10; tm->tm_mon += *ptr++ - '0';
|
||||
if (tm->tm_mon < 1 || tm->tm_mon > 12) break;
|
||||
tm->tm_mon--;
|
||||
|
||||
/* day of month 01-31 */
|
||||
tm->tm_mday = *ptr++ - '0';
|
||||
tm->tm_mday *=10; tm->tm_mday += *ptr++ - '0';
|
||||
if (tm->tm_mday < 1 || tm->tm_mday > 31) break;
|
||||
|
||||
/* Hour 00-23 */
|
||||
tm->tm_hour = *ptr++ - '0';
|
||||
tm->tm_hour *=10; tm->tm_hour += *ptr++ - '0';
|
||||
if (tm->tm_hour < 0 || tm->tm_hour > 23) break;
|
||||
|
||||
/* Minute 00-59 */
|
||||
tm->tm_min = *ptr++ - '0';
|
||||
tm->tm_min *=10; tm->tm_min += *ptr++ - '0';
|
||||
if (tm->tm_min < 0 || tm->tm_min > 59) break;
|
||||
|
||||
/* Second 00-61 */
|
||||
tm->tm_sec = *ptr++ - '0';
|
||||
tm->tm_sec *=10; tm->tm_sec += *ptr++ - '0';
|
||||
if (tm->tm_sec < 0 || tm->tm_sec > 61) break;
|
||||
|
||||
/* Fractions of seconds */
|
||||
for (i = 0, fracs = 0;isdigit(*ptr);) {
|
||||
i*=10; i+= *ptr++ - '0';
|
||||
fracs++;
|
||||
}
|
||||
tm->tm_usec = i;
|
||||
if (i) {
|
||||
for (i = fracs; i<6; i++)
|
||||
tm->tm_usec *= 10;
|
||||
}
|
||||
|
||||
/* Must be UTC */
|
||||
if (*ptr != 'Z') break;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* strcopy is like strcpy except it returns a pointer to the trailing NUL of
|
||||
* the result string. This allows fast construction of catenated strings
|
||||
|
|
|
|||
Loading…
Reference in a new issue