在 C 中将时间从 UTC 更改为本地时间

问题描述

我想在本地时间输出 America/Los_Angeles 到日志文件。目前,我正在获取 UTC 时间。我希望在这三个函数中存在一个解决方案。

/* src/lib/timing.c line 196 */
char* xdebug_nanotime_to_chars(uint64_t nanotime,unsigned char precision)
{
        char *res;
        time_t secs;

        secs = (time_t)(nanotime / NANOS_IN_SEC);
        if (precision > 0) {
                res = xdmalloc(30);
        } else {
                res = xdmalloc(20);
        }
        strftime(res,20,"%Y-%m-%d %H:%M:%s",gmtime(&secs));
        if (precision > 0) {
                sprintf(res + 19,".%09u",(uint32_t)(nanotime % NANOS_IN_SEC));
                if (precision < 9) {
                        *(res + 20 + precision) = '\0';
                }
        }
        return res;
}

打开日志。使用 log_open_timestring 函数设置 xdebug_nanotime_to_chars

/* src/lib/log.c line 586 */
void xdebug_open_log(void)
{
        /* initialize remote log file */
        XG_LIB(log_file) = NULL;
        XG_LIB(log_opened_message_sent) = 0;
        XG_LIB(log_open_timestring) = NULL;

        if (XINI_LIB(log) && strlen(XINI_LIB(log))) {
                XG_LIB(log_file) = xdebug_fopen(XINI_LIB(log),"a",NULL,NULL);
        }
        if (XG_LIB(log_file)) {
                XG_LIB(log_open_timestring) = xdebug_nanotime_to_chars(xdebug_get_nanotime(),6);
        } else if (strlen(XINI_LIB(log))) {
                xdebug_log_diagnose_permissions(XLOG_CHAN_LOGFILE,XINI_LIB(log));
        }
}

打印日志打开时间到日志文件

/* src/lib/log.c line 56 */
static inline void xdebug_internal_log(int channel,int log_level,const char *message)
{
        zend_ulong pid;

        if (!XG_LIB(log_file)) {
                return;
        }

        pid = xdebug_get_pid();

        if (!XG_LIB(log_opened_message_sent) && XG_LIB(log_open_timestring)) {
                XG_LIB(log_opened_message_sent) = 1;

                fprintf(XG_LIB(log_file),"[" ZEND_ULONG_FMT "] Log opened at %s\n",pid,XG_LIB(log_open_timestring));
                fflush(XG_LIB(log_file));
                xdfree(XG_LIB(log_open_timestring));
                XG_LIB(log_open_timestring) = NULL;
        }

        fprintf(
                XG_LIB(log_file),"[" ZEND_ULONG_FMT "] %s%s%s\n",xdebug_channel_name[channel],xdebug_log_prefix[log_level],message
        );

        fflush(XG_LIB(log_file));
}

解决方法

这最终变得非常简单。

我所要做的就是将 gmtime 更改为 localtime,现在所有输出都在我的系统时间而不是 UTC 中。

(当然,也必须从我修改后的源代码编译 Xdebug。)

/* src/lib/timing.c line 196 */
char* xdebug_nanotime_to_chars(uint64_t nanotime,unsigned char precision)
{
        char *res;
        time_t secs;

        secs = (time_t)(nanotime / NANOS_IN_SEC);
        if (precision > 0) {
                res = xdmalloc(30);
        } else {
                res = xdmalloc(20);
        }
        /* strftime(res,20,"%Y-%m-%d %H:%M:%S",gmtime(&secs)); */ right here!
        strftime(res,localtime(&secs));
        if (precision > 0) {
                sprintf(res + 19,".%09u",(uint32_t)(nanotime % NANOS_IN_SEC));
                if (precision < 9) {
                        *(res + 20 + precision) = '\0';
                }
        }
        return res;
}

输出现在与我当前的时区相匹配,即下午 5 点之前:

[12122] Log opened at 2020-12-31 16:50:29.447626
[12122] Log closed at 2020-12-31 16:50:29.780099

如果我想绝对清楚,我想我可以将时区标识符添加到行尾。如果我这样做,我会编辑我的答案。

编辑:我添加了时区标识符。我创建了一个新函数,用于日志打开和关闭函数。

/* src/lib/log.c */
const char* custom_get_tz() /* placed near top of file */
{
        time_t t = time(NULL);
        struct tm lt = {0};
        localtime_r(&t,&lt);
        return lt.tm_zone;
}
.
.
.
 /* around line 63 */
static inline void xdebug_internal_log(int channel,int log_level,const char *message)
{
.
.
.
    /* fprintf(XG_LIB(log_file),"[" ZEND_ULONG_FMT "] Log opened at %s\n",pid,XG_LIB(log_open_timestring)); */
    fprintf(XG_LIB(log_file),"[" ZEND_ULONG_FMT "] Log opened at %s %s\n",XG_LIB(log_open_timestring),custom_get_tz());
.
.
.
}
.
.
.
/* around line 610 */
void xdebug_close_log()
{
.
.
.
    /* fprintf(XG_LIB(log_file),"[" ZEND_ULONG_FMT "] Log closed at %s\n\n",timestr); */
    fprintf(XG_LIB(log_file),"[" ZEND_ULONG_FMT "] Log closed at %s %s\n\n",timestr,custom_get_tz());
.
.
.
}

通过将系统时区更改为 America/Goose_Bay 和 UTC 进行测试:

[31250] Log opened at 2021-01-02 13:44:07.952185 PST
.
.
.
[31250] Log closed at 2021-01-02 13:44:07.957961 PST

[31252] Log opened at 2021-01-02 17:45:55.684079 AST
.
.
.
[31252] Log closed at 2021-01-02 17:45:55.687655 AST

[31254] Log opened at 2021-01-02 21:47:18.788958 UTC
.
.
.
[31254] Log closed at 2021-01-02 21:47:18.792282 UTC

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...