前言
工程中要用到几个时间转换的函数,写了个demo, 验证一下。
实验环境:debian8.8
实验
// @file time_convert.h
// @brief 时间转换
#ifndef __TIME_CONVERT_H__
#define __TIME_CONVERT_H__
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string>
/**
Returns the difference between gmt and local time in seconds.
Use gmtime() and localtime() to keep things simple.
*/
long get_offset_from_gmt_to_local(time_t tm_in);
time_t time_t_add_offset(time_t tm_in, long l_offset);
std::string get_time_t_string(time_t tm_in);
// "2018-07-09 10:12:00" to time_t
time_t time_string_to_time_t(const char* date_time_y_m_d_h_m_s);
time_t get_current_time_t();
struct tm time_t_to_tm(time_t in);
#endif // #ifndef __TIME_CONVERT_H__
// @file time_convert.cpp
// @brief syslog日志宏的实现
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "time_convert.h"
long get_offset_from_gmt_to_local(time_t tm_in)
{
long dt = 0;
long dir = 0;
struct tm *gmt = NULL;
struct tm*loc = NULL;
struct tm sgmt;
if (tm_in == 0) {
tm_in = time(NULL);
}
gmt = &sgmt;
*gmt = *gmtime(&tm_in);
loc = localtime(&tm_in);
dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60
+ (loc->tm_min - gmt->tm_min) * 60;
/**
If the year or julian day is different, we span 00:00 GMT
and must add or subtract a day. Check the year first to
avoid problems when the julian day wraps.
*/
dir = loc->tm_year - gmt->tm_year;
if (dir == 0) {
dir = loc->tm_yday - gmt->tm_yday;
}
dt += dir * 24 * 60 * 60;
return (dt);
}
time_t time_t_add_offset(time_t tm_in, long l_offset)
{
time_t tm_rc = tm_in;
tm_rc += l_offset;
return tm_rc;
}
std::string get_time_t_string(time_t tm_in)
{
char sz_buf[0x100] = {'\0'};
time_t tm_tmp = tm_in;
std::string str_rc = "";
tm* p_tm_gmt = NULL;
p_tm_gmt = gmtime(&tm_tmp);
if (NULL != p_tm_gmt) {
sprintf(sz_buf, "%04d-%02d-%02d %02d:%02d:%02d",
p_tm_gmt->tm_year + 1900,
p_tm_gmt->tm_mon + 1,
p_tm_gmt->tm_mday,
p_tm_gmt->tm_hour,
p_tm_gmt->tm_min,
p_tm_gmt->tm_sec);
str_rc = sz_buf;
}
return str_rc;
}
time_t time_string_to_time_t(const char* date_time_y_m_d_h_m_s)
{
time_t rc;
struct tm tm;
if (NULL != date_time_y_m_d_h_m_s) {
strptime(date_time_y_m_d_h_m_s, "%Y-%m-%d %H:%M:%S", &tm);
rc = mktime(&tm); // t is now your desired time_t
} else {
rc = get_current_time_t();
}
return rc;
}
time_t get_current_time_t()
{
time_t rawtime;
time_t rc;
struct tm* timeinfo = NULL;
time(&rawtime);
timeinfo = localtime(&rawtime);
// if do other case, can modify time now
// e.g.
// timeinfo->tm_year = year - 1900;
// timeinfo->tm_mon = month - 1;
// timeinfo->tm_mday = day;
/* call mktime: timeinfo->tm_wday will be set */
rc = mktime(timeinfo);
return rc;
}
struct tm time_t_to_tm(time_t in)
{
struct tm* timeinfo = NULL;
struct tm rc;
timeinfo = localtime(&in);
memcpy(&rc, timeinfo, sizeof(struct tm));
return rc;
}
// @file main.cpp
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h> // daemon
#include <signal.h>
#include <time.h>
#include "my_syslog.h"
#include "time_convert.h"
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) \
if (NULL != (p)) { \
delete (p); \
(p) = NULL; \
}
#endif // #ifndef SAFE_DELETE
void init(const char* psz_log_owner_name);
void uninit();
void proc_sig_term(int num);
void show_time_stamp(const char* psz_tip, long ts);
int fn_test();
int main(int argc, char** argv)
{
char sz_buf[1024] = {'\0'};
#ifdef MAKE_FILE_MACRO__BIN_NAME
sprintf(sz_buf, "%s", MAKE_FILE_MACRO__BIN_NAME);
init(sz_buf);
MYLOG_D("MAKE_FILE_MACRO__BIN_NAME = [%s]", MAKE_FILE_MACRO__BIN_NAME);
#else
init(NULL);
#endif // #ifdef MAKE_FILE_MACRO__BIN_NAME
fn_test();
uninit();
MYLOG_D("THE END");
return EXIT_SUCCESS;
}
void init(const char* psz_log_owner_name)
{
int i = 0;
daemon(0, 0);
ns_syslog::open_syslog((NULL != psz_log_owner_name) ? psz_log_owner_name : "ns_syslog");
// 设置控制变量中的日志条件, 实际应用中, 是从配置文件读取的控制开关
ns_syslog::g_log_condition.b_EMERG = false;
ns_syslog::g_log_condition.b_CRIT = true;
ns_syslog::g_log_condition.b_ALERT = true;
ns_syslog::g_log_condition.b_ERR = true;
ns_syslog::g_log_condition.b_WARNING = true;
ns_syslog::g_log_condition.b_NOTICE = true;
ns_syslog::g_log_condition.b_INFO = true;
ns_syslog::g_log_condition.b_DEBUG = true;
// 根据控制变量, 设置日志的mask
// 在实际应用中, 这里可以是动态设置, e.g. 配置文件检测线程发现配置变了, 需要变更某些级别的日志记录结果
ns_syslog::set_log_level(
ns_syslog::g_log_condition.b_EMERG,
ns_syslog::g_log_condition.b_ALERT,
ns_syslog::g_log_condition.b_CRIT,
ns_syslog::g_log_condition.b_ERR,
ns_syslog::g_log_condition.b_WARNING,
ns_syslog::g_log_condition.b_NOTICE,
ns_syslog::g_log_condition.b_INFO,
ns_syslog::g_log_condition.b_DEBUG);
// clear screen (print 25 empty line)
for (i = 0; i < 25; i++) {
MYLOG_D("");
}
signal(SIGTERM, proc_sig_term);
}
void uninit()
{
ns_syslog::close_syslog();
}
void proc_sig_term(int num)
{
MYLOG_D("SIGTERM = %d, num = %d", SIGTERM, num);
MYLOG_D("maybe can do some clean task before quit");
exit(1);
}
int fn_test()
{
time_t time_t_give_by_user;
struct tm tm_give_by_user;
time_t time_t_cur;
struct tm tm_cur;
MYLOG_D(">> fn_test()");
time_t_give_by_user = time_string_to_time_t("2018-07-08 10:46:06");
tm_give_by_user = time_t_to_tm(time_t_give_by_user);
// https://en.cppreference.com/w/c/chrono/tm
MYLOG_D("tm_give_by_user = %d-%d-%d %d:%d:%d",
tm_give_by_user.tm_year + 1900,
tm_give_by_user.tm_mon + 1,
tm_give_by_user.tm_mday,
tm_give_by_user.tm_hour,
tm_give_by_user.tm_min,
tm_give_by_user.tm_sec);
time_t_cur = get_current_time_t();
tm_cur = time_t_to_tm(time_t_cur);
MYLOG_D("tm_cur = %d-%d-%d %d:%d:%d",
tm_cur.tm_year + 1900,
tm_cur.tm_mon + 1,
tm_cur.tm_mday,
tm_cur.tm_hour,
tm_cur.tm_min,
tm_cur.tm_sec);
/* run result
Jul 9 11:01:24 localhost test_timezone[1663]: [DEBUG : main.cpp.34 : main()] : MAKE_FILE_MACRO__BIN_NAME = [test_timezone]
Jul 9 11:01:24 localhost test_timezone[1663]: [DEBUG : main.cpp.104 : fn_test()] : >> fn_test()
Jul 9 11:01:24 localhost test_timezone[1663]: [DEBUG : main.cpp.116 : fn_test()] : tm_give_by_user = 2018-7-8 10:46:6
Jul 9 11:01:24 localhost test_timezone[1663]: [DEBUG : main.cpp.127 : fn_test()] : tm_cur = 2018-7-9 11:1:24
Jul 9 11:01:24 localhost test_timezone[1663]: [DEBUG : main.cpp.42 : main()] : THE END
*/
// tm_now = time(NULL); // 1521255156, 这种是秒数
// MYLOG_D("tm_now = %lld", (long long)tm_now);
// show_time_stamp("current local time", tm_now);
// 1520906625610 这种是时间戳,是毫秒数
// show_time_stamp("3rd give time 1", 1520906625610 / 1000);
// show_time_stamp("3rd give time 2", 1520920367484 / 1000);
return 0;
}
void show_time_stamp(const char* psz_tip, long ts)
{
time_t tm_fixed;
long l_offset = 0;
MYLOG_D("%s", (NULL != psz_tip) ? psz_tip : "show_time_stamp");
// 28800 is 8hours(8 * 60 * 60 second)
l_offset = get_offset_from_gmt_to_local(ts);
tm_fixed = time_t_add_offset(ts, l_offset);
MYLOG_D("tm_fixed = %lld => %s", (long long)tm_fixed, get_time_t_string(tm_fixed).c_str());
}
2018_0709_1418
还需要比较2个time_t, 验证了一下。
time_t_begin = get_current_time_t();
sleep(2);
time_t_end = get_current_time_t();
db_offset = difftime(time_t_end, time_t_begin);
MYLOG_D("difftime(time_t_end, time_t_begin) = %d", (int)db_offset);
db_offset = difftime(time_t_begin, time_t_end);
MYLOG_D("difftime(time_t_begin, time_t_end) = %d", (int)db_offset);
/* run result
Jul 9 14:16:03 localhost test_timezone[2406]: [DEBUG : main.cpp.118 : fn_test()] : difftime(time_t_end, time_t_begin) = 2
Jul 9 14:16:03 localhost test_timezone[2406]: [DEBUG : main.cpp.121 : fn_test()] : difftime(time_t_begin, time_t_end) = -2
*/