作者

QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118

参考

Linux下时间/时区的设置
linux C 之时间函数
Linux C 函数(日期时间) --转
linux 的时区设置函数tzset()
Linux在C语言下的时区设置与修改(一)
Linux在C语言下的时区设置与修改(二)
Linux在C语言下的时区设置与修改(三)
将GPS获得的UTC时间转换成本地时间的方法
时间日期与时间戳转换(Linux C)
Linux内核中获取当前时间

内核中时间的获取

采用和用户态相同的gettimeofday

 #include <linux/time.h>void do_gettimeofday(struct timeval *tv);

或者

#include <linux/time.h>
struct timespec current_kernel_time(void);

内核相关结构体定义,都是long类型

struct timespec {__kernel_time_t tv_sec;         /* seconds */long       tv_nsec;        /* nanoseconds */
};struct timeval {__kernel_time_t       tv_sec;     /* seconds */__kernel_suseconds_t   tv_usec;    /* microseconds */
};struct timezone {int  tz_minuteswest; /* minutes west of Greenwich */int  tz_dsttime; /* type of dst correction */
};

时钟和时区

世界标准时间(Coordinated Universal Time,UTC),也就是大家所熟知的格林威治标准时间(Greenwich Mean Time,GMT)。世界各地时间也世界标准时间为基准划分为不同的时区,例如,中国的北京时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5。
Calendar Time:日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。无论哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。日历时间返回自1970-1-1:00:00:00以来所经过的秒数累计值。
关于linux的系统时钟和硬体时钟:linux系统有两个时钟,一个是系统时钟,一个是硬体时钟(CMOS),硬体时钟就是主板上通过晶振计时的时钟,通常是由一块电池供电,一般能用三年左右。Linux系统在启动时,会先读取硬体时钟,把硬体时钟的时间设置为当前的系统时间,之后,系统时间就和硬体时钟独立运行了。系统时钟由linux内核维 护,硬体时钟还是晶振控制。
1,时间保存在硬件实时钟(RTC)中,RTC由主板电池供电,即使关断电源也不会造成时间丢失。
2,系统启动时从RTC获取时间,这个步骤在rc.sysinit中做:
a,首先从/etc/sysconfig/clock中获取RTC相关参数UTC/ARC/SRM。UTC为true表示RTC保存的时间是UTC时间,false表示保存的是本地时间。ARC与SRM的含义参考hwclock的manpage,一般false即可;
b,根据上面获取的内容构造hwclock命令的参数,将时间由RTC读取到系统时钟。
*需要说明的一点是hwclock的输出是本地时间,localtime/utc参数只是用 来告诉hwclock命令COMS时区是哪个时区。比如Linux系统的系统时区设置为CST(中国标准时间),COMS时间采用墙上时间,即COMS时 区也是CST,这时如果使用–utc参数,会让hwclock误以为COMS时区为UTC,所以输出的时间会自动+8。
3,tzset():tzset在程序中用来初始化tzname等全局变量,它首先试图从环 境变量“TZ”中获取时区,如果TZ环境变量存在,即getenv(“TZ”)返回值不为NULL,且包含内容有效,则使用TZ值;如果该变量存在但内容 无效,比如包含错误的时区名字,则使用UTC;如果该变量不存在,即getenv(“TZ”)返回NULL,则查找系统时区设置文件,一般是/etc /localtime。localtime所指文件的内容格式可参考tzfile(5)。
4,time():返回自00:00:00 UTC, January 1, 1970到现在所经过的秒数,注意,是UTC。
5,ctime()/localtime()/mktime():这类和时区相关的函数内部会调用tzset,但只是第一次调用tzset会做实际初始化,后面的调用都是直接返回。
6,系统关闭时,如执行shutdown/reboot/poweroff/halt等操作后,系统时间会保存到RTC中,这是在halt脚本中完成的,参看/etc/init.d/halt内容。

跟日期时间相关的shell命令

$ date                    // 显示当前日期
$ time                   // 显示程序运行的时间
$ hwclock             // 显示与设定硬件时钟
$ clock                  // 显示与设定硬件时钟,是hwclock的链接文件
$ cal                      // 显示日历

linux c语言时间时区数据结构和接口

type.h

类型 time_t是一个signed long类型,

__STD_TYPE __TIME_T_TYPE __time_t;   /* Seconds since the Epoch.  */

time.h

struct tm结构体,


struct tm
{int tm_sec;            /* Seconds. [0-60] (1 leap second) */int tm_min;            /* Minutes. [0-59] */int tm_hour;           /* Hours.   [0-23] */int tm_mday;           /* Day.     [1-31] */int tm_mon;            /* Month.   [0-11] */int tm_year;           /* Year - 1900.  */int tm_wday;         /* Day of week. [0-6] */int tm_yday;            /* Days in year.[0-365] */int tm_isdst;         /* DST.     [-1/0/1]*/# ifdef   __USE_MISClong int tm_gmtoff;       /* Seconds east of UTC.  */const char *tm_zone;     /* Timezone abbreviation.  */
# elselong int __tm_gmtoff;     /* Seconds east of UTC.  */const char *__tm_zone;   /* Timezone abbreviation.  */
# endif
};

函数接口clock,time,difftime,mktime,strftime,mktime以本地时间的年月日为参数,将其变换成time_t值,

__BEGIN_NAMESPACE_STD
/* Time used by the program so far (user time + system time).The result / CLOCKS_PER_SECOND is program time in seconds.  */
extern clock_t clock (void) __THROW;/* Return the current time and put it in *TIMER if TIMER is not NULL.  */
extern time_t time (time_t *__timer) __THROW;/* Return the difference between TIME1 and TIME0.  */
extern double difftime (time_t __time1, time_t __time0)__THROW __attribute__ ((__const__));/* Return the `time_t' representation of TP and normalize TP.  */
extern time_t mktime (struct tm *__tp) __THROW;/* Format TP into S according to FORMAT.Write no more than MAXSIZE characters and return the numberof characters written, or 0 if it would exceed MAXSIZE.  */
extern size_t strftime (char *__restrict __s, size_t __maxsize,const char *__restrict __format,const struct tm *__restrict __tp) __THROW;
__END_NAMESPACE_STD

sfrftime的格式化参数,

%a 当地星期日期的名称缩写, 如:Sun
%A当地星期日期的名称缩写, 如: Sunday
%b当地月份的缩写
%B 当地月份的完整名称
%c 当地适当的日期与时间表示法
%C 以year/100表示年份
%d 月里的天数, 表示法为01-31
%D 相当于"%m%d%y"格式
%e 月里的天数, 表示法为1-31
%h 当地月份的缩写
%H 以24小时制表示小时数, 表示法为00-23
%I 以12小时制表示小时数, 表示法为01-12
%j 一年中的天数(001-366)
%k 以24小时制表示小时数, 表示法为0-23
%l 以12小时制表示小时数, 表示法为1-12
%m 月份(01-12)
%M 分钟数(00-59)
%n 同\n
%p 显示对应的AM或PM
%P 显示对应的am或pm
%r 相当于使用"%I:%M:%S %p"格式
%R 相当于使用"%H:%M"格式
%s 从1970年1月1日0时0分0秒算起至今的UTC时间所经过的秒数
%S 秒数(00-59)
%t 同\t
%T 24小时时间表示, 相当于"%H:%M:%S"格式
%u 一星期中的星期日期, 范围1-7, 星期一从1开始
%U 一年中的星期数(00-53), 一月第一个星期日开始为01
%w 一星期中的星期日期, 范围0-6, 星期日从0开始
%W 一年中的星期数(00-53), 一月第一个星期一开始为01
%x 当地适当的日期表示
%X 当地适当的时间表示
%y 一世纪中的年份表示
%Y 完整的公元年份表示
%Z 使用的时区名称
%% '%'符号

函数接口gmtime,localtime,

__BEGIN_NAMESPACE_STD
/* Return the `struct tm' representation of *TIMERin Universal Coordinated Time (aka Greenwich Mean Time).  */
extern struct tm *gmtime (const time_t *__timer) __THROW;/* Return the `struct tm' representationof *TIMER in the local timezone.  */
extern struct tm *localtime (const time_t *__timer) __THROW;
__END_NAMESPACE_STD

函数接口asctime,ctime,

__BEGIN_NAMESPACE_STD
/* Return a string of the form "Day Mon dd hh:mm:ss yyyy\n"that is the representation of TP in this format.  */
extern char *asctime (const struct tm *__tp) __THROW;/* Equivalent to `asctime (localtime (timer))'.  */
extern char *ctime (const time_t *__timer) __THROW;
__END_NAMESPACE_STD

函数接口stime,

# ifdef __USE_MISC
/* Set the system time to *WHEN.This call is restricted to the superuser.  */
extern int stime (const time_t *__when) __THROW;
# endif

函数接口timegm,timelocal,

# ifdef __USE_MISC
/* Miscellaneous functions many Unices inherited from the public domainlocaltime package.  These are included only for compatibility.  *//* Like `mktime', but for TP represents Universal Time, not local time.  */
extern time_t timegm (struct tm *__tp) __THROW;/* Another name for `mktime'.  */
extern time_t timelocal (struct tm *__tp) __THROW;/* Return the number of days in YEAR.  */
extern int dysize (int __year) __THROW  __attribute__ ((__const__));
# endif

函数接口tzset,

# ifdef  __USE_POSIX
/* Same as above.  */
extern char *tzname[2];/* Set time conversion information from the TZ environment variable.If TZ is not defined, a locale-dependent default is used.  */
extern void tzset (void) __THROW;
# endif

执行该函数之前先设置环境变量,

setenv("TZ", "GMT-8", 1);

例子,

#include <stdio.h>
#include <time.h>
int main(void)
{time_t timep;time(&timep);printf("%s", ctime(&timep));printf("%s", asctime(gmtime(&timep)));return 0;
}

bits/time.h

struct timeval结构体,

/* A time value that is accurate to the nearestmicrosecond but also has a range of years.  */
struct timeval{__time_t tv_sec;     /* Seconds.  */__suseconds_t tv_usec;   /* Microseconds.  */};

sys/time.h

struct timezone结构体

/* Structure crudely representing a timezone.This is obsolete and should never be used.  */
struct timezone{int tz_minuteswest;     /* Minutes west of GMT.  */int tz_dsttime;      /* Nonzero if DST is ever in effect.  */};

tz_dsttime 所代表的状态如下,

DST_NONE /*不使用*/
DST_USA /*美国*/
DST_AUST /*澳洲*/
DST_WET /*西欧*/
DST_MET /*中欧*/
DST_EET /*东欧*/
DST_CAN /*加拿大*/
DST_GB /*大不列颠*/
DST_RUM /*罗马尼亚*/
DST_TUR /*土耳其*/
DST_AUSTALT /*澳洲(1986年以后)*/

函数gettimeofday,settimeofday,返回值 成功则返回0,失败返回-1,错误代码存于errno。附加说明EFAULT指针tv和tz所指的内存空间超出存取权限,

/* Get the current time of day and timezone information,putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.Returns 0 on success, -1 on errors.NOTE: This form of timezone information is obsolete.Use the functions and variables declared in <time.h> instead.  */
extern int gettimeofday (struct timeval *__restrict __tv,__timezone_ptr_t __tz) __THROW __nonnull ((1));#ifdef __USE_MISC
/* Set the current time of day and timezone information.This call is restricted to the super-user.  */
extern int settimeofday (const struct timeval *__tv,const struct timezone *__tz)__THROW;/* Adjust the current time of day by the amount in DELTA.If OLDDELTA is not NULL, it is filled in with the amountof time adjustment remaining to be done from the last `adjtime' call.This call is restricted to the super-user.  */
extern int adjtime (const struct timeval *__delta,struct timeval *__olddelta) __THROW;
#endif

settimeofday函数例子,

/************************************************
参数:*dt数据格式为"2006-4-20 20:30:30"
**************************************************/
int SetSystemTime(char *dt)
{struct rtc_time tm;struct tm _tm;struct timeval tv;time_t timep;sscanf(dt, "%d-%d-%d %d:%d:%d", &tm.tm_year,&tm.tm_mon, &tm.tm_mday,&tm.tm_hour,&tm.tm_min, &tm.tm_sec);_tm.tm_sec = tm.tm_sec;_tm.tm_min = tm.tm_min;_tm.tm_hour = tm.tm_hour;_tm.tm_mday = tm.tm_mday;_tm.tm_mon = tm.tm_mon - 1;_tm.tm_year = tm.tm_year - 1900;timep = mktime(&_tm);tv.tv_sec = timep;tv.tv_usec = 0;if(settimeofday (&tv, (struct timezone *) 0) < 0){printf("Set system datatime error!\n");return -1;}system("hwclock  -w");  //写到硬时钟return 0;
}

linux时间时区和GPS/BD授时相关推荐

  1. Linux时间 时区 同步

    Linux时间 时区 同步卸载ntp服务 pi@raspberrypi:~ $ sudo apt-get remove ntp安装ntpdate客户端 pi@raspberrypi:~ $ sudo ...

  2. LINUX 时间 /时区

    LINUX 时间 /时区 一.设置linux修改时区 首先查看当前时区 #date -R 显示结果为: [root@localhost 20190528]# date -R Wed, 29 May 2 ...

  3. linux系统时间函数,Linux时间时区详解与常用时间函数

    时间与时区 整个地球分为二十四时区,每个时区都有自己的本地时间. UTC时间 与 GMT时间 我们可以认为格林威治时间就是时间协调时间(GMT = UTC),格林威治时间和UTC时间都用秒数来计算的. ...

  4. linux - 时间时区设置

    关键词:时间 时区 docker时区设置 时间戳转换 北京时间 date 设置时区 TZ='Asia/Shanghai' TZ='Asia/Shanghai' date "+%F__%T__ ...

  5. Linux修改时区和时间

    Linux修改时区和时间 修改时区: 1> 找到相应的时区文件 /usr/share/zoneinfo/Asia/Shanghai  用这个文件替换当前的/etc/localtime文件.  或 ...

  6. Linux 时间、时区设置

    Linux 时间.时区设置 CentOS 7: Chrony https://chrony.tuxfamily.org/index.html https://www.cnblogs.com/zydev ...

  7. linux时间为什么是上海,设置CentOS系统时间为上海时区,解决相差8小时解决方法...

    改成上海时区timedatectl set-timezone Asia/Shanghai GPS 系统中有两种时间区分,一为UTC,另一为LT(地方时)两者的区别为时区不同,UTC就是0时区的时间,地 ...

  8. linux 设置时间为昨天,Linux —— 时间(tzselect、timedatactl命令,查看和修改时区,修改时区为东八区)...

    一.设置linux修改时区 首先查看当前时区 #date -R 显示结果为: [root@localhost 20190528]# date -R Wed, 29 May 2019 19:56:23 ...

  9. Linux下修改时间时区

    Linux下修改时间时区 Linux时钟分为系统时钟(System Clock)和硬件(Real Time Clock,简称RTC)时钟.系统时钟是指当前Linux Kernel中的时钟,而硬件时钟则 ...

最新文章

  1. mysql 写入400_MySQL5.7运行CPU达百分之400处理方案
  2. 我理解的配置管理系统
  3. Android Service学习之本地服务
  4. Spring boot的Bean使用JSR 303校验
  5. 『线性空间 整数线性基和异或线性基』
  6. 上传图片至服务器,写入到数据库Blob字段中,以及从数据库读取Blob信息(iframe父子页面传值)(1)
  7. FlashDevelop 3.0.0 Beta2 released
  8. Oozie安装ExtJs教程
  9. 泰坦尼克号数据分析!
  10. 电路基础知识 -- 虚短和虚断
  11. JavaScript设置背景图片
  12. PassMark 更新排行,苹果 M1 杀疯了
  13. 按“Win+E”键出现【找不到应用程序】或【explore.exe找不到】的解决方法
  14. excel同一行中如何添加换行
  15. 中国最美丽地方排行榜及游览最佳时间
  16. where is java_Linux下的搜索查找命令的详解(whereis)
  17. PDF.js 实现pdf分页加载的前端优化(实现按需加载)-前端的demo也已经上传
  18. 用R语言分析詹姆斯的客场得分
  19. Cytoskeleton / 艾美捷——泛素化亲和珠
  20. 软件架构设计的底层逻辑

热门文章

  1. Navicat 连接数据库报错:1045-Access denied for user ‘root‘@‘localhos
  2. 谷歌(Chrome)浏览器 视频播放全屏退出时死机
  3. 2021 CCPC 哈尔滨 E. Power and Modulo (思维题)
  4. 什么样的程序员适合去创业公司
  5. 资深程序员雷总对代码的执念
  6. 多实例下的定时任务如何避免重复执行——分布式定时任务
  7. Linux Kernel compile
  8. 泡芙噶的计算机网络(3)-扑朔迷离的Cisco Packet Tracer实验
  9. 大学计算机基础实验指导word,大学计算机基础实验指导全套.doc
  10. 解读大内老A的《.NET Core框架本质》