Unix时间戳与C语言的time.h库函数

news2024/11/16 9:31:22

目录

Unix时间戳介绍

UTC/GMT

时间与秒计数器转换代码

time.h库函数


Unix时间戳介绍

Unix 时间戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒

时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量

世界上所有时区的秒计数器相同,不同时区通过添加偏移来得到当地时间

UTC/GMT

GMT(Greenwich Mean Time)格林尼治标准时间是一种以地球自转为基础的时间计量系统。它将地球自转一周的时间间隔等分为24小时,以此确定计时标准

UTC(Universal Time Coordinated)协调世界时是一种以原子钟为基础的时间计量系统。它规定铯133原子基态的两个超精细能级间在零磁场下跃迁辐射9,192,631,770周所持续的时间为1秒。当原子钟计时一天的时间与地球自转一周的时间相差超过0.9秒时,UTC会执行闰秒来保证其计时与地球自转的协调一致

时间与秒计数器转换代码

代码演示结果

#include "stdio.h"

typedef unsigned char  uint8_t;
typedef unsigned short   uint16_t;
typedef unsigned  int   uint32_t;


//时间结构体
typedef struct 
{
	uint8_t hour;
	uint8_t min;
	uint8_t sec;			
	//公历日月年周
	uint16_t w_year;
	uint8_t  w_month;
	uint8_t  w_date;
	uint8_t  week;		 
}_calendar_obj;	

_calendar_obj calendar;//时钟结构体 



uint8_t Judge_Leapyear(uint16_t year);
uint8_t Time_ConvertSec(uint16_t year,uint8_t mon,uint8_t day,uint8_t hour,uint8_t min,uint8_t sec);
uint8_t RTC_GetTime(uint32_t time_cnt);	
uint8_t RTC_GetWeek(uint16_t i,uint8_t month,uint8_t day);


//存储每个月第一天相对于某个基准日(如1900年1月1日是星期一)的天数差。
//例如:2月1日星期四,偏差3										 
const uint8_t  table_week[12]={0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; 

enum week { Sunday = 0, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

//平年的月份日期表
const uint8_t mon_table[12] = {31,28,31,30,31,30,31,31,30,31,30,31};


//判断是否是闰年的函数
//输入:年份
//输出:该年份是不是闰年.1,是.0,不是
uint8_t  Judge_Leapyear(uint16_t year)
{
    if(year % 4 == 0)
    {
        if(year % 100 == 0)
        { 
            if(year % 400 == 0) return 1;
            else return 0;
        }else  return 1;       
    }
    else return 0;
}



//把输入的时间转换为UTC/GMT从1970年1月1日0时0分0秒开始所经过的秒数
//1970~2099年为合法年份
//返回值:0,成功;1,年份非法
uint32_t Sec;

uint8_t Time_ConvertSec(uint16_t year,uint8_t mon,uint8_t day,uint8_t hour,uint8_t min,uint8_t sec)
{
	uint16_t t;
	uint32_t sec_cnt = 0;

	if(year < 1970 || year > 2099) return 1;   
	for(t = 1970; t < year; t++)	//把前面完整年份的秒钟相加
	{
		if(Judge_Leapyear(t)) sec_cnt+=31622400;//闰年的秒钟数
		else sec_cnt+=31536000;			  //平年的秒钟数
	}

	mon-=1;
	for(t = 0;t < mon; t++)	   //把前面完整月份的秒钟数相加
	{
		sec_cnt+=(uint32_t)mon_table[t] * 86400;//月份秒钟数相加
		if(Judge_Leapyear(year) && t == 1) sec_cnt+=86400;//闰年2月份增加一天的秒钟数	   
	}

	sec_cnt+=(uint32_t)(day-1) * 86400;//把前面完整日期的秒钟数相加 
	sec_cnt+=(uint32_t)hour * 3600;//小时秒钟数
    sec_cnt+=(uint32_t)min *  60;	 //分钟秒钟数
	sec_cnt+=sec;//最后的秒钟加上去

    Sec = sec_cnt - 8 * 60 * 60;//因为我们输入的时间为东八区时间,减去偏移
	return 0;	    
}




//获得现在是星期几
//功能描述:输入公历日期得到星期(只允许1901-2099年)																			 
uint8_t RTC_GetWeek(uint16_t year,uint8_t month,uint8_t day)
{	
	uint16_t temp;
	uint8_t yearH,yearL;

	yearH = year / 100;	
	yearL = year % 100; //1~99

	// 1900年不是闰年,所以对于2000年及以后的年份,年份数加100,以模拟从1900年开始的偏移
	if (yearH > 19) yearL+=100;//1~199

	// 所过闰年数只算1900年之后的
	//364天是7的倍数,iL为365与364(先都按平年算)的偏移天数
	//iL / 4是366与365(闰年相对平年的天数)的偏移天数  
	temp = yearL + yearL / 4;//A:1900年1月1日映射到i年1月1日的的偏移的星期总数
	temp = temp % 7; //映射到0~6
	temp = temp + day + table_week[month - 1];
	//默认1900年1月1日是星期一+因年份天数不是7的倍数而多出的偏移星期数+同一个月内相对于1号的星期偏移+不同月份对于1月份偏移数

	if (yearL % 4 == 0 && month < 3) temp--;//A语句已经把闰年多出的天数算了,减去已经算的1天,2月29日过完后偏移才加一1,
	return(temp % 7);
}		



//秒数转换为当前的时间
//返回值:0,成功
uint8_t RTC_GetTime(uint32_t time_cnt)
{
	static uint16_t daycnt = 0;
	
	uint32_t temp = 0;
	uint16_t xtemp = 0;

 	temp = time_cnt / 86400;   //秒钟数对应的天数

	if(daycnt != temp)//超过一天了
	{	  
		daycnt = temp;
		xtemp = 1970;	//从1970年开始
		while(temp >= 365)
		{				 
			if(Judge_Leapyear(xtemp))//是闰年
			{
				if(temp >= 366)temp-=366;//总天数减去闰年的天数
				else {xtemp++;break;}  //年份++
			}
			else temp-=365;	  //总天数减去平年的天数
			xtemp++;  //年份++
		}   
		calendar.w_year = xtemp;//得到年份

		xtemp = 0;//清0,作为新变量
		while(temp >= 28)//超过了一个月
		{
			if(Judge_Leapyear(calendar.w_year) && xtemp == 1)//当年是闰年的2月份
			{
				if(temp >= 29)temp-=29;//闰年的天数
				else break; 
			}
			else //不是闰年的2月份
			{
				if(temp >= mon_table[xtemp])temp-=mon_table[xtemp];
				else break;
			}
			xtemp++;  
		}
		calendar.w_month = xtemp+1;	//得到月份
		calendar.w_date = temp+1;  	//得到日期 
	}

	temp = time_cnt % 86400;     		//得到秒钟数   	   
	calendar.hour = temp / 3600;     	//小时
	calendar.min = (temp % 3600) / 60; 	//分钟	
	calendar.sec = (temp % 3600) % 60; 	//秒钟
	calendar.week = RTC_GetWeek(calendar.w_year, calendar.w_month, calendar.w_date);//获取星期   
	return 0;
}

void main(void)
{
    while(1)
    {
        uint8_t year;
        printf("输入年份判断是不是闰年:");
        scanf("%d", &year);
        if(Judge_Leapyear(year))
            printf("\r\n是闰年\r\n");
        else
            printf("\r\n不是闰年\r\n");
        printf("\r\n\r\n");

        if(!Time_ConvertSec(2024, 9, 13, 15, 14, 55))
        {
            printf("%d\r\n",Sec);
        };
        Sec+=8 * 60 * 60; 
        if(!RTC_GetTime(Sec))
        {
            printf("%d-%d-%d %d:%d:%d  %d\r\n\r\n",calendar.w_year, calendar.w_month, calendar.w_date, calendar.hour, calendar.min, calendar.sec, calendar.week);
        }
    }

}

time.h库函数

C语言的time.h模块提供了时间获取和时间戳转换的相关函数,可以方便地进行秒计数器、日期时间和字符串之间的转换

//time文件里的时间定义
struct tm {
   int tm_sec;         /* 秒,范围从 0 到 59        */
   int tm_min;         /* 分,范围从 0 到 59        */
   int tm_hour;        /* 小时,范围从 0 到 23        */
   int tm_mday;        /* 一月中的第几天,范围从 1 到 31    */
   int tm_mon;         /* 月,范围从 0 到 11        */
   int tm_year;        /* 自 1900 年起的年数        */
   int tm_wday;        /* 一周中的第几天,范围从 0 到 6    */
   int tm_yday;        /* 一年中的第几天,范围从 0 到 365    */
   int tm_isdst;       /* 夏令时                */
};

常用函数 

注意

嵌入式C语言中不能使用前两个。

单片机不知道当地是那个时区,获取当地时间函数都以0时区转换,自己加偏移即可。

我国时间以东八区为准

可用函数

应用案例:【STM32】BKP备份寄存器与RTC实时时钟_stm32 hal bkp-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2133873.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ajax 揭秘:异步 Web 交互的艺术

Ajax 揭秘&#xff1a;异步 Web 交互的艺术 一 . Ajax 的概述1.1 什么是 Ajax ?1.2 同步和异步的区别1.3 Ajax 的应用场景1.3.1 注册表单的用户名异步校验1.3.2 内容自动补全 二 . Ajax 的交互模型和传统交互模型的区别三 . Ajax 异步请求 axios3.1 axios 介绍3.1.1 使用步骤3…

车辆重识别(关于卷积神经网络一些资料)2024/9/11

关于卷积神经网络的介绍 一&#xff0c;全连接神经网络 1&#xff0c;全连接神经网络的整体结构 X代表左边输入的数据&#xff08;向量或者矩阵等等&#xff09;&#xff0c;Y代表模型对数据处理之后的结果&#xff0c;中间的节点都可以算作为隐藏层。 2&#xff0c;全连接神经…

【C++二分查找 容斥原理】1201. 丑数 III

本文涉及的基础知识点 C二分查找 容斥原理&#xff1a;组合数学汇总 LeetCode1201. 丑数 III 丑数是可以被 a 或 b 或 c 整除的 正整数 。 给你四个整数&#xff1a;n 、a 、b 、c &#xff0c;请你设计一个算法来找出第 n 个丑数。 示例 1&#xff1a; 输入&#xff1a;n …

读构建可扩展分布式系统:方法与实践03分布式系统要点

1. 通信基础 1.1. 每个分布式系统都包含通过网络进行通信的软件组件 1.2. 硬件 1.2.1. 全球互联网就是一台异构机器&#xff0c;由不同类型的网络通信通道和设备组成&#xff0c;它们每秒将数百万条消息通过网络传送到预定目的地 1.2.2. 对于单个光纤链路&#xff0c;可以提…

使用gzexe保护Kylin Linux Shell脚本安全

使用gzexe保护Kylin Linux Shell脚本安全 1、加密脚本2、解密脚本3、注意事项 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Kylin Linux中&#xff0c;若需保护shell脚本内容不被直接查看&#xff0c;可以使用gzexe工具进行加密。 1、…

R语言机器学习算法实战系列(一):XGBoost算法(eXtreme Gradient Boosting)

介绍 XGBoost(eXtreme Gradient Boosting)是一种基于梯度提升决策树(GBDT)的优化算法,它在处理大规模数据集和复杂模型时表现出色,同时在防止过拟合和提高泛化能力方面也有很好的表现。以下是XGBoost算法的原理和应用方向的详细介绍: 算法原理 目标函数:XGBoost的目标…

Android 测试机

要测手机应用&#xff0c;直接挂电脑上跑虚拟机的话&#xff0c;怀疑电脑都要起火了。 eBay 上买了个新的机器&#xff0c;也才 100 美元多点&#xff0c;机器都没有拆过&#xff0c;电池是完全无电的状态。 操作系统是 Android 12 的版本&#xff0c;升级到 Android 14 后&am…

从用户数据到区块链:Facebook如何利用去中心化技术

在数字化时代&#xff0c;用户数据的管理和保护已成为科技公司面临的重大挑战。作为全球最大的社交网络平台之一&#xff0c;Facebook不仅在用户数据的处理上积累了丰富的经验&#xff0c;也在探索如何利用去中心化技术&#xff0c;如区块链&#xff0c;来改进其数据管理和用户…

怎么使用ai 免费生成ppt?这4个工具可以帮忙

随之AI工具的流行&#xff0c;网络上也涌现了一批 AIPPT 工具&#xff0c;可以在办公上帮助我们节省很多制作PPT的时间。通常它们的操作也比较简单&#xff0c;所以适合很多人使用。为了可以帮助大家提高办公效率&#xff0c;我在这里跟大家分享4款可以免费使用的AIPPT制作工具…

STM32——看门狗通俗解析

笔者在学习看门狗的视频后&#xff0c;对看门狗仍然是一知半解&#xff0c;后面在实际应用中发现它是一个很好用的检测或者调试工具。所以总结一下笔者作为初学小白对看门狗的理解。 主函数初始化阶段、循环阶段和复位 众所周知&#xff0c;程序的运行一般是这样的&#xff1…

解决项目启动时报“找不到符号”问题

前言 在Java开发过程中&#xff0c;遇到“找不到符号”的错误是非常常见的现象。这种错误往往意味着编译器无法识别你所引用的某个类、方法或变量。本文旨在提供一套详细的排查和解决思路&#xff0c;帮助开发者快速定位并解决此类问题。 问题描述 “找不到符号”错误通常出…

K8S - Volume - NFS 卷的简介和使用

在之前的文章里已经介绍了 K8S 中两个简单卷类型 hostpath 和 emptydir k8s - Volume 简介和HostPath的使用 K8S - Emptydir - 取代ELK 使用fluentd 构建logging saidcar 但是这两种卷都有同1个限制&#xff0c; 就是依赖于 k8s nodes的空间 如果某个service pod中需要的vol…

2024年职场人士都在用的PDF转换工具大赏

PDF文件已经变得越来越常见了&#xff0c;是不是不知不觉你收到的或者发出去的文件都是这个格式。它可以巩固格式&#xff0c;但是编辑起来还是有一定难度的。这篇文章我来分享一些可以从pdf转换器免费版官网下载的工具。 1.Foxit PDF转换大师 链接一下>>https://www.p…

sqlgun靶场漏洞挖掘

进入首页首先看到一个搜索框&#xff0c;那么我们试一下xss 用script弹了个一 接下来我们尝试一下sql注入 这里我们使用联合查询查到了他的数据库名&#xff0c;那么这里也就存在SQL注入了 这里存在SQL注入那么我们就尝试一下是否可以注入木马来getshell 首先我们扫描目录&…

YOLO介绍—datawhale

速度快&#xff1a;YOLO的设计目标是实现快速的对象检测&#xff0c;它在保持相对高准确度的同时&#xff0c;能够实现高帧率的实时检测。 易于实现&#xff1a;YOLO的架构相对简单&#xff0c;易于理解和实现&#xff0c;这使得它在学术和工业界都得到了广泛的应用。 版本迭…

机器学习(西瓜书)第 14 章 概率图模型

14.1 隐马尔可夫模型 机器学习最重要的任务&#xff0c;是根据一些已观察到的证据&#xff08;例如训练样本&#xff09;来对感兴趣的未知变量&#xff08;例如类别标记&#xff09;进行估计和推测。概率模型&#xff08;probabilistic model&#xff09;提供了一种描述框架&a…

快讯丨深蓝L07将于9月20日正式上市

9月13日获悉&#xff0c;继第二十七届成都车展首发亮相后&#xff0c;深蓝汽车全新“科技智享中型轿车”——深蓝L07&#xff0c;将于9月20日迎来正式上市&#xff01; 作为深蓝汽车旗下第二款轿车力作&#xff0c;深蓝L07携#左手深蓝超级增程&#xff0c;右手华为乾崑智能#两…

自动驾驶:LQR、ILQR和DDP原理、公式推导以及代码演示(六、ILQR正则化和line search)

&#xff08;六&#xff09;ILQR正则化和line search 1. ILQR正则化 在iLQR中&#xff0c;我们通常线性化系统动力学并对目标函数进行二阶近似。在反向传播步骤中&#xff0c;我们需要计算逆矩阵&#xff08;控制变量对目标函数的二阶导数矩阵&#xff09;&#xff0c;用以更…

通信工程学习:什么是FDMA频分多址

FDMA&#xff1a;频分多址 FDMA&#xff08;Frequency Division Multiple Access&#xff0c;频分多址&#xff09;是一种在无线通信领域广泛应用的多址技术。该技术通过将可用的频谱资源按频率划分&#xff0c;把传输频带划分为若干较窄且互不重叠的子频带&#xff08;或称信道…

IP-Adapter学习

参考&#xff1a;https://baijiahao.baidu.com/s?id1803373544569190578&wfrspider&forpc IP-Adapter 是 SD中比较重要的controlnet&#xff0c;由腾讯公司出品。主要原理&#xff1a;提取图像特征&#xff0c;并嵌入预训练文本&#xff0c;最终加入到扩散图像中。简…