杰瑞科技汇

java timestamp 格式

时间戳 vs. 格式化

  1. 时间戳:通常指一个特定的、精确到毫秒甚至纳秒的瞬间,在 Java 中,它本质上是一个长整型数字,表示自 1970 年 1 月 1 日 00:00:00 UTC(称为“纪元”或 Epoch)以来经过的毫秒数。

    java timestamp 格式-图1
    (图片来源网络,侵删)
    • java.util.Datejava.sql.Timestamp 都代表了这样一个瞬间。
    • System.currentTimeMillis() 返回的就是这个长整型数字。
  2. 格式化:指将一个时间戳(瞬间)转换成人类可读的字符串(如 "2025-10-27 10:30:00"),或者将一个符合某种格式的字符串解析回一个时间戳对象的过程。


旧版 API (不推荐,但需了解)

在 Java 8 之前,主要使用 java.util.Datejava.text.SimpleDateFormat

a. java.util.Date

Date 对象本身不包含格式信息,它只是一个时间点,要格式化它,必须借助 SimpleDateFormat

示例:格式化 Date

java timestamp 格式-图2
(图片来源网络,侵删)
import java.util.Date;
import java.text.SimpleDateFormat;
public class LegacyDateFormat {
    public static void main(String[] args) {
        // 1. 获取当前时间的 Date 对象
        Date now = new Date();
        // 2. 创建 SimpleDateFormat 对象,并指定格式模式
        // yyyy: 年, MM: 月, dd: 日, HH: 24小时制, mm: 分, ss: 秒
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 3. 格式化 Date 对象为字符串
        String formattedDate = formatter.format(now);
        System.out.println("原始 Date 对象: " + now);
        System.out.println("格式化后的字符串: " + formattedDate);
        // 4. 解析字符串为 Date 对象
        try {
            String dateStr = "2025-12-31 23:59:59";
            Date parsedDate = formatter.parse(dateStr);
            System.out.println("解析后的 Date 对象: " + parsedDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

SimpleDateFormat 常用模式字符:

字符 含义 示例
y yyyy (2025), yy (23)
M MM (10), M (10)
d dd (27), d (27)
H 小时 (24小时制) HH (14)
h 小时 (12小时制) hh (02)
m mm (30)
s ss (05)
S 毫秒 SSS (123)
a 上午/下午标记 AMPM

缺点SimpleDateFormat非线程安全的,在多线程环境下共享同一个实例会导致数据错乱,必须为每个线程创建新的实例。


b. java.sql.Timestamp

这是 java.util.Date 的子类,专门用于与 JDBC 交互,可以精确到纳秒,它的格式化方式与 Date 完全相同。

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
public class SqlTimestampFormat {
    public static void main(String[] args) {
        // 获取当前时间的 Timestamp 对象
        Timestamp now = new Timestamp(System.currentTimeMillis());
        // 格式化
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        String formattedTs = formatter.format(now);
        System.out.println("原始 Timestamp: " + now);
        System.out.println("格式化后: " + formattedTs);
    }
}

现代化 API (Java 8+, 强烈推荐)

Java 8 引入了 java.time 包,它彻底解决了旧 API 的设计问题,提供了更强大、更安全、更易用的 API。

java timestamp 格式-图3
(图片来源网络,侵删)

a. 核心类

描述
Instant 代表一个时间线上的瞬间,与 java.util.Date 类似,精确到纳秒,可以看作是 UTC 时间。
LocalDateTime 不包含时区的日期和时间,如 "2025-10-27T10:30:00"。
ZonedDateTime 包含时区的日期和时间,如 "2025-10-27T10:30:00+08:00[Asia/Shanghai]"。
DateTimeFormatter 线程安全的日期、时间、时间戳的格式化器。

b. 使用 DateTimeFormatter 进行格式化

示例:格式化 LocalDateTime

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ModernDateFormat {
    public static void main(String[] args) {
        // 1. 获取当前日期时间 (无时区)
        LocalDateTime now = LocalDateTime.now();
        // 2. 创建 DateTimeFormatter (线程安全)
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        // 3. 格式化
        String formattedDateTime = now.format(formatter);
        System.out.println("格式化后的 LocalDateTime: " + formattedDateTime);
        // 4. 定义格式并解析
        String dateTimeStr = "2025-12-31 23:59:59";
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeStr, inputFormatter);
        System.out.println("解析后的 LocalDateTime: " + parsedDateTime);
    }
}

DateTimeFormatter 常用模式字符:SimpleDateFormat 大部分相同,但更丰富。

字符 含义
yyyy
MM
dd
HH 小时 (24小时制)
mm
ss
SSS 毫秒
nn 纳秒
XXX 时区偏移 (如 +08:00)
VV 时区ID (如 Asia/Shanghai)
z 时区名称 (如 CST)

Timestampjava.time 的转换

在 JDBC 编程中,数据库返回的 java.sql.Timestamp 需要转换为现代的 java.time 类型。

java.sql.Timestamp -> java.time.LocalDateTime

import java.sql.Timestamp;
import java.time.LocalDateTime;
public class TimestampToLocalDateTime {
    public static void main(String[] args) {
        // 假设这是从数据库获取的 Timestamp
        Timestamp sqlTs = new Timestamp(System.currentTimeMillis());
        // 转换为 LocalDateTime
        // Timestamp.toLocalDateTime() 是 Java 8+ 提供的便捷方法
        LocalDateTime ldt = sqlTs.toLocalDateTime();
        System.out.println("原始 Timestamp: " + sqlTs);
        System.out.println("转换后的 LocalDateTime: " + ldt);
        // 另一种方式 (更通用)
        // LocalDateTime ldt2 = LocalDateTime.ofInstant(sqlTs.toInstant(), ZoneId.systemDefault());
    }
}

java.time.LocalDateTime -> java.sql.Timestamp

import java.sql.Timestamp;
import java.time.LocalDateTime;
public class LocalDateTimeToTimestamp {
    public static void main(String[] args) {
        // 获取当前 LocalDateTime
        LocalDateTime ldt = LocalDateTime.now();
        // 转换为 Timestamp
        // Timestamp.valueOf() 是 Java 8+ 提供的便捷方法
        Timestamp sqlTs = Timestamp.valueOf(ldt);
        System.out.println("原始 LocalDateTime: " + ldt);
        System.out.println("转换后的 Timestamp: " + sqlTs);
    }
}

从时间戳数值(毫秒秒数)创建对象

如果你有一个从 System.currentTimeMillis() 或其他来源获得的 long 类型的时间戳数值。

在旧 API 中

long timestampMillis = 1698379800000L;
Date date = new Date(timestampMillis);

在新 API 中

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
long timestampMillis = 1698379800000L;
// 1. 转换为 Instant (UTC 时间点)
Instant instant = Instant.ofEpochMilli(timestampMillis);
System.out.println("Instant: " + instant);
// 2. 转换为指定时区的 LocalDateTime
// 转换为系统默认时区的 LocalDateTime
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
System.out.println("LocalDateTime (系统默认时区): " + ldt);
// 转换为纽约时区的 LocalDateTime
LocalDateTime nycLdt = LocalDateTime.ofInstant(instant, ZoneId.of("America/New_York"));
System.out.println("LocalDateTime (纽约时区): " + nycLdt);

总结与最佳实践

特性 旧 API (java.util.Date) 新 API (java.time)
核心类 Date, SimpleDateFormat LocalDateTime, Instant, DateTimeFormatter
线程安全 SimpleDateFormat 不安全 DateTimeFormatter 安全
易用性 设计有缺陷,功能分散 设计清晰,API 直观
时区处理 较弱 ZonedDateTime, ZoneId 等提供强大支持
与数据库 java.sql.Timestamp Timestamp.valueOf()toLocalDateTime() 方便转换
推荐度 不推荐,仅维护旧项目 强烈推荐,所有新项目都应使用

最佳实践建议:

  1. 新项目一律使用 java.time 包。
  2. 在应用内部处理日期时间时,优先使用 LocalDateTime(如果不需要时区)或 ZonedDateTime(如果需要时区)。
  3. 只在与数据库交互时,才使用 java.sql.Timestamp,并利用 valueOf()toLocalDateTime()java.timejava.sql 之间进行转换。
  4. 永远不要java.text.SimpleDateFormat 声明为 static 共享变量,如果必须使用旧代码,请为每次格式化/解析都创建新实例。
分享:
扫描分享到社交APP
上一篇
下一篇