Timestamps | 时间戳

注:本文为 “Timestamps” 相关文章合辑

机翻未校。


Timestamps: What they are and why they matter?

时间戳是什么,为什么它们很重要?

Last update on January 08 2025 13:26:46 (UTC/GMT +8 hours)

Understanding Timestamps: A Beginner’s Guide
了解时间戳:初学者指南

Introduction

A timestamp is a precise record of time at which an event occurred, typically represented as a sequence of characters. Timestamps play a crucial role in computer systems, databases, and applications by ensuring data integrity and providing a reference for when specific events take place.
时间戳是事件发生时间的精确记录,通常表示为字符序列。时间戳在计算机系统、数据库和应用程序中发挥着至关重要的作用,可确保数据完整性并为特定事件的发生时间提供参考。

This guide explores the concept of timestamps, their applications, advantages, and examples in programming languages like Python and JavaScript.
本指南探讨了时间戳的概念、它们的应用、优势以及 Python 和 JavaScript 等编程语言中的示例。

What is a Timestamp?

A timestamp is a digital record of a specific date and time, often used to log events or changes in a system. They are expressed in various formats, such as:
时间戳是特定日期和时间的数字记录,通常用于记录系统中的事件或更改。它们以各种格式表示,例如:

  • Human-readable format: 2025-01-04 10:00:00
    人类可读格式:2025-01-04 10:00:00

  • UNIX timestamp: The number of seconds elapsed since January 1, 1970 (UTC).
    UNIX 时间戳:自 1970 年 1 月 1 日 (UTC) 以来经过的秒数。

Why use Timestamps?

为什么使用 Timestamps?

  • 1. Data Tracking

    Monitor changes or events in systems and applications.
    监视系统和应用程序中的更改或事件。

  • 2. Synchronization

    Coordinate actions across distributed systems.
    跨分布式系统协调作。

  • 3. Audit Trails

    Provide accountability and history for operations.
    为运营提供问责制和历史记录。

  • 4. Time-Based Operations

    Schedule tasks or trigger events based on specific timestamps.
    根据特定时间戳安排任务或触发事件。

Common Timestamp Formats

  • 1. UNIX Timestamp

    Represents time as the number of seconds since 1970-01-01 00:00:00 UTC.
    Example: 1707043200 (UNIX timestamp for 2025-01-04 00:00:00).
    将时间表示为自 1970-01-01 00:00:00 UTC 以来的秒数。 示例:1707043200(2025-01-04 00:00:00 的 UNIX 时间戳)。

  • 2. ISO 8601

    International standard format for representing date and time.
    表示日期和时间的国际标准格式。

    Example: 2025-01-04T10:00:00Z.
    示例:2025-01-04T10:00:00Z。

  • 3. Epoch Milliseconds

    Similar to UNIX timestamp but includes milliseconds.
    Example: 1707043200000.
    类似于 UNIX 时间戳,但包括毫秒。 示例:1707043200000。

Examples of Timestamps in Programming
编程中的时间戳示例

Python Example
Python 示例

Code:

import time
from datetime import datetime

# Get the current UNIX timestamp
current_timestamp = int(time.time())
print("UNIX Timestamp:", current_timestamp)

# Convert UNIX timestamp to human-readable format
readable_time = datetime.fromtimestamp(current_timestamp)
print("Human-readable Time:", readable_time)

# Convert human-readable time to ISO 8601
iso_time = readable_time.isoformat()
print("ISO 8601 Format:", iso_time)

Output:
输出:

UNIX Timestamp: 1736132972
Human-readable Time: 2021-01-06 08:39:32
ISO 8601 Format: 2021-01-06T08:39:32

JavaScript Example
JavaScript 示例

Code:

// Get the current UNIX timestamp
const unixTimestamp = Math.floor(Date.now() / 1000);
console.log("UNIX Timestamp:", unixTimestamp);

// Convert UNIX timestamp to human-readable format
const readableTime = new Date(unixTimestamp * 1000);
console.log("Human-readable Time:", readableTime.toISOString());

// Convert current date to ISO 8601 format
const isoTime = new Date().toISOString();
console.log("ISO 8601 Format:", isoTime);

Output: 输出:

"UNIX Timestamp:"
1736133073
"Human-readable Time:"
"2021-01-06T03:11:13.000Z"
"ISO 8601 Format:"
"2021-01-06T03:11:13.625Z"

Advantages of using Timestamps

使用 Timestamp 的优点

  • 1. Accuracy 准确性

    Precisely records when events occur.
    精确记录事件发生的时间。

  • 2. Standardization 标准化

    Universal formats like ISO 8601 ensure consistency.
    ISO 8601 等通用格式可确保一致性。

  • 3. Automation 自动化

    Enables automated tracking and synchronization.
    启用自动跟踪和同步。

  • 4. Versatility 多功能性

    Used across various fields, including databases, web development, and log management.
    用于各个领域,包括数据库、Web 开发和日志管理。

Where are Timestamps used?

时间戳用在什么地方?

  • 1. Databases

    Track changes or log insertions and updates. Example: SQL CURRENT_TIMESTAMP.
    跟踪更改或记录插入和更新。示例:SQL CURRENT_TIMESTAMP。

  • 2. Web Development

    Synchronize client-server communication. Example: JSON APIs.
    同步客户端-服务器通信。示例:JSON API。

  • 3. File Systems

    Record file creation, modification, and access times.
    记录文件创建、修改和访问时间。

  • 4. Applications

    Schedule reminders, notifications, or background jobs.
    计划提醒、通知或后台作业。

Challenges with Timestamps

时间戳的挑战

  • 1. Time Zone Handling 时区处理

    Convert timestamps accurately between different time zones.
    在不同时区之间准确转换时间戳。

  • 2. Precision Issues 精度问题

    Milliseconds and microseconds may be necessary for some applications.
    对于某些应用程序,可能需要毫秒和微秒。

  • 3. Synchronization 同步

    Ensure timestamps align across distributed systems.
    确保时间戳在分布式系统之间保持一致。

Summary

总结

Timestamps are fundamental in modern computing, offering a reliable way to track, log, and synchronize events. Understanding their formats, applications, and handling in programming languages equips developers and users to implement efficient and accurate time-based operations.
时间戳是现代计算的基础,它提供了一种可靠的方法来跟踪、记录和同步事件。了解它们在编程语言中的格式、应用程序和处理使开发人员和用户能够实现高效、准确的基于时间的作。


ISO 8601

国际标准 ISO 8601,是国际标准化组织的日期和时间的表示方法,全称为《数据元和交换格式 信息交换 日期和时间表示法》。目前是 2004 年 12 月 1 日发行的第三版 “ISO8601:2004” 以替代 1998 年的第一版 “ISO8601:1998” 与 2000 年的第二版 “ISO8601:2000”。

基本原则

  • 时间日期按照年月日时分秒的顺序排列,大时间单位在小时间单位之前。除了公元前的时刻外,用本标准表示的两个时刻中较早者在字典序上先于较晚者。这个特性有利于按时间排序。
  • 每个时间单位的位数固定,不足时于左补 0。
  • 本标准提供两种方法来表示时间:其一为只有数字的基础格式;其二为添加分隔符的扩展格式,从而更易读。标准原文建议 “应避免在纯文本中使用基础格式”。扩展格式使用连字符 “-” 来分隔日期,使用冒号 “:” 来分隔时间。比如 2009 年 1 月 6 日在扩展格式中可以写成 “2009-01-06”,在基本格式中可以简单地写成 “20090106” 而不会产生歧义。
  • 精度不足时,可以从右侧开始忽略日期或时间的某个单位。比如 2004 年 5 月可以表示为 “2004-05”(第五个月)。这种格式永远不会表示 2004 年未指定月份的第 5 天,也不会表示从 2004 年至 2005 年。
  • 实际运用中需要更高的精度时,可以在秒数后添加十进制小数。

日期表示法

ISO 8601 使用公历。ISO 8601:2004 规定了一个参考日期,即 1875 年 5 月 20 日,当天《米制公约》在巴黎签署;ISO 8601-1:2019 删除了这个明确的参考日期。不过公历自 1582 年 10 月 15 日公布后,到米制公约签署前的日期,也一直适用此标准。

至于公布公历前的日期,若通信双方达成一致,也可以用前推公历表示。标准要求所有日期必须是连续的,因此需要向前推导这些日子在格里历中对应的日期,而使用儒略历将违反标准。

年份

为了规避千年虫问题,标准要求至少使用四位数来表示年份,形如 “YYYY”。这样可以表示 0000 至 9999 的年份,其中 0000 意为公元前 1 年,如同天文纪年。不过这并不完全适用于 1583 年之前的年份。标准规定 “0000 至 1582 的年份仅应在双方有共识时用于通信”。

若要表示前 1 年之前或 9999 年之后的年份,标准也允许有共识的双方扩展表达方式。双方应事先规定增加的位数,并且年份前必须有正号 “+” 或负号 “-” 而不使用 “AD/BC” 或 “CE/BCE” 表示之。依据标准,若年份带符号,则前 1 年为 “+0000”,前 2 年为 “-0001”,依此类推。

月份和日期

月份和日各使用两位数字表示。月份在 01 到 12 之间,日期在 01 到 31 之间。表示日期的基本格式为 “YYYYMMDD”,扩展格式为 “YYYY-MM-DD”。例如,1919 年 8 月 10 日可以表示为 “19190810” 或 “1919-08-10”。

标准也允许更低的精度。例如 “1919-08” 表示 1919 年 8 月(不可以表示为 “191908” 以防止有人理解为 2019 年 19 月 8 日),“1919” 表示 1919 年,“191” 表示 1910 年代,“19” 表示二十世纪。表示二十一世纪的某年时,ISO 8601:2000 允许省去年份的前两位,形如 “YYMMDD”,相当于 “20YY-MM-DD”,但是 ISO 8601:2004 禁止了这种表示方式。

顺序日期表示法

完全表示:可以将一年内的天的序数用 3 位数字表示,平年 365 天,闰年 366 天。如 2004 年 5 月 3 日可以表示为 2004-1242004124

星期日历表示法

使用年份和星期表示某一日期的格式形如 YYYYWwwD 或 YYYY-Www-D,YYYY 表示年份,其值与年月日格式中的年份略有差别;Www 表示该日期所属星期是今年的第几个星期,范围在 W01 到 W53 之间;D 表示该日是本星期的第几天,范围在 1 到 7 之间,每个星期以周一作为第一天。例如 1926 年 8 月 17 日可写成 1926-W33-2 或 1926W332。

每年的第一个星期可以用如下方法决定:

  1. 本年度第一个星期四所在的星期;
  2. 1 月 4 日所在的星期;
  3. 本年度第一个至少有 4 天在同一星期内的星期;
  4. 星期一在去年 12 月 29 日至今年 1 月 4 日以内的星期。

推理可得,如果 1 月 1 日是星期一、星期二、星期三或者星期四,它所在星期就是本年第一个星期;如果 1 月 1 日是星期五、星期六或星期日,则它所在星期就是上一年第 52 或者 53 个日历星期;12 月 28 日总是在一年最后一个星期。

日历星期表示法

可以用 2 位数表示本年内第几个日历星期,但日历星期前要加上一个大写字母 W。 其他规定同星期日历表示法。

例如,如 2004 年第 19 个星期可写成:2004-W192004W19

日期时间表示法

只使用数字为基本格式。使用冒号 “:” 间隔开小时、分、秒的为扩展格式。小时、分和秒都用 2 位数表示。

对于当地时间 15 时 27 分 46 秒,

  • 完全表示:152746 或 15:27:46
  • 缺省小时的特定分和秒:-2746 或 - 27:46
  • 降低精度仅有小时和分:1528 或 15:28
  • 缺省小时的特定分:-28
  • 缺省日的特定小时:15
  • 带有小数的当地时间的完全表示:152735.5 或 15:27:35.5
  • 缺省小时的分,带有小数的秒:-2735.5 或 - 27:35.5
  • 午夜,一日的开始:完全表示为 000000 或 00:00:00;仅有小时和分表示为 0000 或 00:00
  • 午夜,一日的终止:完全表示为 240000 或 24:00:00;仅有小时和分表示为 2400 或 24:00
  • 如果时间在零时区,并恰好与协调世界时相同,那么(不加空格地)在时间最后加一个大写字母 Z。Z 是相对协调世界时时间 0 偏移的代号。如下午 2 点 30 分 5 秒表示为 14:30:05Z 或 **143005Z;只表示 ** 小时和分,为 1430Z 或 14:30Z;只表示小时,则为 14Z 或 14Z。
  • 其他时区用实际时间加时差表示,当时的 UTC+8 时间表示为 22:30:05+08:00223005+0800,也可以简化成 223005+08

日期和时间的组合表示法

合并表示时,要在时间前面加一大写字母 T,如要表示东八区时间 2004 年 5 月 3 日下午 5 点 30 分 8 秒,可以写成 2004-05-03T17:30:08+08:0020040503T173008+08

时间段表示法

如果要表示某一作为一段时间间隔,前面加一大写字母 P,但时间段后都要加上相应的代表时间的大写字母。如在一年三个月五天六小时七分三十秒内,可以写成 P1Y3M5DT6H7M30S

时间间隔表示法

从一个时间开始到另一个时间结束,或者从一个时间开始持续一个时间间隔,要在前后两个时间(或时间间隔)之间放置斜线符 “/”。格式为以下中的一种:

< 起始时间 >/< 结束时间 >
< 起始时间 >/< 时长 >
< 时长 >/< 结束时间 >
< 时长 >

例如 19850412/19860101,19850412/P6M。

循环时间表示法

前面加上一大写字母 R,格式为:

R【循环次数】【/ 开始时间】/ 时间间隔【/ 结束时间】

如要从 2004 年 5 月 6 日北京时间下午 1 点起时间间隔半年零 5 天 3 小时循环,且循环 3 次,可以表示为 R3/20040506T130000+08/P0Y6M5DT3H0M0S

如以 1 年 2 个月为循环间隔,无限次循环,最后循环终止于 2025 年 1 月 1 日,可表示为 R/P1Y2M/20250101

对应的各地标准

  • 中华人民共和国国家标准 GB/T 7408-2005《数据元和交换格式 信息交换 日期和时间表示法》与 ISO 8601:2000 等效采用。

参考文献

  1. ^ last in ISO8601:2000, in use by RFC 6350 - vCard Format Specification. IETF. August 2011 [2016-06-29]. Truncated representation, as specified in [ISO.8601.2000], Sections 5.2.1.3 d), e), and f), is permitted.

什么是 Timestamp—— 时间戳?

Sun sky 发布 2020-05-31 18:30:07

在查看大数据挑战赛的数据时,发现其中一项为 “Timestamp”。因不了解其含义,遂通过百度查询并记录相关内容。

百科定义

时间戳指从格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒)起至当前时刻的总秒数。

时间戳是运用数字签名技术产生的数据,其签名对象涵盖原始文件信息、签名参数、签名时间等内容。时间戳系统用于生成和管理时间戳,对签名对象进行数字签名以产生时间戳,借此证明原始文件在签名时间之前已然存在。

可信时间戳是由联合信任时间戳服务中心签发的电子凭证,用于证明自申请可信时间戳后,电子数据文件内容保持完整、未被更改。可信时间戳接入核准书的颁发,标志着可信时间戳在档案领域的规范化应用正式开启,其在电子档案及档案数字化副本内容防篡改方面发挥作用,保障档案具备法律凭证效力。依据《电子签名法》中有关数据电文原件形式的要求,申请了可信时间戳认证的电子文件、电子档案或纸质档案的数字化副本等,可视为法规规定的原件形式。

通俗来讲,时间戳是一份能够表明某份数据在特定时间点已存在的完整且可验证的数据。其主要目的是为用户提供电子证据,用以证明用户某些数据的产生时间。

个人理解

时间戳是一种时间记录方式,对数据产生的时间进行唯一认证,且该认证具有不可更改性。


timestamp(时间戳)详解

Gu 发布 2010-08-04 17:38

每个数据库均设有一个计数器,用于记录数据行的插入、更新操作。若在表中添加 timestamp 列,该列将记录每个数据行的计数器值。假设数据库当前计数器值为 20(实际中并非数字类型,此处为便于解释采用数字类型表示),那么在表 A 中插入一条记录后,插入行的 timestamp 值为 21;接着更新表 B 的一条记录后,更新行的 timestamp 值为 22;随后再更新刚才插入的行,此时其 timestamp 值为 23。由此可见,每个行都拥有一个 timestamp 值,且该值在数据库的所有表中具有唯一性。当更新行时,被更新行的 timestamp 值会加 1。需注意,删除操作不会影响计数器。

timestamp 的作用

timestamp 旨在避免更新冲突,此外,它还具有其他作用,例如在 SQL Server 全文索引时用于增量填充。

timestamp 的应用

只需在表中添加一个 timestamp 类型的列,该列会自动记录当前计数器的值。一个表只能存在一个 timestamp 列,且不能将其作为主键。不可为空的 timestamp 列在语义上等同于 binary(8) 列;可为空的 timestamp 列在语义上等同于 varbinary(8) 列。

timestamp 是否会重复

在使用 select into 语句时,timestamp 可能会出现重复。

如何查看数据库中当前的 timestamp

在查询分析器中,可使用 “print @@DBTS” 语句查看当前数据库的 timestamp 值。

增、改没有 timestamp 列的表数据时,@@DBTS 是否会改变

不会改变。

利用 timestamp 避免更新冲突

在 SQL Server 中,可利用 timestamp 数据类型避免更新冲突。

例如,在一个内容管理系统中,A 和 B 同时编辑某一篇文章,且双方均不知晓对方的操作。当双方保存后,都认为已成功保存,但实际上数据库仅保存了最后提交的记录,先提交的记录被覆盖,导致数据库中的数据与操作者预期不符。

为避免此类更新冲突,一种方法是采用模拟锁机制,即一人编辑时另一人不允许编辑,但该方法较为繁琐。鉴于此类更新冲突并非频繁发生,投入过多精力在此处并不值得。而使用 timestamp 则可轻松实现避免更新冲突。具体步骤如下:

  1. 在表中增加一个名为 tmstmp 的字段,数据类型为 timestamp,可参考 SQL Server 中 timestamp(时间戳)的相关设置。
  2. 编辑文章时,增加一个隐藏域:<input type="hidden"name="timestamp"value="<%=rs("tmstmp")%>">(显示 timestamp 值的方法:select(字段名 + 0) as 别名)。
  3. 更新文章时:
sql = "update... where id=" & id & "and tmstmp=" & tmstmp
conn.Execute sql, effectLines
if effectLines <= 0 then
    ' 更新失败,可能是原记录不存在,或者更新冲突
end if

SQL Server 中 timestamp(时间戳)

例如,字段的标识列属性(数据类型为数值型)在插入新行时会自动添加;而字段的数据类型为时间戳类型时,每行更新时数据库会自动更新该行此字段的值。

我们知道数字类型有 “标识” 属性,设置好 “标识种子”“标识递增量” 后,每增加一条记录,该字段的值会在最近的一个标识值基础上自动增加,借此可判断记录的添加先后顺序,但无法知晓哪些记录被修改过。而 timestamp 类型的字段,在增加记录和修改记录时,都会在最近的一个时间戳基础上自动增加,从而能够判断哪些记录被修改过。

如何显示 timestamp 的值

有反馈,使用 “response.Write(rs(“[timestamp]”))” 输出结果为空白,但在查询分析器中能看到一串数字。此时,在编写 SQL 语句时,可采用 “select(字段名 + 0) as 别名” 的方式,输出时即可正常显示。(如:0x000000000000FACC)

如何显示当前数据库的时间戳

在查询分析器中,使用 “print @@DBTS” 语句可显示当前数据库的时间戳。


时间戳 timestamp

三五月儿发布 2013-12-02 22:19:26

1. 时间戳

在数据库中,时间戳是自动生成的唯一二进制数据,通常作为给数据表的行添加版本戳的机制。其具有以下特点:

  • timestamp 与时间和日期并无关联。
  • timestamp 的存储大小为 8 字节。
  • 一个数据表仅能有一个 timestamp 列。
  • 每次修改或插入包含 timestamp 列的行时,会在 timestamp 列中插入增量数据库时间戳值。
  • timestamp 列不适合作为键使用,因为任何更新操作都会改变 timestamp 的值。

2. 时间戳的作用及应用

防止丢失更新

多用户同时修改一行数据时,最后提交修改的数据会覆盖前面提交的数据,导致前面的更新丢失,而时间戳可避免此类情况发生。

应用于数据增量更新

若要将一个表中更新的数据复制到另外一个表,可依据时间戳确认哪些数据是更新过的数据。

3. 实例

新建含有时间戳列的表 tb_Class

img

插入若干条数据,并执行 SQL 查询

select * from tb_Class;

img

执行以下 SQL 查询

select ts from tb_Class where classid=1
update tb_Class set teacher='ly' where classid=1
select ts from tb_Class where classid=1

img

从结果可知,更新行数据前后的时间戳的值发生了改变。

防止更新丢失的实例(源自网络)

declare table tmp(a varchar(10),b rowsversion)
insert into tmp(a) values('abc')

事务 A

declare @rv rowversion
select @rv=b from tmp where a='abc'
waitfor delay '00:00:05'
update tmp set a='xyz' where b=@rv

事务 B

update tmp set a='aaa' where b=@rv

事务 A 执行完毕后会发现并未将 ‘aaa’ 抹去,从而防止了丢失更新的现象。

补充

不建议使用 timestamp 语法,后续版本的 Microsoft SQL Server 将删除该功能。在新的开发工作中应避免使用,并着手修改当前仍在使用该功能的应用程序。推荐使用 rowversion。(微软 MSDN)


TIMESTAMP(时间戳)

衣乌安 于 2018-09-09 16:57:44 发布

一、TIMESTAMP 的变体

TIMESTAMP 时间戳在创建的时候可以有多种不同的特性,如:
1.在创建新记录和修改现有记录的时候都对这个数据列刷新

TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

2.在创建新记录的时候把这个字段设置为当前时间,但以后修改时,不再刷新它

TIMESTAMP DEFAULT CURRENT_TIMESTAMP

3.在创建新记录的时候把这个字段设置为 0,以后修改时刷新它

TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

4.在创建新记录的时候把这个字段设置为给定值,以后修改时刷新它

TIMESTAMP DEFAULT 'yyyy - mm - dd hh:mm:ss' ON UPDATE CURRENT_TIMESTAMP

MySQL 目前不支持列的 Default 为函数的形式,如要达到某列的默认值为当前更新日期与时间的功能,可以使用 TIMESTAMP 列类型。下面就详细说明 TIMESTAMP 列类型。

二、TIMESTAMP 列类型

TIMESTAMP 值可以从 1970 年的某时开始一直到 2037 年,精度为一秒,其值作为数字显示。TIMESTAMP 值显示尺寸的格式如下表所示:

列类型显示格式
TIMESTAMP(14)YYYYMMDDHHMMSS
TIMESTAMP(12)YYMMDDHHMMSS
TIMESTAMP(10)YYMMDDHHMM
TIMESTAMP(8)YYYYMMDD
TIMESTAMP(6)YYMMDD
TIMESTAMP(4)YYMM
TIMESTAMP(2)YY

“完整” TIMESTAMP 格式是 14 位,但 TIMESTAMP 列也可以用更短的显示尺寸,最常见的显示尺寸是 6、8、12 和 14。你可以在创建表时指定一个任意的显示尺寸,但是定义列长为 0 或比 14 大均会被强制定义为列长 14。列长在从 1~13 范围的奇数值尺寸均被强制为下一个更大的偶数。

例如:

定义字段长度强制字段长度
TIMESTAMP(0) ->TIMESTAMP(14)
TIMESTAMP(15) ->TIMESTAMP(14)
TIMESTAMP(1) ->TIMESTAMP(2)
TIMESTAMP(5) ->TIMESTAMP(6)

所有的 TIMESTAMP 列都有同样的存储大小,使用被指定的时期时间值的完整精度(14 位)存储合法的值,不考虑显示尺寸。不合法的日期,将会被强制为 0 存储。

这有几个含意:

  1. 虽然建表时定义了列 TIMESTAMP(8),但在进行数据插入与更新时,TIMESTAMP 列实际上保存了 14 位的数据(包括年月日时分秒),只不过在查询时 MySQL 返回的是 8 位的年月日数据。如果使用 ALTER TABLE 拓宽一个狭窄的 TIMESTAMP 列,以前被 “隐蔽” 的信息将被显示。
  2. 同样,缩小一个 TIMESTAMP 列不会导致信息丢失,只是感觉上值在显示时,较少的信息被显示出来。
  3. 尽管 TIMESTAMP 值被存储为完整精度,直接操作存储值的唯一函数是 UNIX_TIMESTAMP();由于 MySQL 返回 TIMESTAMP 列的列值是经过格式化后的检索的值,这意味着可能不能使用某些函数来操作 TIMESTAMP 列(例如 HOUR() 或 SECOND()),除非 TIMESTAMP 值的相关部分被包含在格式化的值中。例如,一个 TIMESTAMP 列只有被定义为 TIMESTAMP(10) 以上时,TIMESTAMP 列的 HH 部分才会被显示,因此在更短的 TIMESTAMP 值上使用 HOUR() 会产生一个不可预知的结果。
  4. 不合法 TIMESTAMP 值被变换到适当类型的 “零” 值(00000000000000)。(DATETIME, DATE 亦然)

例如可以使用下列语句来验证:

CREATE TABLE test(
    'id' INT(3) UNSIGNED AUTO_INCREMENT,
    'date1' TIMESTAMP(8),
    PRIMARY KEY('id')
);
INSERT INTO test SET id = 1;
SELECT * FROM test;
iddate1
120021114
ALTER TABLE test CHANGE 'date1' 'date1' TIMESTAMP(14);
SELECT * FROM test;
iddate1
120021114093723

可以使用 TIMESTAMP 列类型自动地用当前的日期和时间标记 INSERT 或 UPDATE 的操作。如果你有多个 TIMESTAMP 列,只有第一个自动更新。自动更新第一个 TIMESTAMP 列在下列任何条件下发生:

  1. 列值没有明确地在一个 INSERT 或 LOAD DATA INFILE 语句中指定。
  2. 列值没有明确地在一个 UPDATE 语句中指定且另外一些的列改变值。(注意一个 UPDATE 设置一个列为它已经有的值,这将不引起 TIMESTAMP 列被更新,因为如果设置一个列为它当前的值,MySQL 为了效率而忽略更改。)
  3. 明确地设定 TIMESTAMP 列为 NULL。
  4. 除第一个以外的 TIMESTAMP 列也可以设置到当前的日期和时间,只要将列设为 NULL,或 NOW()。
CREATE TABLE test( 
    'id' INT(3) UNSIGNED AUTO_INCREMENT,
    'date1' TIMESTAMP(14),
    'date2' TIMESTAMP(14),
    PRIMARY KEY('id')
);
INSERT INTO test(id, date1, date2) VALUES(1, NULL, NULL);
INSERT INTO test SET id = 2;
iddate1date2
12002111409372320021114093723
22002111409372400000000000000

第一条指令因设 date1、date2 为 NULL,所以 date1、date2 值均为当前时间。第二条指令因没有设 date1、date2 列值,第一个 TIMESTAMP 列 date1 更新为当前时间,而第二个 TIMESTAMP 列 date2 因日期不合法而变为 “00000000000000”。

UPDATE test SET id = 3 WHERE id = 1;
iddate1date2
32002111409400920021114093723
22002111409372400000000000000

这条指令没有明确地设定 date2 的列值,所以第一个 TIMESTAMP 列 date1 将被更新为当前时间。

UPDATE test SET id = 1, date1 = date1, date2 = NOW() WHERE id = 3; 
iddate1date2
12002111409400920021114094320
22002111409372400000000000000

这条指令因设定 date1 = date1,所以在更新数据时 date1 列值并不会发生改变,而因设定 date2 = NOW(),所以在更新数据时 date2 列值会被更新为当前时间。此指令等效为:

UPDATE test SET id = 1, date1 = date1, date2 = NULL WHERE id = 3;

因 MySQL 返回的 TIMESTAMP 列为数字显示形式,可以用 DATE_FROMAT() 函数来格式化 TIMESTAMP 列,如下所示:

SELECT id, DATE_FORMAT(date1, '% Y-% m-% d % H:% i:% s') As date1,
       DATE_FORMAT(date2, '% Y-% m-% d % H:% i:% s') As date2 FROM test;
iddate1date2
12002 - 11 - 14 09:40:092002 - 11 - 14 09:43:20
22002 - 11 - 14 09:37:240000 - 00 - 00 00:00:00
SELECT id, DATE_FORMAT(date1, '% Y-% m-% d') As date1,
       DATE_FORMAT(date2, '% Y-% m-% d') As date2 FROM test;
iddate1date2
12002 - 11 - 142002 - 11 - 14
22002 - 11 - 140000 - 00 - 00

在某种程度上,可以把一种日期类型的值赋给一个不同的日期类型的对象。然而,尤其需要注意的是:值有可能发生一些改变或信息的损失:

  1. 如果将一个 DATE 值赋给一个 DATETIME 或 TIMESTAMP 对象,结果值的时间部分被设置为 ‘00:00:00’,因为 DATE 值中不包含有时间信息。

  2. 如果将一个 DATETIME 或 TIMESTAMP 值赋给一个 DATE 对象,结果值的时间部分被删除,因为 DATE 类型不存储时间信息。

  3. 尽管 DATETIME, DATE 和 TIMESTAMP 值全都可以用同样的格式集来指定,但所有类型不都有同样的值范围。例如,

    TIMESTAMP 值不能比 1970 早,也不能比 2037 晚,这意味着,一个日期例如 ‘1968 - 01 - 01’,当作为一个 DATETIME 或 DATE 值时它是合法的,但它不是一个正确 TIMESTAMP 值!并且如果将这样的一个对象赋值给 TIMESTAMP 列,它将被变换为 0。

    • DATETIME 类型可以存储更广泛的日期和时间范围。它不存储时区信息,而是存储一个绝对的时间点。
    • DATE 类型只存储日期,没有时间部分。

三、当指定日期值时,当心某些缺陷

  1. 允许作为字符串指定值的宽松格式能被欺骗

    例如,因为 “:” 分隔符的使用,值 ‘10:11:12’ 可能看起来像时间值,但是如果在一个日期中使用,上下文将作为年份被解释成 ‘2010 - 11 - 12’。值 ‘10:45:15’ 将被变换到 ‘0000 - 00 - 00’,因为 ‘45’ 不是一个合法的月份。

  2. 以 2 位数字指定的年值是模糊的,因为世纪是未知的

    MySQL 使用下列规则解释 2 位年值:

    • 在 00 - 69 范围的年值被变换到 2000 - 2069
    • 在范围 70 - 99 的年值被变换到 1970 - 1999

via:

<think>好的,我现在需要在Java中将Timestamp对象转换为Unix时间戳或者毫秒级时间戳。让我先理清楚这两个概念的区别。Unix时间戳通常指的是从1970年1月1日00:00:00 UTC到现在的秒数,而毫秒级时间戳则是同样的时间跨度,但以毫秒为单位,也就是秒数乘以1000。 首先,我需要了解Java中的Timestamp类。Timestamp属于java.sql包,用于表示数据库中的时间戳,它继承自java.util.Date。所以,Timestamp对象内部应该保存的是从1970年1月1日以来的毫秒数。这样,要转换为毫秒级时间戳的话,可能只需要调用getTime()方法即可,这个方法在Date类中存在,应该也被Timestamp继承下来了。 那如果用户需要的是秒级的Unix时间戳,也就是将毫秒数除以1000后的结果。这时候,我需要先获取毫秒数,然后进行整除处理,转换成秒。需要注意的是,可能存在精度丢失的问题,但Unix时间戳通常不考虑毫秒部分,所以直接取整应该没问题。 接下来,我需要确认一下具体的代码实现。例如,用户有一个Timestamp对象,比如从数据库查询出来的,如何获取它的毫秒和秒级时间戳。可能的步骤如下: 1. 获取Timestamp对象的毫秒数:使用timestamp.getTime()方法,这会返回long类型的毫秒数。 2. 转换为秒级时间戳:将毫秒数除以1000,得到的结果就是秒级的Unix时间戳。这里需要注意的是,由于Java中整数除法会自动取整,所以直接除以1000即可。 举个例子,假设有一个Timestamp对象timestamp,那么代码可能是这样的: long milliseconds = timestamp.getTime(); long unixTimestamp = milliseconds / 1000; 或者更简洁地写成: long unixTimestamp = timestamp.getTime() / 1000; 这样就能得到秒级的Unix时间戳。如果是毫秒级的,直接使用getTime()的结果即可。 另外,用户提到的引用中,引用[2]中的例子展示了如何将long类型的时间戳转换为Date对象,这其实是一个反向操作。而用户的问题是将Timestamp转换为long,所以应该反过来操作。引用[3]中提到在shell脚本中处理昨天的日期转换为Unix时间戳,这虽然环境不同,但原理是一样的,即获取时间的毫秒数然后转换。 还需要注意时区的问题。Timestamp对象是否考虑了时区?根据Java文档,Timestamp是基于UTC的,所以在大多数情况下,直接转换可能没有问题。但如果在不同的时区环境中处理时间戳,可能需要额外的调整。不过,Unix时间戳本身就是基于UTC的,所以只要Timestamp正确表示了UTC时间,转换结果就是正确的。 此外,用户可能需要处理不同的来源,比如Timestamp是从数据库来的,或者通过其他方式生成。但不管来源如何,只要Timestamp对象正确,转换方法应该一致。 总结一下,步骤应该是: 1. 使用Timestamp对象的getTime()方法获取毫秒数。 2. 如果需要秒级时间戳,将毫秒数除以1000。 现在,我需要检查是否有其他需要注意的地方。例如,是否有可能出现负数时间戳(早于1970年的时间),但这种情况处理方式是一样的,只是数值为负。另外,确保返回的long类型足够大,不会溢出,不过在Java中long是64位的,应该不会有问题。 可能用户还会问如何处理当前时间的时间戳,这时候可以用System.currentTimeMillis()来获取当前的毫秒级时间戳,然后同样处理。不过用户的问题集中在Timestamp对象上,所以重点还是调用Timestamp的方法。 最后,编写代码示例来演示转换过程,确保语法正确,并且符合用户的需求。</think>在Java中,`java.sql.Timestamp`对象内部存储的是自协调世界时1970年1月1日00:00:00以来的毫秒数。转换步骤如下: ### 1. 转换为毫秒级时间戳 直接调用`getTime()`方法即可获得毫秒级时间戳: ```java Timestamp timestamp = new Timestamp(System.currentTimeMillis()); long milliseconds = timestamp.getTime(); // 毫秒级时间戳 ``` ### 2. 转换为秒级Unix时间戳 将毫秒级时间戳除以1000,取整数部分: ```java long unixTimestamp = timestamp.getTime() / 1000; // 秒级Unix时间戳 ``` ### 完整示例代码 ```java import java.sql.Timestamp; public class TimestampToUnix { public static void main(String[] args) { // 创建当前时间的Timestamp对象 Timestamp timestamp = new Timestamp(System.currentTimeMillis()); // 转换为毫秒级时间戳 long milliseconds = timestamp.getTime(); System.out.println("毫秒级时间戳: " + milliseconds); // 转换为秒级Unix时间戳 long unixTimestamp = milliseconds / 1000; System.out.println("秒级Unix时间戳: " + unixTimestamp); } } ``` ### 注意事项 - **时区问题**:`Timestamp`基于UTC时间,与Unix时间戳定义一致,无需额外时区转换[^3]。 - **精度丢失**:秒级时间戳会丢弃毫秒部分(如`1625000000123`毫秒转换为`1625000000`秒)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值