在 C 中将时间从 UTC 更改为本地时间
Change time from UTC to local time in C
我想在本地时间输出,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) = '[=10=]';
}
}
return res;
}
打开日志。使用 xdebug_nanotime_to_chars
函数设置 log_open_timestring
。
/* 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, NULL, 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",
pid,
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, 20, "%Y-%m-%d %H:%M:%S", localtime(&secs));
if (precision > 0) {
sprintf(res + 19, ".%09u", (uint32_t)(nanotime % NANOS_IN_SEC));
if (precision < 9) {
*(res + 20 + precision) = '[=10=]';
}
}
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, <);
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", pid, 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", pid, timestr); */
fprintf(XG_LIB(log_file), "[" ZEND_ULONG_FMT "] Log closed at %s %s\n\n", pid, 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
我想在本地时间输出,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) = '[=10=]';
}
}
return res;
}
打开日志。使用 xdebug_nanotime_to_chars
函数设置 log_open_timestring
。
/* 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, NULL, 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",
pid,
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, 20, "%Y-%m-%d %H:%M:%S", localtime(&secs));
if (precision > 0) {
sprintf(res + 19, ".%09u", (uint32_t)(nanotime % NANOS_IN_SEC));
if (precision < 9) {
*(res + 20 + precision) = '[=10=]';
}
}
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, <);
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", pid, 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", pid, timestr); */
fprintf(XG_LIB(log_file), "[" ZEND_ULONG_FMT "] Log closed at %s %s\n\n", pid, 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