关于时间类型(time.h)-时间与字符串转换

时间类型


在进行程序开发的过程中,免不了和时间打交道,下面就是一些关于WIndows和Linux的时间类型分析

预习知识


Unix时间戳,Unix时间,POSIX时间,这三种表达方式都是一样的。代表了从格林威治时间(世界时)1970年1月1号00时00分00秒起知道现在的秒数。

因为操作系统一般用32位2进制数表示时间,那么可以知道系统Unix时间戳最多可以使用到2038年1月19号3时14分07秒,在下一秒时会发生溢出。如果使用64位二进制则不会出现错误。

一般来说时间分为:

  • 本地时间
  • 格林位置时间(世界时):根据地球转速周期性差异矫正后时间
  • 时间协调时间:以地球自转为基础的时间标准

时间在Linux中的两种表示方法


  • time_t:存储了从1970年到现在经过了多少秒。如果想要更加精确的时间,可以使用struct timeval,可以精确到微秒

    struct timeval
    {
    long tv_sec;
    //秒
    long tv_usec;
    //微秒
    }
    
  • tm:用结构分别存储年、月、日、时、分、秒

    struct tm
    {
        int tm_sec;  
        //秒,正常范围0-59, 但允许至61
        int tm_min;  
        //分钟,0-59
        int tm_hour; 
        //小时, 0-23
        int tm_mday; 
        //日,即一个月中的第几天,1-31
        int tm_mon;   1+p->tm_mon;
        //月, 从一月算起,0-11
        int tm_year;   1900+ p->tm_year;
        //年, 从1900至今已经多少年
        int tm_wday; 
        //星期,一周中的第几天, 从星期日算起,0-6
        int tm_yday; 
        //从今年1月1日到目前的天数,范围0-365
        int tm_isdst; 
        //夏令时,冬令时的标志(不要忘记赋值,不知道就-1)
    };
    

    需要特别注意的是,年份是从1900年起至今多少年,而不是直接存储如2011年,月份从0开始的,0表示一月,星期也是从0开始的, 0表示星期日,1表示星期一。

常用的时间函数


  1. #include <time.h>
    char *asctime(const struct tm* timeptr);
    

    该函数将tm格式的时间转化为真实世界的时间,类型为字符串。

    注意:该函数的输出格式为Wed Aug 14 04:21:25 2019,这个格式尽量不要参与运算。

  2. char *ctime(const time_t *timep);
    

    将time_t格式的时间转化为真实世界实参,类型为字符串。

    注意:该函数的输出格式为Wed Aug 14 04:21:25 2019,这个格式尽量不要参与运算。

  3. double difftime(time_t time1, time_t time2);
    

    返回两个时间相差的秒数,其实time_t是unsigned long类型,可以直接相减

  4. int gettimeofday(struct timeval *tv, struct timezone *tz);
    

    返回当前时间距离1970年的秒数和微秒数,后面的参数是时区

  5. struct tm* gmtime(const time_t *timep);
    

    将time_t时间转化为没有经过时区转换的UTC时间,转化后的格式是struct tm结构指针

  6. stuct tm* localtime(const time_t *timep);
    

    将time_t转化为经过时区转换的时间,转化后的格式是struct tm结构指针

  7. time_t mktime(struct tm* timeptr);
    

    将tm格式时间转化为time_t的格式(自1970到今天的秒数)

  8. time_t time(time_t *t);
    

    获得现在时间的time_t的格式(自1970到现在的秒数)

时间格式的转化


在实际使用中我们经常希望将事件格式转化为我们希望的到的格式,而不是asctime或者ctime所给出的格式

时间与字符串的相互转化

我们知道Unix环境下有strptime函数,所以在Unix和windows环境下代码有些许差别

前置知识
strftime函数
  1. 函数定义

    C 库函数 size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr) 根据 format 中定义的格式化规则,格式化结构 timeptr 表示的时间,并把它存储在 str 中。

  2. 函数声明

    size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr);
    
  3. 函数参数类型

    • str – 这是指向目标数组的指针,用来复制产生的 C 字符串
    • maxsize – 这是被复制到 str 的最大字符数
    • format – 这是 C 字符串,包含了普通字符和特殊格式说明符的任何组合。这些格式说明符由函数替换为表示 tm 中所指定时间的相对应值
    • 格式说明符:
    %a 星期几的简写
    %A 星期几的全称
    %b 月分的简写
    %B 月份的全称
    %c 标准的日期的时间串
    %C 年份的后两位数字
    %d 十进制表示的每月的第几天
    %D 月/天/年
    %e 在两字符域中,十进制表示的每月的第几天
    %F 年-月-日
    %g 年份的后两位数字,使用基于周的年
    %G 年分,使用基于周的年
    %h 简写的月份名
    %H 24小时制的小时
    %I 12小时制的小时
    %j 十进制表示的每年的第几天
    %m 十进制表示的月份
    %M 十时制表示的分钟数
    %n 新行符
    %p 本地的AM或PM的等价显示
    %r 12小时的时间
    %R 显示小时和分钟:hh:mm
    %S 十进制的秒数
    %t 水平制表符
    %T 显示时分秒:hh:mm:ss
    %u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)
    %U 第年的第几周,把星期日做为第一天(值从0到53)
    %V 每年的第几周,使用基于周的年
    %w 十进制表示的星期几(值从0到6,星期天为0)
    %W 每年的第几周,把星期一做为第一天(值从0到53)
    %x 标准的日期串
    %X 标准的时间串
    %y 不带世纪的十进制年份(值从0到99)
    %Y 带世纪部分的十制年份
    %z,%Z 时区名称,如果不能得到时区名称则返回空字符。
    %% 百分号
    
strptime函数
  1. 函数定义

    strptime主要用于把字符串转换成分解时间,与strftime的作用相反。都位于<time.h>中,原型如下:
    extern char *strptime (__const char *__restrict __s, __const char *__restrict __fmt, struct tm *__tp);

  2. 函数形参

    第一个形参是传入的时间格式字符串"2022-09-01 12:23:09"
    第二个形参是需要传入的时间格式
    第三个参数是一个tm的结构体指针

需要包括的头文件如下:

#include <iostream>
#include <time.h>
#include <cstdlib>
#include <string>
时间转字符串代码(Unix,windows)
time_t t;  //秒时间
tm* local; //本地时间 
tm* gmt;   //格林威治时间
char buf[128]= {0};
 
t = time(NULL); //获取目前秒时间
local = localtime(&t); //转为本地时间
strftime(buf, 64, "%Y-%m-%d %H:%M:%S", local);
std::cout << buf << std::endl;
 
gmt = gmtime(&t);//转为格林威治时间
strftime(buf, 64, "%Y-%m-%d %H:%M:%S", gmt);
std::cout << buf << std::endl;
字符串转时间代码Unix
tm tm_;
time_t t_;
char buf[128]= {0};
 
strcpy(buf, "2012-01-01 14:00:00");
strptime(buf, "%Y-%m-%d %H:%M:%S", &tm_); //将字符串转换为tm时间
tm_.tm_isdst = -1;
t_  = mktime(&tm_); //将tm时间转换为秒时间
t_ += 3600;  //秒数加3600
 
tm_ = *localtime(&t_);//输出时间
strftime(buf, 64, "%Y-%m-%d %H:%M:%S", &tm_);
std::cout << buf << std::endl;

字符串转时间代码Windows
time_t StringToDatetime(char *str)
{
    tm tm_;
    int year, month, day, hour, minute,second;
    sscanf(str,"%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);
    tm_.tm_year  = year-1900;
    tm_.tm_mon   = month-1;
    tm_.tm_mday  = day;
    tm_.tm_hour  = hour;
    tm_.tm_min   = minute;
    tm_.tm_sec   = second;
    tm_.tm_isdst = 0;
 
    time_t t_ = mktime(&tm_); //已经减了8个时区
    return t_; //秒时间
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值