HOWTO · Java
用 Java 将字符串转换为时间戳
它显示了四种在 Java 中将字符串转换为时间戳的方法
本页内容
java.sql.Timestamp 表示具有秒的小数精度的日期和时间,常用于 JDBC。应根据输入的形式选择解析方式:SQL 风格的日期时间可使用 Timestamp.valueOf(),自定义日期时间格式可使用 DateTimeFormatter,只有日期的输入则可使用 LocalDate。如果输入中没有时区信息,这些转换也无法推断出时区。
使用 Timestamp.valueOf() 解析标准日期时间字符串
对于 2024-06-15 14:30:00 这样的字符串,Timestamp.valueOf(String) 可以直接解析 SQL 时间戳格式。该 API 接受 JDBC 时间戳转义格式的值,也允许包含可选的小数秒;它并不局限于此处展示的整秒格式。如果输入使用了不同的字段顺序或分隔符,请改用其他解析方式。
运行此示例:
import java.sql.Timestamp;
public class StringToTimestamp {
public static void main(String[] args) {
String input = "2024-06-15 14:30:00";
Timestamp timestamp = Timestamp.valueOf(input);
System.out.println(timestamp);
}
}
2024-06-15 14:30:00.0
输出中的 .0 表示秒的小数部分。如果值的格式不正确,API 会拒绝解析;对于外部输入,应在应用程序边界处进行校验并处理解析错误。
使用 DateTimeFormatter 解析自定义日期时间字符串
如果输入值采用 15/06/2024 14:30:00 这样的格式,可使用 DateTimeFormatter 将其解析为 LocalDateTime,再将该对象传给 Timestamp.valueOf(LocalDateTime)。格式模式必须与输入相符:dd/MM/uuuu 表示日、月、年,HH:mm:ss 使用 24 小时制。LocalDateTime 不包含偏移量或时区,因此这种方式会保留本地日期和时间字段,但不能确定唯一的时间线时刻。
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CustomTimestamp {
public static void main(String[] args) {
String input = "15/06/2024 14:30:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse(input, formatter);
Timestamp timestamp = Timestamp.valueOf(localDateTime);
}
}
使用 SimpleDateFormat 将解析后的日期转换为 Timestamp
对于使用 java.util.Date 的旧代码,可以用 SimpleDateFormat 解析自定义格式。解析结果是一个 Date;getTime() 返回其自纪元起算的毫秒值,可传给 Timestamp 构造函数。除非另行设置,SimpleDateFormat 使用 JVM 默认时区,并且默认采用宽松解析。若需要可预测的解释结果,应明确设置时区和宽松解析选项。示例将时区固定为 UTC,并关闭宽松解析。该 API 还是可变且非线程安全的,因此不要让多个线程同时共用同一个实例。
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class LegacyTimestamp {
public static void main(String[] args) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
formatter.setLenient(false);
Date parsed = formatter.parse("15/06/2024 14:30:00");
Timestamp timestamp = new Timestamp(parsed.getTime());
}
}
使用 LocalDate.atStartOfDay() 将仅含日期的字符串转换为 Timestamp
仅含日期的值没有指定时间。可将其解析为 LocalDate,通过 atStartOfDay() 选择午夜作为预期时间,再将得到的 LocalDateTime 转换为 Timestamp。这样会明确写出所采用的假设;输入中原本没有的时间并不会因此得到保留。
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class DateOnlyTimestamp {
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2024-06-15");
LocalDateTime startOfDay = date.atStartOfDay();
Timestamp timestamp = Timestamp.valueOf(startOfDay);
}
}
如何选择 LocalDateTime 或 Timestamp
如果值表示本地日历日期和钟表时间,而且应用程序暂时不应为它指定时区,请使用 LocalDateTime。如果 JDBC 等 API 要求 java.sql.Timestamp,则使用 Timestamp;它可以保存秒的小数部分,并通过毫秒值表示时间线上的一个时刻。将 LocalDateTime 转换为 Timestamp 时,会使用 JVM 默认时区推导该毫秒值,因此在默认时区不同的机器上,相同的本地日期和时间字段可能对应不同的时刻。
如果输入包含偏移量或地区信息,应先用能够表示偏移量或时区的 java.time 类型解析并保留这些信息,再转换为时间线上的时刻或数据库类型。Timestamp.valueOf() 和 LocalDateTime 都无法推断发送方意图采用的时区。数据库列类型和 JDBC 驱动也可能应用各自的时区规则,因此应确保应用程序在存储和读取数据时采用一致的假设。