/* -*- c-basic-offset: 2 -*- */
/*
Copyright ( C ) 2010 - 2013 Kentoku SHIBA
Copyright ( C ) 2011 - 2015 Kouhei Sutou < kou @ clear - code . com >
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 2 . 1 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1335 USA
*/
#include "mrn_time_converter.hpp"
#ifdef min
# undef min
#endif
#ifdef max
# undef max
#endif
#include <limits>
// for debug
#define MRN_CLASS_NAME "mrn::TimeConverter"
namespace mrn {
TimeConverter::TimeConverter() = default ;
TimeConverter::~TimeConverter() = default ;
time_t TimeConverter::tm_to_time_gm(struct tm *time, bool *truncated) {
MRN_DBUG_ENTER_METHOD();
*truncated = true ;
struct tm gmdate;
time->tm_yday = -1 ;
time->tm_isdst = -1 ;
time_t sec_t = mktime(time);
if (time->tm_yday == -1 ) {
DBUG_RETURN(-1 );
}
if (!gmtime_r(&sec_t, &gmdate)) {
DBUG_RETURN(-1 );
}
int32 mrn_utc_diff_in_seconds =
(
time->tm_mday > 25 && gmdate.tm_mday == 1 ? -1 :
time->tm_mday == 1 && gmdate.tm_mday > 25 ? 1 :
time->tm_mday - gmdate.tm_mday
) * 24 * 60 * 60 +
(time->tm_hour - gmdate.tm_hour) * 60 * 60 +
(time->tm_min - gmdate.tm_min) * 60 +
(time->tm_sec - gmdate.tm_sec);
DBUG_PRINT("info" , ("mroonga: time->tm_year=%d" , time->tm_year));
DBUG_PRINT("info" , ("mroonga: time->tm_mon=%d" , time->tm_mon));
DBUG_PRINT("info" , ("mroonga: time->tm_mday=%d" , time->tm_mday));
DBUG_PRINT("info" , ("mroonga: time->tm_hour=%d" , time->tm_hour));
DBUG_PRINT("info" , ("mroonga: time->tm_min=%d" , time->tm_min));
DBUG_PRINT("info" , ("mroonga: time->tm_sec=%d" , time->tm_sec));
DBUG_PRINT("info" , ("mroonga: mrn_utc_diff_in_seconds=%d" ,
mrn_utc_diff_in_seconds));
if (mrn_utc_diff_in_seconds > 0 ) {
if (sec_t > std::numeric_limits<time_t>::max() - mrn_utc_diff_in_seconds) {
DBUG_RETURN(-1 );
}
} else {
if (sec_t < std::numeric_limits<time_t>::min() - mrn_utc_diff_in_seconds) {
DBUG_RETURN(-1 );
}
}
*truncated = false ;
DBUG_RETURN(sec_t + mrn_utc_diff_in_seconds);
}
long long int TimeConverter::tm_to_grn_time(struct tm *time, int usec,
bool *truncated) {
MRN_DBUG_ENTER_METHOD();
long long int sec = tm_to_time_gm(time, truncated);
DBUG_PRINT("info" , ("mroonga: sec=%lld" , sec));
DBUG_PRINT("info" , ("mroonga: usec=%d" , usec));
long long int grn_time = *truncated ? 0 : GRN_TIME_PACK(sec, usec);
DBUG_RETURN(grn_time);
}
long long int TimeConverter::mysql_time_to_grn_time(MYSQL_TIME *mysql_time,
bool *truncated) {
MRN_DBUG_ENTER_METHOD();
int usec = mysql_time->second_part;
long long int grn_time = 0 ;
*truncated = false ;
switch (mysql_time->time_type) {
case MYSQL_TIMESTAMP_DATE:
{
DBUG_PRINT("info" , ("mroonga: MYSQL_TIMESTAMP_DATE" ));
struct tm date;
memset(&date, 0 , sizeof (struct tm));
date.tm_year = mysql_time->year - TM_YEAR_BASE;
if (mysql_time->month > 0 ) {
date.tm_mon = mysql_time->month - 1 ;
} else {
date.tm_mon = 0 ;
*truncated = true ;
}
if (mysql_time->day > 0 ) {
date.tm_mday = mysql_time->day;
} else {
date.tm_mday = 1 ;
*truncated = true ;
}
DBUG_PRINT("info" , ("mroonga: tm_year=%d" , date.tm_year));
DBUG_PRINT("info" , ("mroonga: tm_mon=%d" , date.tm_mon));
DBUG_PRINT("info" , ("mroonga: tm_mday=%d" , date.tm_mday));
bool tm_truncated = false ;
grn_time = tm_to_grn_time(&date, usec, &tm_truncated);
if (tm_truncated) {
*truncated = true ;
}
}
break ;
case MYSQL_TIMESTAMP_DATETIME:
{
DBUG_PRINT("info" , ("mroonga: MYSQL_TIMESTAMP_DATETIME" ));
struct tm datetime;
memset(&datetime, 0 , sizeof (struct tm));
datetime.tm_year = mysql_time->year - TM_YEAR_BASE;
if (mysql_time->month > 0 ) {
datetime.tm_mon = mysql_time->month - 1 ;
} else {
datetime.tm_mon = 0 ;
*truncated = true ;
}
if (mysql_time->day > 0 ) {
datetime.tm_mday = mysql_time->day;
} else {
datetime.tm_mday = 1 ;
*truncated = true ;
}
datetime.tm_hour = mysql_time->hour;
datetime.tm_min = mysql_time->minute;
datetime.tm_sec = mysql_time->second;
DBUG_PRINT("info" , ("mroonga: tm_year=%d" , datetime.tm_year));
DBUG_PRINT("info" , ("mroonga: tm_mon=%d" , datetime.tm_mon));
DBUG_PRINT("info" , ("mroonga: tm_mday=%d" , datetime.tm_mday));
DBUG_PRINT("info" , ("mroonga: tm_hour=%d" , datetime.tm_hour));
DBUG_PRINT("info" , ("mroonga: tm_min=%d" , datetime.tm_min));
DBUG_PRINT("info" , ("mroonga: tm_sec=%d" , datetime.tm_sec));
bool tm_truncated = false ;
grn_time = tm_to_grn_time(&datetime, usec, &tm_truncated);
if (tm_truncated) {
*truncated = true ;
}
}
break ;
case MYSQL_TIMESTAMP_TIME:
{
DBUG_PRINT("info" , ("mroonga: MYSQL_TIMESTAMP_TIME" ));
int sec =
mysql_time->hour * 60 * 60 +
mysql_time->minute * 60 +
mysql_time->second;
DBUG_PRINT("info" , ("mroonga: sec=%d" , sec));
grn_time = GRN_TIME_PACK(sec, usec);
if (mysql_time->neg) {
grn_time = -grn_time;
}
}
break ;
default :
DBUG_PRINT("info" , ("mroonga: default" ));
grn_time = 0 ;
break ;
}
DBUG_RETURN(grn_time);
}
void TimeConverter::grn_time_to_mysql_time(long long int grn_time,
MYSQL_TIME *mysql_time) {
MRN_DBUG_ENTER_METHOD();
long long int sec;
int usec;
GRN_TIME_UNPACK(grn_time, sec, usec);
DBUG_PRINT("info" , ("mroonga: sec=%lld" , sec));
DBUG_PRINT("info" , ("mroonga: usec=%d" , usec));
switch (mysql_time->time_type) {
case MYSQL_TIMESTAMP_DATE:
{
DBUG_PRINT("info" , ("mroonga: MYSQL_TIMESTAMP_DATE" ));
struct tm date;
time_t sec_t = sec;
// TODO: Add error check
gmtime_r(&sec_t, &date);
DBUG_PRINT("info" , ("mroonga: tm_year=%d" , date.tm_year));
mysql_time->year = date.tm_year + TM_YEAR_BASE;
DBUG_PRINT("info" , ("mroonga: tm_mon=%d" , date.tm_mon));
mysql_time->month = date.tm_mon + 1 ;
DBUG_PRINT("info" , ("mroonga: tm_mday=%d" , date.tm_mday));
mysql_time->day = date.tm_mday;
}
break ;
case MYSQL_TIMESTAMP_DATETIME:
{
DBUG_PRINT("info" , ("mroonga: MYSQL_TIMESTAMP_DATETIME" ));
struct tm date;
time_t sec_t = sec;
// TODO: Add error check
gmtime_r(&sec_t, &date);
DBUG_PRINT("info" , ("mroonga: tm_year=%d" , date.tm_year));
mysql_time->year = date.tm_year + TM_YEAR_BASE;
DBUG_PRINT("info" , ("mroonga: tm_mon=%d" , date.tm_mon));
mysql_time->month = date.tm_mon + 1 ;
DBUG_PRINT("info" , ("mroonga: tm_mday=%d" , date.tm_mday));
mysql_time->day = date.tm_mday;
DBUG_PRINT("info" , ("mroonga: tm_hour=%d" , date.tm_hour));
mysql_time->hour = date.tm_hour;
DBUG_PRINT("info" , ("mroonga: tm_min=%d" , date.tm_min));
mysql_time->minute = date.tm_min;
DBUG_PRINT("info" , ("mroonga: tm_sec=%d" , date.tm_sec));
mysql_time->second = date.tm_sec;
mysql_time->second_part = usec;
}
break ;
case MYSQL_TIMESTAMP_TIME:
DBUG_PRINT("info" , ("mroonga: MYSQL_TIMESTAMP_TIME" ));
if (sec < 0 ) {
mysql_time->neg = true ;
sec = -sec;
}
mysql_time->hour = static_cast <unsigned int >(sec / 60 / 60 );
mysql_time->minute = sec / 60 % 60 ;
mysql_time->second = sec % 60 ;
mysql_time->second_part = usec;
break ;
default :
DBUG_PRINT("info" , ("mroonga: default" ));
break ;
}
DBUG_VOID_RETURN;
}
long long int TimeConverter::mysql_datetime_to_grn_time(long long int mysql_datetime,
bool *truncated) {
MRN_DBUG_ENTER_METHOD();
MYSQL_TIME mysql_time;
mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME;
mysql_time.neg = 0 ;
mysql_time.second_part = 0 ;
mysql_time.second = (mysql_datetime % 100 );
mysql_time.minute = (mysql_datetime / 100 % 100 );
mysql_time.hour = (mysql_datetime / 10000 % 100 );
mysql_time.day = (mysql_datetime / 1000000 % 100 );
mysql_time.month = (mysql_datetime / 100000000 % 100 );
mysql_time.year = (mysql_datetime / 10000000000 LL % 10000 );
long long int grn_time = mysql_time_to_grn_time(&mysql_time, truncated);
DBUG_RETURN(grn_time);
}
long long int TimeConverter::grn_time_to_mysql_datetime(long long int grn_time) {
MRN_DBUG_ENTER_METHOD();
MYSQL_TIME mysql_time;
mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME;
grn_time_to_mysql_time(grn_time, &mysql_time);
long long int mysql_datetime =
(mysql_time.second * 1 ) +
(mysql_time.minute * 100 ) +
(mysql_time.hour * 10000 ) +
(mysql_time.day * 1000000 ) +
(mysql_time.month * 100000000 ) +
(mysql_time.year * 10000000000 LL);
DBUG_RETURN(mysql_datetime);
}
}
Messung V0.5 in Prozent C=99 H=100 G=99
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-10-08)
¤
*© Formatika GbR, Deutschland