• C语言时间函数gmtime和localtime


    time_t的值是什么?

    当通过time函数获取系统时间的时候,time_t得到的是一个计算机系统时间是按照UTC时间计算的从1970年1月1日0时开始的秒数。因此,在当前某一时刻,无论运行的计算机在地球哪个时区,其通过time(NULL)函数获得的time_t的值都是相同的。

    localtime 函数

    time_t转换为可读的本地时间格式用localtime函数。

    gmtime 函数

    time_t转换为可读的UTC时间格式用gmtime函数。

    mktime函数

    既然计算机的time_t使用统一的UTC时间基准计时。在struct tm对象到time_t时,却只提供了一个转换函数:mktime函数。但是它却是把本地时间格式的struct tm对象转到time_t(注意,time_t只有UTC格式)。为何没有UTC时间格式的转换函数?(本文无答案)。

    我们通过下面的程序验证:

    #include 
    #include 
    
    time_t tp = 0;
    time_t tn = 0;
    struct tm *tmp = 0;
    time(&tp);
    printf("time():%d\n",tp);
    tmp = localtime(&tp);
    tn = mktime(tmp);
    printf("time()->localtime()->mktime(): %d\n", tn);
    tmp = gmtime(&tp);
    tn = mktime(tmp);
    printf("time()->gmtime()->mktime(): %d\n", tn);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    运行结果:

    time(): 1659079214
    time()->localtime()->mktime(): 1659079214
    time()->gmtime()->mktime(): 1659050414
    
    • 1
    • 2
    • 3

    查阅文档得知,mktime函数是将struct tm对象作为本地时间转换为time_t

    参考:

    • https://linux.die.net/man/3/gmtime
    • https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mktime-mktime32-mktime64?view=msvc-170
    • https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/gmtime.3.html

    从time_t到struct tm

    当我们在处理涉及全球时间的程序时,分2种情况(此处仅讨论Windows和Linux):

    • 如果time_t的值是从time(NULL)函数或者已知为本地系统时间而来,则需要用gmtime函数来转换为struct tm对象。
    • 如果time_t的值是从其他已知的UTC时间而来,则需要用localtime函数来转换为struct tm对象。

    从struct tm到time_t

    如果需要将struct tm格式的时间转换为time_t,而struct tm对象如果不是本地时间,则需要在mktime执行以后,加上一个本地时间到UTC时间的偏移秒数。

    多时区时间转换

    如果需要处理其他时区的时间,可以使用boost的local_time。他可以获得不同时区与UTC的时间差,还可以在不同时区直接用boost::local_date_time::local_time_in (boost::local_time::time_zone_ptr)函数从一个时区的时间转换为另一个时区的时间。并且可以处理烦人的冬夏令时。

    #include "boost/date_time/local_time/local_time.hpp"
    boost::local_time::tz_database tz_db;
    const char* filename = "date_time_zonespec.csv";
    tz_db.load_from_file(filename);
    const char* region = "America/New_York";
    boost::local_time::time_zone_ptr tz = tz_db.time_zone_from_region(region);
    boost::posix_time::ptime t(boost::posix_time::second_clock::universal_time());
    boost::local_time::local_date_time dt(t, tz);
    auto t1 = dt.local_time();
    auto td = t1 - t;	// 这是指定时区和UTC时区相差的秒数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    参考:

    https://www.boost.org/doc/libs/1_78_0/doc/html/date_time/examples.html

  • 相关阅读:
    QueryDet项目实战应用
    【我不熟悉的css】09-深度选择器deep不好使
    Leetcode1021. 删除最外层的括号(simple)
    SwiftUI Apple App Store 发布App的初学者完整指南
    HTML中的语义化标签
    asp.net core mvc区域路由
    MySQL索引
    【技术积累】软件工程中的测试驱动开发【一】
    函数(上)
    [BSidesCF 2019]Futurella 1
  • 原文地址:https://blog.csdn.net/sunny_98_98/article/details/126057133