Java开发过程中,时间戳是非常常见的数据类型,广泛应用于日志记录、数据库存储、接口参数传递、缓存过期判断、订单创建时间记录等场景。相比传统的日期格式,时间戳具有统一、精确、易比较等特点,因此在后端开发中经常需要获取当前时间对应的时间戳。
Java提供了多种获取时间戳的方式,不同版本的JDK也提供了不同的时间处理API。从早期的System.currentTimeMillis(),到Java 8之后更加完善的java.time时间API,开发者可以根据实际需求选择合适的方法。
一、什么是时间戳
时间戳(Timestamp)通常指从某个固定时间点开始计算的时间总毫秒数或秒数。
在Java开发中,最常见的是Unix时间戳,也就是:
-
从1970年1月1日00:00:00 UTC开始计算
-
以毫秒(ms)或秒(s)作为单位
-
当前时间距离起始时间的数值
例如:
毫秒时间戳: 1720000000000 秒时间戳: 1720000000
两者区别主要在精度:
| 类型 | 单位 | 位数 | 使用场景 |
|---|---|---|---|
| 秒级时间戳 | 秒 | 10位左右 | 接口参数、业务时间 |
| 毫秒级时间戳 | 毫秒 | 13位左右 | Java系统日志、数据库记录 |
| 微秒级时间戳 | 微秒 | 16位左右 | 高精度交易系统 |
Java默认获取的时间戳通常是毫秒级。
二、使用System.currentTimeMillis()获取时间戳
System.currentTimeMillis()是Java中最常用的获取时间戳方式。
示例:
Javapublic class TimestampDemo { public static void main(String[] args) { long timestamp = System.currentTimeMillis(); System.out.println(timestamp); } }
输出:
1720000000000
该方法返回当前时间距离1970年1月1日00:00:00 UTC的毫秒数。
优点
-
使用简单
-
性能较高
-
兼容所有Java版本
-
适合大多数业务场景
常见应用
1. 记录程序执行耗时
Javalong start = System.currentTimeMillis(); // 执行业务代码 long end = System.currentTimeMillis(); System.out.println("耗时:" + (end - start) + "ms");
通过计算两个时间戳的差值,可以快速统计代码执行时间。
2. 生成唯一标识
部分业务会将时间戳加入ID:
JavaString orderId = "ORDER_" + System.currentTimeMillis(); System.out.println(orderId);
生成:
ORDER_1720000000000
不过需要注意,单纯依靠时间戳不能保证绝对唯一,高并发环境还需要结合随机数或序列号。
三、使用Instant获取时间戳(Java 8推荐方式)
Java 8引入了新的日期时间API,其中Instant专门用于表示时间线上的一个瞬间,非常适合处理时间戳。
示例:
Javaimport java.time.Instant; public class InstantTimestamp { public static void main(String[] args) { long timestamp = Instant.now().toEpochMilli(); System.out.println(timestamp); } }
输出:
1720000000000
其中:
JavaInstant.now()
表示当前时间。
通过:
JavatoEpochMilli()
转换为毫秒时间戳。
获取秒级时间戳
如果业务需要秒级时间戳,可以使用:
Javalong seconds = Instant.now().getEpochSecond(); System.out.println(seconds);
输出:
1720000000
相比System.currentTimeMillis(),Instant语义更加清晰,更符合现代Java开发规范。
四、使用LocalDateTime获取时间戳
LocalDateTime主要用于表示日期时间,例如:
2026-10-03 12:30:00
它本身不包含时区信息,因此不能直接转换时间戳。
需要结合时区:
Javaimport java.time.LocalDateTime; import java.time.ZoneId; public class LocalDateTimeTimestamp { public static void main(String[] args) { long timestamp = LocalDateTime.now() .atZone(ZoneId.systemDefault()) .toInstant() .toEpochMilli(); System.out.println(timestamp); } }
转换过程:
LocalDateTime | ↓ ZoneId添加时区 | ↓ Instant | ↓ 时间戳
指定固定时区获取时间戳
服务器部署环境不同,系统默认时区可能不同。
例如:
Javalong timestamp = LocalDateTime.now() .atZone(ZoneId.of("Asia/Shanghai")) .toInstant() .toEpochMilli();
这样可以避免不同服务器之间时间不一致的问题。
五、使用Date获取时间戳
在Java早期版本中,java.util.Date是常用时间类。
示例:
Javaimport java.util.Date; public class DateTimestamp { public static void main(String[] args) { Date date = new Date(); long timestamp = date.getTime(); System.out.println(timestamp); } }
Date.getTime()返回毫秒时间戳。
实际上:
Javanew Date().getTime()
与:
JavaSystem.currentTimeMillis()
结果基本一致。
区别在于:
-
System.currentTimeMillis()直接获取当前时间 -
Date先创建日期对象,再获取时间
因此单纯获取时间戳时,更推荐:
JavaSystem.currentTimeMillis()
六、使用Timestamp获取时间戳
Java提供了:
Javajava.sql.Timestamp
用于数据库时间处理。
示例:
Javaimport java.sql.Timestamp; public class SqlTimestampDemo { public static void main(String[] args) { Timestamp timestamp = new Timestamp(System.currentTimeMillis()); System.out.println(timestamp.getTime()); } }
输出:
1720000000000
该方式常用于JDBC数据库操作。
例如:
JavaPreparedStatement ps = connection.prepareStatement( "insert into user(create_time) values(?)" ); ps.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
七、时间戳转换为日期时间
除了获取时间戳,实际开发中也经常需要将时间戳转换成日期。
使用Date转换
Javalong timestamp = System.currentTimeMillis(); Date date = new Date(timestamp); System.out.println(date);
使用Java 8时间API转换
Javalong timestamp = System.currentTimeMillis(); LocalDateTime time = LocalDateTime.ofInstant( Instant.ofEpochMilli(timestamp), ZoneId.systemDefault() ); System.out.println(time);
输出:
2026-10-03T12:30:00
八、获取时间戳时的常见问题
1. 秒和毫秒混淆
这是最容易出现的问题。
例如:
Java:
JavaSystem.currentTimeMillis()
返回:
1720000000000
接口要求:
1720000000
此时需要:
Javalong seconds = System.currentTimeMillis() / 1000;
否则会导致时间解析错误。
2. 时区问题
时间戳本身表示的是一个绝对时间,不包含时区。
但是转换日期时需要指定时区:
JavaZoneId.of("Asia/Shanghai")
如果服务器部署在不同地区,建议明确设置时区。
3. 使用System.currentTimeMillis()计算高精度时间
需要注意:
JavaSystem.currentTimeMillis()
适合业务时间,不适合精确性能分析。
例如统计代码执行时间,更推荐:
JavaSystem.nanoTime()
示例:
Javalong start = System.nanoTime(); // 执行业务 long end = System.nanoTime(); System.out.println(end - start);
nanoTime()用于计算时间间隔,不代表真实时间戳。
九、不同获取时间戳方式对比
| 方法 | Java版本 | 精度 | 推荐程度 | 使用场景 |
|---|---|---|---|---|
| System.currentTimeMillis | 全版本 | 毫秒 | 高 | 普通业务 |
| Instant.now() | Java8+ | 毫秒/秒 | 高 | 新项目推荐 |
| LocalDateTime转换 | Java8+ | 毫秒 | 中 | 日期时间处理 |
| Date.getTime() | 全版本 | 毫秒 | 中 | 老项目兼容 |
| Timestamp.getTime() | 全版本 | 毫秒 | 中 | 数据库操作 |
十、实际开发中的推荐写法
如果项目使用Java 8及以上版本,建议优先使用Instant:
Javalong timestamp = Instant.now().toEpochMilli();
如果只是简单获取当前毫秒时间戳:
Javalong timestamp = System.currentTimeMillis();
如果涉及业务时间转换:
JavaLocalDateTime.now() .atZone(ZoneId.systemDefault()) .toInstant() .toEpochMilli();
如果涉及数据库:
Javanew Timestamp(System.currentTimeMillis());
根据不同场景选择合适的方法,可以提高代码可读性和维护性。
总结
Java获取时间戳的方法比较丰富,从传统的System.currentTimeMillis()、Date,到Java 8提供的Instant、LocalDateTime等新时间API,都可以满足不同开发需求。
在普通业务开发中,System.currentTimeMillis()依然是最简单高效的选择;对于新项目,推荐使用Java 8时间API中的Instant进行时间处理;涉及数据库交互时,可以结合Timestamp完成时间存储。
掌握不同时间戳获取方式以及它们的适用场景,可以有效避免时间单位错误、时区混乱等问题,提高Java应用程序的稳定性。