如何转换UTC日期&时间到C ++中的time_t? [英] How to convert a UTC date & time to a time_t in C++?

查看:69
本文介绍了如何转换UTC日期&时间到C ++中的time_t?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要转换UTC日期&以年,月,日等数字表示的时间为time_t.为此,某些系统提供了 mkgmtime timegm 之类的功能,但这不是标准功能,并且在我的Solaris系统上不存在.

I want to convert a UTC date & time given in numbers for year, month, day, etc. to a time_t. Some systems offer functions like mkgmtime or timegm for this purpose but that is not standard and does not exist on my Solaris system.

到目前为止,我发现的唯一解决方案是使用setenv将本地时区设置为UTC,然后调用 mktime .但是,这种方法不是线程安全的,缓慢的,不可移植的,甚至会在我的系统上产生内存泄漏.

The only solution I have found so far involves setting the local time zone to UTC with setenv and then call mktime. However this approach is not thread-safe, slow, not portable and even generates a memory leak on my system.

我还看到了尝试使用 gmtime 确定当前UTC偏移量,然后将其添加到 mktime 结果中的方法.但据我所知,所有这些方法都存在差距.毕竟,从本地时间到UTC的转换不是唯一的.

I have also seen approaches that tried to determine the current UTC offset using gmtime and then adding that to the result of mktime. But as far as I have seen all those approaches had gaps. After all, the conversion from the local time to UTC is not unique.

您认为什么是最好的解决方案?

What do you think is the best solution?

推荐答案

我决定实现自己的mkgmtime版本,并且比我想象的要容易.

I have decided to implement my own version of mkgmtime and it was easier than I thought.

const int SecondsPerMinute = 60;
const int SecondsPerHour = 3600;
const int SecondsPerDay = 86400;
const int DaysOfMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool IsLeapYear(short year)
{
    if (year % 4 != 0) return false;
    if (year % 100 != 0) return true;
    return (year % 400) == 0;
}

time_t mkgmtime(short year, short month, short day, short hour, short minute, short second)
{
    time_t secs = 0;
    for (short y = 1970; y < year; ++y)
        secs += (IsLeapYear(y)? 366: 365) * SecondsPerDay;
    for (short m = 1; m < month; ++m) {
        secs += DaysOfMonth[m - 1] * SecondsPerDay;
        if (m == 2 && IsLeapYear(year)) secs += SecondsPerDay;
    }
    secs += (day - 1) * SecondsPerDay;
    secs += hour * SecondsPerHour;
    secs += minute * SecondsPerMinute;
    secs += second;
    return secs;
}

我主要担心的是 mkgmtime 必须与 gmtime 保持一致.这样, gmtime(mktime(t))返回原始输入值.因此,我比较了time_t在0和MAX_INT之间的所有61的倍数的结果,它们的确相等(至少在我的系统上).因此上面的例程是正确的.

My main concern was that mkgmtime must be consistent with gmtime. Such that gmtime(mktime(t)) returns the original input values. Therefore I have compared the results for all multiples of 61 between 0 and MAX_INT for time_t and they are indeed equal (at least on my system). Therefore the above routine is correct.

此结果还意味着C库没有考虑leap秒,这本身是一件坏事,但对我而言是有好处的.这两个功能将长期保持一致.绝对可以肯定的是,使用此功能的Timestamp类始终对程序启动执行快速检查,并证明几个有意义的值的一致性.

This outcome also means that the C library does not take leap seconds into account, which is a bad thing in itself but good for my purpose. The two functions will stay consistent for a long time. To be absolutely sure, my Timestamp class that uses this function always performs a quick check on program start and proves the consistency for a couple of meaningful values.

这篇关于如何转换UTC日期&amp;时间到C ++中的time_t?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆