使用strptime函数时遇到的一个坑

做新专辑排序的需求时,需要对专辑的时间进行排序,由于目前该字段是字符串类型的日期,在排序函数中要转成标准的UNIX时间戳来进行对比,大概代码如下:

struct tm tm1;
strptime(string("2018-01-18").c_str(), "%Y-%m-%d", &tm1);
time_t t1 = mktime(&tm1);
std::cout << t1 << endl;

struct tm tm2;
strptime(string("2011-11-11").c_str(), "%Y-%m-%d", &tm2);
time_t t2 = mktime(&tm2);
std::cout << t2 << endl;

std::cout << "result:" << ((t1 > t2) ? "true" : "false") << endl;

一个很简单的字符串转时间戳进行比较的逻辑,但是运行后发现,mktime()返回的时间戳很随机,明显有异常。

3175021632//错误的时间戳
1320966000
result:true
...
2765263112//错误的时间戳
1320966000
result:true

查看mktime()的API:

Notes If the std::tm object was obtained from std::get_time or the POSIX strptime, the value of tm_isdst is indeterminate, and needs to be set explicitly before calling mktime.

这里有提到说如果是从strptime()取到的值,tm_isdst的值是不确定的,必须手动指定。因此想到,是否对于未做初始化的struct tmstrptime()函数并不会去给每个值赋值。查看strptime

It is unspecified whether multiple calls to strptime() using the same tm structure will update the current contents of the structure or overwrite all contents of the structure. Conforming applications should make a single call to strptime() with a format and all data needed to completely specify the date and time being converted.

因此,解决方法就是在使用strptime()之前,对结构体进行零初始化(zero-initialize)

struct tm tm1 = {0};
...
struct tm tm2 = {0};

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏纯洁的微笑

jvm系列(一):java类的加载机制

1、什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Cl...

41060
来自专栏老马寒门IT

Node入门教程(5)第四章:global 全局变量

global - 全局变量 全局对象(global object),不要和 全局的对象( global objects )或称标准内置对象混淆。这里说的全局的对...

30740
来自专栏重庆的技术分享区

AngularJs指令解密

17570
来自专栏无题

堆外内存概要

DirectByteBuffer JDK中使用 DirectByteBuffer对象来表示堆外内存,每个 DirectByteBuffer对象在初始化时,都会创...

25340
来自专栏生信宝典

Bash概论 - Linux系列教程补充篇

本篇是我最开始学习Linux命令时看的一篇帖子,最早见于ChinaUnix (这次查找其出处时发现2002年就有这篇)。学习过程中,遇到问题就查一下。这次看到,...

20370
来自专栏雪胖纸的玩蛇日常

老男孩Python全栈开发(92天全)视频教程 自学笔记05

22940
来自专栏java一日一条

【Java并发编程】使用wait/notify/notifyAll实现线程间通信的几点重要说明

在 Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信。在线程中调用 wait(...

10030
来自专栏Python、Flask、Django

PHP htmlspecialchars_decode()函数

13540
来自专栏前端杂货铺

内置对象,原生对象和宿主对象

js内置对象是ECMAScript规范中要求实现的一些函数和对象,具体包括Object,Function,Number,Boolean,Array, Strin...

30250
来自专栏乐百川的学习频道

设计模式(二十三) 模板模式

模板模式也是一种行为型模式,而且它非常好理解。当我们解决问题需要固定几个步骤, 这些步骤的顺序不能改变,而步骤的具体实现可以变化的时候,就可以使用模板模式。模板...

17560

扫码关注云+社区

领取腾讯云代金券