Linux日期时间
2019/10/27
date +%D
2019-10-27
date +%F
07:08:09
date +%T
2019
date +%Y
时间戳
date +%s
[exper@linuxprobe Desktop]$ date +%F
2019-10-27
[exper@linuxprobe Desktop]$ date +%T
07:28:29
[exper@linuxprobe Desktop]$ date +%D
10/27/19
[exper@linuxprobe Desktop]$ date +%Y
2019
[exper@linuxprobe Desktop]$ date+"%Y:%M:%S"
2019:31:05
[exper@linuxprobe Desktop]$ date +%s
1572132955
[exper@linuxprobe Desktop]$ date+"%Y-%m-%d
%H:%M:%S"
2019-10-27 07:40:16
[exper@linuxprobe Desktop]$ date +"%F%T"
2019-10-27 07:44:25
[exper@linuxprobe Desktop]$ date +"%D%T"
10/27/19 07:44:44
C日期时间处理函数
常用函数和时间结构
#include
#ifndef __TIME_T
#define __TIME_T
typedef
long time_t;
#endif
time_t为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。
Unix时间戳不仅被使用在Unix系统,类Unix系统中也被广泛采用。
目前相当一部分操作系统使用32位二进制数字表示时间,此类系统的Unix时间戳最多可以使用到格林威治时间2038年01月19日03时14分07秒(二进制:01111111
11111111 11111111 11111111)。其后一秒,二进制数字会变为10000000
00000000 00000000
00000000,发生溢出错误,造成系统将时间误解为1901年12月13日20时45分52秒。这很可能会引起软件故障,甚至是系统瘫痪。
使用64位二进制数字表示时间的系统(最多可以使用到格林威治时间292,277,026,596年12月04日15时30分08秒)则基本不会遇到这类溢出问题。
struct tm
{
int
tm_sec;
int
tm_min;
int
tm_hour;
int
tm_mday;
int
tm_mon;
1+p->tm_mon;
int
tm_year;
1900+ p->tm_year;
int
tm_wday;
int
tm_yday;
int
tm_isdst;
};
需要特别注意的是,年份是从1900年起至今多少年,而不是直接存储如2011年,月份从0开始的,0表示一月,星期也是从0开始的,
0表示星期日,1表示星期一。
函数原型:
time_t time(time_t *time);
该函数返回系统的当前日历时间。自1970年1月1日以来经过的秒数,如果系统没有时间,返回-1。
样例如下:
#include
#include
using namespace std;
int main(int argc, char* argv[])
{
time_t
t;
t=
time(NULL);
time_t
t2;
time(&t2);
cout
<< "t= "
<< t <<
"; t2= "<< t2
<< endl;
time_t
t3 = 2147483647;
struct
tm tt;
localtime_r(&t3,
&tt);
char
buf[64] = {0};
strftime(buf,
sizeof(buf), "%Y-%m-%d %H:%M:%S", &tt);
cout
<< buf
<< endl;
t3 =
-2147483648;
struct tm tt1;
localtime_r(&t3,
&tt1);
char
buf1[64] = {0};
strftime(buf1,
sizeof(buf1), "%Y-%m-%d %H:%M:%S",
&tt1);
cout <
<< endl;
cout <
<< '-'
<< tt1.tm_mon + 1
<< '-'
<
<< ' '
<< tt1.tm_hour
<
<< tt1.tm_min
<< ':'
<< tt1.tm_sec
<< endl;
return
0;
}
[exper@linuxprobe src]$ ./testtime
t= 1572138944; t2= 1572138944
2038-01-19 11:14:07
1901-12-14 03:52:12
1901-12-14 3:52:12
time_t这种类型就是用来存储从1970年到现在经过了多少秒,要想更精确一点,可以用结构structtimeval,它精确到微妙。struct
timeval{ long tv_sec;
long tv_usec;
};
函数原型:
#include
int gettimeofday(struct timeval *restricttp, void
*restrict tzp);
样例如下:
include
#include
#include
using namespace std;
int main(int argc, char* argv[])
{
struct
timeval tv1;
gettimeofday(&tv1,
NULL);
cout
<< tv1.tv_sec
<< ' '
<< tv1.tv_usec
<
return
0;
}
小结:利用time和gettimeofday获取到当前的时间戳,然后利用localtime_r获得struct
tm结构。利用tm自行组装时间字符串或者调用strftime得到字符串的日历时间。
若是已知字符串日历时间,需要得到当前的时间戳,则需要做如下转换:
首先,将字符串日历时间转换成struct tm结构;
#define
_XOPEN_SOURCE
#include
char *strptime(const char *s, const char*format, struct tm
*tm);
其次,将struct tm转换成时间戳
time_t mktime(struct tm *tm);
样例如下:
#include
#include
using namespace std;
int main(int argc, char* argv[])
{
struct
tm tm1;
char
buf[] = "2019-10-10 10:10:10";
strptime(buf,
"%Y-%m-%d %H:%M:%S", &tm1);
cout
<< tm1.tm_year + 1900
<< '/'
<< tm1.tm_mon +
1<< '/'
<< \
tm1.tm_mday
<< ' '
<< tm1.tm_hour
<< ':'
<
<< ':'
<< tm1.tm_sec
<< endl;
time_t
t;
t=
mktime(&tm1);
cout
<< t <<
endl;
return
0;
}
[exper@linuxprobe src]$ ./strtimetostamp
2019/10/10 10:10:10
1570673410
如果时间精度需要到到达纳秒级别,则需要使用如下的时间结构:
#ifndef _TIMESPEC#define _TIMESPECstruct timespec {time_t
tv_sec; // seconds long tv_nsec; // and
nanoseconds };#endifstruct
timespec有两个成员,一个是秒,一个是纳秒,所以最高精确度是纳秒。一般由函数int
clock_gettime(clockid_t, struct timespec
*)获取特定时钟的时间,常用如下4种时钟:CLOCK_REALTIME统当前时间,从1970年1.1日算起CLOCK_MONOTONIC系统的启动时间,不能被设置CLOCK_PROCESS_CPUTIME_ID本进程运行时间CLOCK_THREAD_CPUTIME_ID本线程运行时间
样例如下:
#include
#include
using namespace std;
int main(int argc, char* argv[])
{
struct
timespec ts;
clock_gettime(CLOCK_REALTIME,
&ts);
cout
<< ts.tv_sec
<< ' '
<< ts.tv_nsec
<< endl;
return
0;
}
[exper@linuxprobe src]$ ./nstime
1572141768 75658932