ITS#9120 fix tm2time compat breakage

Add lutil_tm2gtime for Proleptic Gregorian calendar,
revert lutil_tm2time to previous behavior using Unix epoch
This commit is contained in:
Howard Chu 2020-01-19 19:05:04 +00:00
parent e7538fa462
commit c06807ec45
3 changed files with 78 additions and 10 deletions

View file

@ -169,8 +169,8 @@ typedef struct lutil_tm {
} lutil_tm;
typedef struct lutil_timet {
unsigned int tt_sec; /* seconds since 0000 */
int tt_gsec; /* seconds since 0000, high 7 bits, sign-flipped */
unsigned int tt_sec; /* seconds since epoch, 0000 or 1970 */
int tt_gsec; /* seconds since epoch, high 7 bits, maybe sign-flipped */
/* sign flipped to sort properly as unsigned ints */
unsigned int tt_usec; /* microseconds */
} lutil_timet;
@ -180,11 +180,16 @@ LDAP_LUTIL_F( int )
lutil_parsetime LDAP_P((
char *atm, struct lutil_tm * ));
/* Convert structured time to time in seconds since 1900 */
/* Convert structured time to time in seconds since 1970 (Unix epoch) */
LDAP_LUTIL_F( int )
lutil_tm2time LDAP_P((
struct lutil_tm *, struct lutil_timet * ));
/* Convert structured time to time in seconds since 0000 (Proleptic Gregorian) */
LDAP_LUTIL_F( int )
lutil_tm2gtime LDAP_P((
struct lutil_tm *, struct lutil_timet * ));
#ifdef _WIN32
LDAP_LUTIL_F( void )
lutil_slashpath LDAP_P(( char* path ));

View file

@ -151,14 +151,78 @@ size_t lutil_localtime( char *s, size_t smax, const struct tm *tm, long delta )
return ret + 4;
}
/* Proleptic Gregorian Calendar, 1BCE = year 0 */
int lutil_tm2time( struct lutil_tm *tm, struct lutil_timet *tt )
{
static int moffset[12] = {
0, 31, 59, 90, 120,
151, 181, 212, 243,
273, 304, 334 };
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);
/* this function can handle a range of about 17408 years... */
/* 86400 seconds in a day, divided by 128 = 675 */
tt->tt_sec *= 675;
/* move high 7 bits into tt_gsec */
tt->tt_gsec = tt->tt_sec >> 25;
tt->tt_sec -= tt->tt_gsec << 25;
/* get hours */
sec = tm->tm_hour;
/* convert to minutes */
sec *= 60L;
sec += tm->tm_min;
/* convert to seconds */
sec *= 60L;
sec += tm->tm_sec;
/* add remaining seconds */
tt->tt_sec <<= 7;
tt->tt_sec += sec;
/* return success */
return 0;
}
/* Proleptic Gregorian Calendar, 1BCE = year 0 */
int lutil_tm2gtime( struct lutil_tm *tm, struct lutil_timet *tt )
{
static int moffset[12] = {
0, 31, 59, 90, 120,
151, 181, 212, 243,
273, 304, 334 };
int sec, year;
long tmp;
@ -169,7 +233,6 @@ int lutil_tm2time( struct lutil_tm *tm, struct lutil_timet *tt )
year = tm->tm_year + 1900;
tmp = year * 365;
/* add in leap days */
sec = (year - 1) / 4;
tmp += sec;
@ -181,7 +244,7 @@ int lutil_tm2time( struct lutil_tm *tm, struct lutil_timet *tt )
if (year > 0)
tmp++;
/* calculate days from months */
/* calculate days from months */
tmp += moffset[tm->tm_mon];
/* add in this year's leap day, if any */

View file

@ -5843,7 +5843,7 @@ int generalizedTimeIndexer(
assert(values[i].bv_val != NULL && values[i].bv_len >= 10);
/* Use 40 bits of time for key */
if ( lutil_parsetime( values[i].bv_val, &tm ) == 0 ) {
lutil_tm2time( &tm, &tt );
lutil_tm2gtime( &tm, &tt );
tmp[0] = tt.tt_gsec & 0xff;
tmp[4] = tt.tt_sec & 0xff;
tt.tt_sec >>= 8;
@ -5890,7 +5890,7 @@ int generalizedTimeFilter(
if ( value->bv_val && value->bv_len >= 10 &&
lutil_parsetime( value->bv_val, &tm ) == 0 ) {
lutil_tm2time( &tm, &tt );
lutil_tm2gtime( &tm, &tt );
tmp[0] = tt.tt_gsec & 0xff;
tmp[4] = tt.tt_sec & 0xff;
tt.tt_sec >>= 8;