Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >c++11:使用HowardHinnant/date.h解析ISO8601格式字符串,并解决时区问题

c++11:使用HowardHinnant/date.h解析ISO8601格式字符串,并解决时区问题

作者头像
10km
发布于 2021-09-26 03:30:52
发布于 2021-09-26 03:30:52
1.2K00
代码可运行
举报
文章被收录于专栏:10km的专栏10km的专栏
运行总次数:0
代码可运行

C++11提供了std::get_time函数用于解析时间格式字符串,解析成功后将时间保存在std::tm结构中。

但是对于ISO8601标准中有毫秒精度的字符串比如('2014-11-12T19:12:14.505+0800')是不支持的。

如何解析这种有毫秒精度的时间字符串呢?

HowardHinnant/date

通过stakoverflow上的这个贴子:

《how do I parse an iso 8601 date (with optional milliseconds) to a struct tm in C++?》 https://stackoverflow.com/questions/26895428/how-do-i-parse-an-iso-8601-date-with-optional-milliseconds-to-a-struct-tm-in-c

我知道github上的开源代码HowardHinnant/date提供了这种支持.核心代码只有一个date.h头文件。include进来就可以使用。

下面是从贴子中抄来的使用HowardHinnant/date对ISO8601标准时间字符串解析的示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "date.h"
#include <iostream>
#include <sstream>

date::sys_time<std::chrono::milliseconds>
parse8601(std::istream&& is)
{
    std::string save;
    is >> save;
    std::istringstream in{save};
    date::sys_time<std::chrono::milliseconds> tp;
    in >> date::parse("%FT%TZ", tp);
    if (in.fail())
    {
        in.clear();
        in.exceptions(std::ios::failbit);
        in.str(save);
        in >> date::parse("%FT%T%Ez", tp);
    }
    return tp;
}

int
main()
{
    using namespace date;
    using namespace std;
    // 这里输出显示为UTC时间
    cout << parse8601(istringstream{"2014-11-12T19:12:14.505Z"}) << '\n';
    cout << parse8601(istringstream{"2014-11-12T12:12:14.505-5:00"}) << '\n';
}

注意事项

  1. 要注意的是如果字符串中没有指定时区,HowardHinnant/date在解析时会自动解析成UTC时间,而不是本地时间。这与std::get_time是不一样的。
  2. 第二个问题是如果字符串中没有日期,只有时间(如12:12:14),HowardHinnant/date不能正确解析,所以建议是要判断日期格式,如果日期字符串没有只有时间,还是用std::get_time来解析.

时区问题

对于第一个问题其实HowardHinnant/date也提供了解决方案。进一步阅读HowardHinnant/date的源码,发现date::parse函数有好几个重载函数。上面的示例中只是用了参数最少最简单的一个,下面date::parse函数这个有4个参数的版本,后面两个参数都是用于时区设置的,如果正确指定了时区参数,解析出来的时间就是当前时区的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <class Parsable, class CharT, class Traits, class Alloc>
inline
auto
parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
      std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset)
  • abbrev 指定提供时区名字缩写,如CST–中国标准时间(但这个参数似乎无效,我没有深究)
  • offset 相对GMT时间以分钟为单位时区偏移,比如北京时间东八区就是8x60=480。

这个第二个参数就是指定当前时区与GMT时间的偏移.默认这个参数为0,如果指定了该参数,则转换后的时间是以当前时区计算的时间。

所以上面的例子代码做如下修改,就可以支持将未指定时区的字符串解析为本地时间.说明参见代码中的中文注释。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 增加一个时区偏移参数 offset
static date::sys_time<std::chrono::milliseconds>
parse8601(std::istream&& is,int offset = 0/** 时区偏移 */)
{
    std::string save;
    is >> save;
    std::istringstream in{save};
    date::sys_time<std::chrono::milliseconds> tp;
    // 将 offset 传递给data:parse
    in >> date::parse("%FT%TZ", tp,std::string(), std::chrono::minutes(offset));
    if (in.fail())
    {
        in.clear();
        in.exceptions(std::ios::failbit);
        in.str(save);
        in >> date::parse("%FT%T%Ez", tp);
    }
    return tp;
}

int
main()
{
    using namespace date;
    using namespace std;
    // 这里输出显示为UTC时间
    cout << parse8601(istringstream{"2014-11-12T19:12:14.505Z"}) << '\n';
    cout << parse8601(istringstream{"2014-11-12T12:12:14.505-5:00"}) << '\n';
    /** 
     * 下面这个字符串没有指定时区,我们希望它解析为当前时间,
     * 所以offset使用北京时间(+08:00)的时区偏移
     */
    cout << parse8601(istringstream{"2014-11-12T12:12:14.505"},480) << '\n';
}

上面的例子中480仅对+08:00时区有效,如何自动获取当前时区的偏移呢?

参见我的上一篇博客:

《c,c++:获取当前时区偏移》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/09/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python | 时间戳转换
爬数据的时候,有没有遇见过爬下来的数据日期显示为一大串数字?像上图中的beginbidtime变量,这是时间戳。时间戳是啥?是指格林威治时间自 1970 年 1 月 1 日(00:00:00 GMT)(一般把这个时点称为 unix 纪元或 POSIX 时间)至当前时间的总秒数。时间戳的好处是能够唯一地表示某一刻的时间,但这显然不利于肉眼观察和分析数据,所以下面我们将时间戳转化为常见的时间格式。
PyStaData
2020/09/14
3.7K0
Python | 时间戳转换
《Pandas Cookbook》第10章 时间序列分析1. Python和Pandas日期工具的区别2. 智能切分时间序列3. 只使用适用于DatetimeIndex的方法4. 计算每周的犯罪数5.
一些时间差的别名 http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
SeanCheney
2018/11/20
4.8K0
【原创干货】6000字、22个案例详解Pandas数据分析/预处理时的实用技巧,超简单
上两篇原创的文章,小编主要是讲了数据可视化方面的内容,但是好像看得人不是很多的样子(搞得小编心里拔凉拔凉的....)
用户6888863
2022/04/13
1.6K0
【原创干货】6000字、22个案例详解Pandas数据分析/预处理时的实用技巧,超简单
Pandas-21.时间
Pandas-21.时间 now print(pd.datetime.now()) # 2019-04-03 23:06:58.992842 Timestamp print(pd.Timestamp("2020-1-1")) # 2020-01-01 00:00:00 print(pd.Timestamp(1588686880, unit='s')) # 2020-05-05 13:54:40 date_range print(pd.date_range("12:00", "14:30",freq="30m
悠扬前奏
2019/05/29
4880
Pandas DateTime 超强总结
对于 Pandas 来说,可以处理众多的数据类型,其中最有趣和最重要的数据类型之一就是时间序列数据。时间序列数据无处不在,它在各个行业都有很多应用。患者健康指标、股票价格变化、天气记录、经济指标、服务器、网络、传感器和应用程序性能监控都是时间序列数据的应用方向
周萝卜
2022/05/22
5.6K0
Pandas DateTime 超强总结
7个常用的Pandas时间戳处理函数
Pandas 库中有四个与时间相关的概念 日期时间:日期时间表示特定日期和时间及其各自的时区。它在 pandas 中的数据类型是 datetime64[ns] 或 datetime64[ns, tz]。 时间增量:时间增量表示时间差异,它们可以是不同的单位。示例:"天、小时、减号"等。换句话说,它们是日期时间的子类。 时间跨度:时间跨度被称为固定周期内的相关频率。时间跨度的数据类型是 period[freq]。 日期偏移:日期偏移有助于从当前日期计算选定日期,日期偏移量在 pandas 中没有特定的数据类
数据STUDIO
2022/05/24
1.5K0
Pandas处理时间序列数据的20个关键知识点
时间序列数据有许多定义,它们以不同的方式表示相同的含义。一个简单的定义是时间序列数据包括附加到顺序时间点的数据点。
deephub
2020/09/23
2.8K0
Pandas处理时间序列数据的20个关键知识点
pandas多表操作,groupby,时间操作
使用场景:有两张表left和right,一般要求它们的表格结构一致,数据量也一致,使用right的数据去填补left的数据缺漏 如果在同一位置left与right数据不一致,保留left的数据
李智
2018/08/03
3.8K0
pandas多表操作,groupby,时间操作
Pandas 2.2 中文官方教程和指南(二十一·二)
有时,我们需要调整箱子的开始而不是结束,以便使用给定的freq进行向后重新采样。向后重新采样默认将closed设置为'right',因为最后一个值应被视为最后一个箱子的边缘点。
ApacheCN_飞龙
2024/05/24
5470
Pandas时序数据处理入门
作为一个几乎每天处理时间序列数据的人,我发现pandas Python包对于时间序列的操作和分析非常有用。
AiTechYun
2019/09/08
4.2K0
《利用Python进行数据分析·第2版》第11章 时间序列11.1 日期和时间数据类型及工具11.2 时间序列基础11.3 日期的范围、频率以及移动11.4 时区处理时区本地化和转换11.5 时期及其
时间序列(time series)数据是一种重要的结构化数据形式,应用于多个领域,包括金融学、经济学、生态学、神经科学、物理学等。在多个时间点观察或测量到的任何事物都可以形成一段时间序列。很多时间序列是固定频率的,也就是说,数据点是根据某种规律定期出现的(比如每15秒、每5分钟、每月出现一次)。时间序列也可以是不定期的,没有固定的时间单位或单位之间的偏移量。时间序列数据的意义取决于具体的应用场景,主要有以下几种: 时间戳(timestamp),特定的时刻。 固定时期(period),如2007年1月或201
SeanCheney
2018/04/24
6.7K0
《利用Python进行数据分析·第2版》第11章 时间序列11.1 日期和时间数据类型及工具11.2 时间序列基础11.3 日期的范围、频率以及移动11.4 时区处理时区本地化和转换11.5 时期及其
整理总结 python 中时间日期类数据处理与类型转换(含 pandas)
我自学 python 编程并付诸实战,迄今三个月。 pandas可能是我最高频使用的库,基于它的易学、实用,我也非常建议朋友们去尝试它。——尤其当你本身不是程序员,但多少跟表格或数据打点交道时,pandas 比 excel 的 VBA 简单优雅多了。
刘娟娟PRESSone
2019/10/25
2.3K0
数据导入与预处理-拓展-pandas时间数据处理01
数据导入与预处理-拓展-pandas时间数据处理01 数据导入与预处理-拓展-pandas时间数据处理02 数据导入与预处理-拓展-pandas时间数据处理03
用户2225445
2022/11/12
6.7K0
数据导入与预处理-拓展-pandas时间数据处理01
python+pandas+时间、日期以及时间序列处理方法
先简单的了解下日期和时间数据类型及工具 python标准库包含于日期(date)和时间(time)数据的数据类型,datetime、time以及calendar模块会被经常用到。datetime以毫秒形式存储日期和时间,datetime.timedelta表示两个datetime对象之间的时间差。给datetime对象加上或减去一个或多个timedelta,会产生一个新的对象
公众号---人生代码
2019/08/30
1.7K0
Pandas处理时间序列数据-入门
在pandas中,时间戳(Timestamp,通常指的是自1970年1月1日(UTC)以来的秒数)是用于表示特定时间点的数据类型。它是pandas库中用于时间序列分析的一个重要组成部分,基于Python的datetime模块但提供了更丰富的功能。时间戳不仅包含日期(年、月、日),还包含时间(时、分、秒,以及可选的毫秒、微秒和纳秒)。
皮大大
2024/09/05
2970
【硬核干货】Pandas模块中的数据类型转换
我们在整理数据的时候,经常会碰上数据类型出错的情况,今天小编就来分享一下在Pandas模块当中的数据类型转换的相关技巧,干货满满的哦!
用户6888863
2023/03/01
1.7K0
【硬核干货】Pandas模块中的数据类型转换
5招学会Pandas数据类型转化
日常数据处理中,经常需要对一些数据进行类型转化以便于后续的处理,由于自己不太喜欢记住它们,所以每次不记得具体函数方法的时候都是搜索一下,感觉还是有点Fei时间。
可以叫我才哥
2021/09/03
1.5K0
5招学会Pandas数据类型转化
Pandas非常用技巧汇总
注意:由于NaN的存在,B列初始的数据类型是float,如果要变成整数,使用astype转换即可。
致Great
2023/08/25
5490
时间序列 | 字符串和日期的相互转换
在数据处理过程中,难免会遇到日期格式,特别是从外部读取数据到jupyter或其他python编译器中,用于数据处理分析时。若读取excel文档时还能保留原本日期时间格式,但有时却差强人意,读取后为字符串格式,尤其是以csv格式存储的数据。此时就需要用到字符串转日期格式。
数据STUDIO
2021/06/24
7.5K0
Pandas 2.2 中文官方教程和指南(二十一·一)
pandas 包含一组紧凑的 API,用于执行窗口操作 - 一种在值的滑动分区上执行聚合的操作。该 API 的功能类似于groupby API,Series和DataFrame调用具有必要参数的窗口方法,然后随后调用聚合函数。
ApacheCN_飞龙
2024/05/24
4260
推荐阅读
相关推荐
Python | 时间戳转换
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验