聊聊UTC时间那些事

本文介绍了在单片机项目中如何处理UTC时间和Unix时间戳,详细阐述了UTC时间的概念,并解释了Unix时间戳的定义,包括闰秒的处理。讨论了如何在单片机上实现UTC到Unix时间戳的转换,提供了部分代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做了一个单片机的项目,采用外接RTC模块,而外接模块只有年月日时分秒寄存器,需要用到时间戳对发生的事件和日志做记录。于是就想做一个使用在单片机上的UTC转Unix时间戳的库。

先说一下什么是UTC时间,UTC是Coordinated Universal Time缩写,中文又称协调世界时。在了解UTC时间系统的时候,还有一个叫GMT的时间系统,GMT中文称为格林威治标准时间。严格意义上来说UTC是最接近GMT的,但是对于大多数用途来说,UTC时间是可以与GMT时间进行互换的。目前GMT时间已不再被科学界所确定。更多的关于UTC时间的介绍请移步https://en.wikipedia.org/wiki/Coordinated_Universal_Time,哈哈,作者偷个懒

搞清楚什么是UTC时间之后,我们就需要知道另一个概念Unix时间戳,什么是Unix时间戳呢,看一下定义:Unix时间戳是从1970年1月1日(UTC的午夜),可以理解为1970年1月1日 00:00:00,开始所经过的秒数,不考虑闰秒。有童鞋会问什么是闰秒,简单的来说,地球由于自身的自转在变慢,每一天并不是真的只有86400秒,每天慢一点,每天慢一点,过了很多年就慢出了一秒来了,那这一秒要怎么处理呢,当然是加进去了,这就是闰秒。更多详细信息,请移步上述链接。

搞清楚以上的概念之后呢,我们就来搞清楚我们的问题是什么:

  1. 将Unix时间戳转换为对应时区的UTC时间;
  2. 将对应时区的UTC时间转换为Unix时间戳;

先来解决第一个问题,。。。。。废话不多说,直接上代码

#ifndef TIMEMODULE_H
#define TIMEMODULE_H

typedef unsigned long UnixTime_t;

#pragma pack(1)
typedef struct _TimeZone_t{
	
<think>嗯,用户这次要查SQLServer的时间查询格式和用法,看来是在处理数据库的时间操作问题。之前系统指令要求技术回答要用中文、数学公式要LaTeX格式,这个需求倒是用不上数学公式。用户提到“参考站内引用”,但翻看对话历史发现上次的引用示例是关于快速排序的,和当前需求完全无关。这说明用户可能复制了系统模板忘记删掉,实际要解决的就是纯SQL问题。注意到用户用了“尽可能多参考上一次回答”的表述——但其实这是首次讨论SQL话题,历史对话只有那个快速排序的例子。用户可能误以为我们聊过类似内容?不过没关系,专注解决当前问题就好。用户需求很明确:要时间查询的格式和实例。重点应该是SQLServer特有的日期时间类型(比如datetime和datetime2的区别)以及如何正确格式化查询条件。用户可能是遇到条件筛选不生效的问题,或是刚接触SQLServer的时间处理。先从基础覆盖起:日期类型解释、WHERE条件写法、不同精度的时间段查询。特别是凌晨时间点容易出错的00:00:00问题,一定要用闭区间说明。另外考虑补充常见错误场景,比如忘记毫秒导致的漏查数据问题。示例部分准备用具体场景:查当天记录(凌晨陷阱问题)、本周数据(星期天特殊处理)、时间范围查询(精准到毫秒的写法)。系统函数如GETDATE()和CONVERT()是实用重点。相关问题的延伸要围绕实际开发痛点:时区转换(国际业务常见)、计算字段(时效统计)、性能优化(时间字段索引失效问题)。用户没提时区,但可能后续遇到问题就补上了“如何修改字段类型”这个运维需求。</think> 以下是SQL Server中时间查询的格式及详细用法说明,包含常用场景示例: --- ### 一、SQL Server日期时间类型 | 类型 | 精度 | 格式示例 | 范围 | |---------------|-----------|----------------------|--------------------------| | `DATE` | 天 | `2023-07-15` | 0001-01-01 到 9999-12-31 | | `TIME` | 100纳秒 | `14:30:45.1234567` | 00:00:00.0000000 到 23:59:59.9999999 | | `DATETIME` | 3.33毫秒 | `2023-07-15 14:30:45.123` | 1753-01-01 到 9999-12-31 | | `DATETIME2` | 100纳秒 | `2023-07-15 14:30:45.1234567` | 0001-01-01 到 9999-12-31 | | `SMALLDATETIME` | 1分钟 | `2023-07-15 14:30:00` | 1900-01-01 到 2079-06-06 | --- ### 二、基础查询格式及示例 #### 1. 精确时间查询 ```sql -- 查询特定日期 SELECT * FROM Orders WHERE OrderDate = '2023-07-15'; -- 查询日期时间 (需包含时间部分) SELECT * FROM Logs WHERE CreateTime = '2023-07-15 14:30:45.123'; ``` #### 2. 范围查询(重点!) ```sql -- 查询今天所有记录 (避免凌晨0点遗漏) SELECT * FROM Events WHERE EventTime >= CAST(GETDATE() AS DATE) AND EventTime < DATEADD(DAY, 1, CAST(GETDATE() AS DATE)); ``` #### 3. 日期部分比较 ```sql -- 查询7月所有订单 SELECT * FROM Orders WHERE MONTH(OrderDate) = 7 AND YEAR(OrderDate) = 2023; ``` --- ### 三、高级用法示例 #### 1. 时间段查询(精确到毫秒) ```sql -- 查询上午9点到10点间的记录 SELECT * FROM SensorData WHERE LogTime BETWEEN '2023-07-15 09:00:00.000' AND '2023-07-15 10:00:00.000'; ``` #### 2. 时间计算 ```sql -- 查询30分钟内的操作记录 SELECT * FROM UserActions WHERE ActionTime > DATEADD(MINUTE, -30, GETDATE()); ``` #### 3. 时区转换 ```sql -- UTC时间转本地时间 (SQL Server 2016+) SELECT OrderId, OrderDate AT TIME ZONE 'UTC' AT TIME ZONE 'China Standard Time' AS LocalTime FROM Orders; ``` --- ### 四、格式化函数 | 函数 | 示例 | 输出结果 | |---------------------|-------------------------|----------------------| | `CONVERT(VARCHAR, GETDATE(), 112)` | YYYYMMDD | `20230715` | | `CONVERT(VARCHAR, GETDATE(), 120)` | YYYY-MM-DD HH:MI:SS | `2023-07-15 14:30:45` | | `FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm')` | 自定义格式 | `2023-07-15 14:30` | --- ### 五、常见错误及避坑指南 1. **凌晨时间陷阱** ```sql -- 错误写法(会遗漏00:00:00的数据) WHERE EventDate BETWEEN '2023-07-15' AND '2023-07-16' -- 正确写法 WHERE EventDate >= '2023-07-15' AND EventDate < '2023-07-16' ``` 2. **忽略毫秒精度** 当使用 `DATETIME2` 类型时,需精确到毫秒: ```sql -- 可能遗漏毫秒级数据 WHERE CreateTime > '2023-07-15 14:30:45' -- 推荐写法 WHERE CreateTime > '2023-07-15 14:30:45.000' ``` 3. **隐式转换问题** 避免字符串与日期混用: ```sql -- 可能触发全表扫描(低效) WHERE CONVERT(VARCHAR(10), OrderDate, 112) = '20230715' -- 高效写法(用日期范围) WHERE OrderDate >= '2023-07-15' AND OrderDate < '2023-07-16' ``` --- ### 六、性能优化建议 1. 对日期字段使用索引时,避免在`WHERE`子句中使用函数计算 2. 针对高频查询的时间字段,考虑创建计算列并建立索引: ```sql ALTER TABLE Orders ADD OrderDateOnly AS CAST(OrderDate AS DATE); CREATE INDEX IX_OrderDate ON Orders(OrderDateOnly); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值