使用C语言编写windows特有的_mktime64和_localtime64_s

网上看到有编写_mktime64的帖子,但是他们写的_mktime64输出的结果与Windows的输出结果不一致。经过本人对windows的_mktime64函数实现的跟踪研究,发现网上最接近正确答案的写法缺少对时区的计算。

一、_mktime64 日期时间转int64

/*
 *相比网上其它帖子的源码进行完善,输出结果与windows自带的_mktime64输出结果一致
 *_tm为当前真实日期,此处与windows的入参有所不同
 */
_int64 _mktime64(const tm& _tm)
{
    tm _tmp = _tm;
    if (0 >= (int) (_tmp.tm_mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
         _tmp.tm_mon += 12;      /* Puts Feb last since it has leap day */
         _tmp.tm_year -= 1;
    }

    return  ((((_tmp.tm_year/4 - _tmp.tm_year/100 + _tmp.tm_year/400 + 367*_tmp.tm_mon/12 + _tmp.tm_mday) +
                        _tmp.tm_year*365 - 719499
                    )*24 + _tmp.tm_hour /* now have hours */
                )*60 + _tmp.tm_min /* now have minutes */
            )*60 + _tmp.tm_sec /* finally seconds */
            - 8*3600; /*时区*/
};

二、_localtime64_s int64转日期时间

void _localtime64_s(const long long& _iTime, tm& _tm)
{
    #define CHCK_IS_LEAP_YEAR(y)  (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
    int startYear = 1970;
    long long _iTimep = _iTime;
    _iTimep += 8*3600;

    _tm.tm_sec = _iTimep % 60;
    _tm.tm_min = ((_iTimep - _tm.tm_sec) / 60) % 60;
    _tm.tm_hour  = (((_iTimep - _tm.tm_sec) / 60 - _tm.tm_min) / 60) % 24;

    int _alldays = (((_iTimep - _tm.tm_sec) / 60 - _tm.tm_min) / 60 - _tm.tm_hour) / 24;

    _tm.tm_wday = _alldays % 6 + 1;
    _tm.tm_isdst = 0;
    _tm.tm_year = _alldays / 365 + startYear; /*简易算法,直接用365整除,目前满足计算结果*/

    int _ndays = 0; /*计算从startYear到_tm.tm_year-1年总计天数*/
    for(int i = startYear; i < _tm.tm_year; i++)
    {
        if(CHCK_IS_LEAP_YEAR(i)){
            _ndays += 366;
        }else{
            _ndays += 365;
        }
    }

    int k,leap;
    int yearday = _alldays - _ndays;
    _tm.tm_yday = yearday;
    int _months_days[2][13] =
    {
        {0,31,28,31,30,31,30,31,31,30,31,30,31},
        {0,31,29,31,30,31,30,31,31,30,31,30,31}
    };

    if(CHCK_IS_LEAP_YEAR(_tm.tm_year)){
        leap = 1;
    }else{
        leap = 0;
    }

    for(k = 1; yearday > _months_days[leap][k]; k++)
        yearday -= _months_days[leap][k];
    _tm.tm_mon = k;
    _tm.tm_mday = yearday + 1;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值