mysql 查询时间戳(TIMESTAMP)转成常用可读时间格式

本文介绍了MySQL中的两个常用时间函数FROM_UNIXTIME()和UNIX_TIMESTAMP()。详细解释了如何使用这两个函数进行Unix时间戳与日期时间之间的转换,并展示了各种格式化选项。

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

from_unixtime()是MySQL里的时间函数 
date为需要处理的参数(该参数是Unix 时间戳),可以是字段名,也可以直接是Unix 时间戳字符串 
后面的 '%Y%m%d' 主要是将返回值格式化 
例如: 

mysql>SELECT FROM_UNIXTIME( 1249488000, '%Y%m%d' )  
->20071120 
mysql>SELECT FROM_UNIXTIME( 1249488000, '%Y年%m月%d' )  
->2007年11月20 
UNIX_TIMESTAMP()是与之相对正好相反的时间函数 
 
UNIX_TIMESTAMP(), UNIX_TIMESTAMP(date) 

 

  若无参数调用,则返回一个 Unix timestamp ('1970-01-01 00:00:00' GMT 之后的秒数) 作为无符号整数。若用date 来调用 UNIX_TIMESTAMP(),它会将参数值以'1970-01-01 00:00:00' GMT后的秒数的形式返回。date 可以是一个 DATE 字符串、一个 DATETIME字符串、一个 TIMESTAMP或一个当地时间的YYMMDD 或YYYMMDD格式的数字。 
 
例如:  

mysql> SELECT UNIX_TIMESTAMP() ; (执行使得时间:2009-08-06 10:10:40->1249524739 
mysql> SELECT UNIX_TIMESTAMP('2009-08-06') ; 
->1249488000 
使用 FROM_UNIXTIME函数,具体如下:   
  
FROM_UNIXTIME(unix_timestamp,format)   
返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条目同样的修饰符。   
根据format字符串格式化date值。下列修饰符可以被用在format字符串中: %M 月名字(January……December)   
%W 星期名字(Sunday……Saturday)   
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。)   
%Y 年, 数字, 4%y 年, 数字, 2%a 缩写的星期名字(Sun……Sat)   
%d 月份中的天数, 数字(00……31)   
%e 月份中的天数, 数字(0……31)   
%m 月, 数字(01……12)   
%c 月, 数字(1……12)   
%b 缩写的月份名字(Jan……Dec)   
%j 一年中的天数(001……366)   
%H 小时(00……23)   
%k 小时(0……23)   
%h 小时(01……12)   
%I 小时(01……12)   
%l 小时(1……12)   
%i 分钟, 数字(00……59)   
%r 时间,12 小时(hh:mm:ss [AP]M)   
%T 时间,24 小时(hh:mm:ss)   
%S 秒(00……59)   
%s 秒(00……59)   
%p AM或PM   
%w 一个星期中的天数(0=Sunday ……6=Saturday )   
%U 星期(0……52), 这里星期天是星期的第一天   
%u 星期(0……52), 这里星期一是星期的第一天   
%% 一个文字“%”。

 

<think>我们有一个任务:将MySQL查询结果中的时间戳换为包含毫秒的日期格式。 在MySQL中,时间戳通常以整数形式存储(如UNIX时间戳)或以DATETIME、TIMESTAMP类型存储(可以包含小数秒部分表示毫秒)。 假设我们有一个TIMESTAMP(3)或DATETIME(3)类型的列,其中(3)表示毫秒精度(即小数点后3位)。 如果我们想要在查询结果中以特定格式显示日期时间(包括毫秒),我们可以使用DATE_FORMAT函数。但是,标准的DATE_FORMAT函数不支持毫秒的格式化。 然而,我们可以通过以下方式实现: 1. 将时间戳换为字符串,并提取到毫秒部分。 2. 使用`DATE_FORMAT`来格式化日期和时间部分,然后连接毫秒部分。 但是,请注意:MySQL中的时间戳如果包含小数秒,那么我们可以使用`%f`来获取微秒(6位),然后我们可以截取前3位作为毫秒。 示例: 假设我们有一个表`mytable`,其中有一个名为`timestamp_col`的列,类型为`TIMESTAMP(3)`(存储到毫秒)。 我们可以这样查询: ```sql SELECT CONCAT( DATE_FORMAT(timestamp_col, '%Y-%m-%d %H:%i:%s'), '.', LPAD(FLOOR(MICROSECOND(timestamp_col) / 1000), 3, '0') ) AS formatted_datetime FROM mytable; ``` 解释: - `DATE_FORMAT(timestamp_col, '%Y-%m-%d %H:%i:%s')`:将日期时间部分格式化为'YYYY-MM-DD HH:MM:SS'。 - `MICROSECOND(timestamp_col)`:返回时间戳的微秒部分(0到999999)。 - 将微秒除以1000并取整,得到毫秒(0到999)。 - 使用`LPAD(..., 3, '0')`将毫秒数字填充为3位(例如,5变成'005',12变成'012')。 - 最后用`CONCAT`将日期时间部分、小数点以及毫秒部分连接起来。 另一种方法:使用`SUBSTRING_INDEX`和`CAST`,但上面的方法更直接。 注意:如果原始时间戳的精度不是毫秒(比如是微秒),而我们只需要毫秒,那么上述除法取整是合适的。 如果我们的列是整数形式的UNIX时间戳(包含毫秒),那么我们需要先将其换为DATETIME,然后再格式化。 例如,假设我们有一个整数列`unix_timestamp_ms`,它存储的是毫秒级UNIX时间戳(从1970-01-01开始的毫秒数)。 我们可以这样换: ```sql SELECT CONCAT( DATE_FORMAT(FROM_UNIXTIME(unix_timestamp_ms / 1000), '%Y-%m-%d %H:%i:%s'), '.', LPAD(unix_timestamp_ms % 1000, 3, '0') ) AS formatted_datetime FROM mytable; ``` 解释: - `FROM_UNIXTIME`函数接受秒级UNIX时间戳,所以我们将毫秒级时间戳除以1000得到秒(浮点数),然后`FROM_UNIXTIME`可以处理浮点数并保留小数部分(微秒)。 - 但是,注意:`FROM_UNIXTIME`返回的是带有微秒的DATETIME(如果输入是浮点数),但我们需要毫秒。同时,我们还需要单独获取毫秒部分(即原时间戳除以1000后的余数,即毫秒部分)。 - 因此,我们使用`unix_timestamp_ms % 1000`得到毫秒部分(0到999),然后填充为3位。 - 注意:`FROM_UNIXTIME(unix_timestamp_ms / 1000)`会返回一个DATETIME值,我们将其格式化为字符串(不含毫秒),然后拼接上毫秒部分。 但是,这种方法可能会因为浮点数精度问题导致毫秒部分不准确?为了避免,我们可以使用整数运算: ```sql SELECT CONCAT( DATE_FORMAT(FROM_UNIXTIME(FLOOR(unix_timestamp_ms / 1000)), '%Y-%m-%d %H:%i:%s'), '.', LPAD(unix_timestamp_ms % 1000, 3, '0') ) AS formatted_datetime FROM mytable; ``` 这里我们使用`FLOOR`函数取整,确保传入`FROM_UNIXTIME`的是整数秒,然后毫秒部分由余数单独计算。 但是,这样处理会丢失小数秒(即毫秒)?因为`FROM_UNIXTIME`只接受整数秒时,返回的是整数秒对应的日期时间,然后我们再加上毫秒部分。注意:这样拼接后的时间字符串实际上比原时间多出了毫秒部分,而原时间戳的毫秒部分已经通过取余单独计算了,所以是准确的。 然而,这种方法有一个问题:我们拼接后的字符串实际上是一个字符串,而不是时间类型。而且,如果我们需要在应用中使用这个字符串,它是符合预期的。 总结: 根据我们的时间戳存储方式,选择合适的方法。 情况1:时间戳以DATETIME或TIMESTAMP类型存储(包含小数秒,如TIMESTAMP(3)) 使用第一种方法。 情况2:时间戳以整数形式存储(毫秒级UNIX时间戳) 使用第二种方法(整数运算)。 另外,如果我们使用的是MySQL 8.0,我们可以使用`CAST`函数将时间戳换为带有毫秒的字符串,然后进行格式化,但可能不如上述方法灵活。 示例:在MySQL 8.0中,我们可以直接: ```sql SELECT DATE_FORMAT(timestamp_col, '%Y-%m-%d %H:%i:%s.%f') AS formatted_datetime FROM mytable; ``` 但是,这会输出6位微秒,而我们只需要3位毫秒。所以我们可以截取前23个字符(因为日期时间格式为19个字符,加上3位毫秒和一个小数点,共23个字符): ```sql SELECT LEFT(DATE_FORMAT(timestamp_col, '%Y-%m-%d %H:%i:%s.%f'), 23) AS formatted_datetime FROM mytable; ``` 这种方法更简洁,但需要注意,如果微秒部分不足6位,它会自动用0填充,所以取前23位正好是毫秒(因为毫秒是3位,加上前面的19位日期时间格式和一个小数点,共23位)。 因此,如果我们使用的是MySQL 8.0,并且列是TIMESTAMP或DATETIME类型(带小数秒),那么这种方法最简单。 综上所述,根据MySQL版本和存储类型,我们有以下方法: 方法1(适用于任何MySQL版本,列是DATETIME或TIMESTAMP类型): ```sql SELECT CONCAT( DATE_FORMAT(timestamp_col, '%Y-%m-%d %H:%i:%s'), '.', LPAD(FLOOR(MICROSECOND(timestamp_col) / 1000), 3, '0') ) AS formatted_datetime FROM mytable; ``` 方法2(适用于整数存储的毫秒级UNIX时间戳): ```sql SELECT CONCAT( DATE_FORMAT(FROM_UNIXTIME(FLOOR(unix_timestamp_ms / 1000)), '%Y-%m-%d %H:%i:%s'), '.', LPAD(unix_timestamp_ms % 1000, 3, '0') ) AS formatted_datetime FROM mytable; ``` 方法3(MySQL 8.0+,列是DATETIME或TIMESTAMP类型): ```sql SELECT LEFT(DATE_FORMAT(timestamp_col, '%Y-%m-%d %H:%i:%s.%f'), 23) AS formatted_datetime FROM mytable; ``` 请根据实际情况选择合适的方法。 注意:在方法1中,我们使用`FLOOR(MICROSECOND(timestamp_col)/1000)`来得到毫秒,因为`MICROSECOND`返回的是微秒(0-999999),除以1000得到毫秒(可能为0-999.999),然后取整得到0-999的整数毫秒。如果原始数据是毫秒精度,那么微秒部分实际上是毫秒乘以1000,所以除以1000后取整正好是毫秒。例如,如果时间戳是'2023-01-01 12:00:00.123',那么微秒是123000,除以1000得123,取整后还是123。 但是,如果原始数据是微秒精度,而我们只需要毫秒,那么这种方法会丢弃额外的微秒(例如,123456微秒会变成123毫秒)。这符合要求,因为我们只需要毫秒。 因此,方法1是通用的。 现在,我们可以根据用户的具体情况推荐相应的方法。 由于用户的问题没有说明时间戳的存储类型,我们可以给出一个通用的方法,并解释不同情况下的处理。 另外,如果用户的时间戳列是字符串类型,那么需要先换为时间类型,然后再格式化,但这不在本问题范围内。 所以,我们假设用户的时间戳TIMESTAMP或DATETIME类型(含毫秒)或者是整数UNIX时间戳(毫秒)。 我们给出一个通用的回答,涵盖两种常见情况。</think>### MySQL查询结果中时间戳换为带毫秒的日期格式 在MySQL中,将时间戳换为包含毫秒的日期格式需要根据时间戳的存储类型选择不同方法: #### 方法1:从`DATETIME(3)`/`TIMESTAMP(3)`列提取毫秒 如果时间戳存储为带毫秒精度的`DATETIME(3)`或`TIMESTAMP(3)`类型: ```sql SELECT CONCAT( DATE_FORMAT(your_column, '%Y-%m-%d %H:%i:%s'), '.', LPAD(FLOOR(MICROSECOND(your_column)/1000), 3, '0') ) AS formatted_datetime FROM your_table; ``` **原理**: 1. `DATE_FORMAT()`处理日期和时间部分 2. `MICROSECOND()`提取微秒值(6位) 3. `FLOOR(MICROSECOND/1000)`获取毫秒(3位) 4. `LPAD(..., 3, '0')`确保毫秒保持3位数字 #### 方法2:从UNIX时间戳(毫秒级)换 如果存储的是毫秒级UNIX时间戳(整数): ```sql SELECT CONCAT( DATE_FORMAT(FROM_UNIXTIME(your_column / 1000), '%Y-%m-%d %H:%i:%s'), '.', LPAD(your_column % 1000, 3, '0') ) AS formatted_datetime FROM your_table; ``` **原理**: 1. `FROM_UNIXTIME(your_column/1000)`将毫秒秒级时间戳 2. `your_column % 1000`直接获取毫秒部分 3. 拼接时用`LPAD`补位 #### 方法3:MySQL 8.0+ 简化方案 ```sql SELECT DATE_FORMAT(your_column, '%Y-%m-%d %H:%i:%s.%f') AS full_format, LEFT(DATE_FORMAT(your_column, '%Y-%m-%d %H:%i:%s.%f'), 23) AS trimmed_ms FROM your_table; ``` **说明**: - `%f`输出6位微秒(如.123000) - `LEFT(..., 23)`截取前23字符保留3位毫秒 #### 验证示例 ```sql SELECT CONCAT( DATE_FORMAT(NOW(3), '%Y-%m-%d %H:%i:%s.'), LPAD(FLOOR(MICROSECOND(NOW(3))/1000), 3, '0') ) AS current_ms; ``` 输出示例:`2023-08-04 15:30:45.789` > **关键点**: > 1. 确保原始列支持毫秒精度(如`DATETIME(3)`) > 2. 整数UNIX时间戳需确认是否为毫秒级 > 3. 毫秒部分需用`LPAD`补零保证3位显示 > 4. 在金融等高精度场景需验证时间精度[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值