將 13 位毫秒級時間戳轉為可讀日期格式,是日常開發高頻需求。本文對比傳統 SimpleDateFormat 與 Java 8+ java.time 兩種方案,給出生產級代碼範本。
String timestamp = "1328007600000"; // 13 位毫秒字符串
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = sdf.format(new Date(Long.parseLong(timestamp)));
System.out.println(dateStr); // 2012-01-31
注意點:
SimpleDateFormat 非線程安全,多線程環境下請用 ThreadLocal 或每次新建實例。ParseException,需捕獲處理。import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
String timestamp = "1328007600000";
long millis = Long.parseLong(timestamp);
// 毫秒轉 Instant → 本地日期時間 → 格式化
LocalDateTime ldt = Instant.ofEpochMilli(millis)
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
String dateStr = ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(dateStr); // 2024-05-20 (視運行時區而定)
| 特性 | SimpleDateFormat | java.time (DateTimeFormatter) |
|---|---|---|
| 線程安全 | ❌ 不安全 | ✅ 不可變,天然線程安全 |
| 時區處理 | 隱式使用默認時區 | 顯式 ZoneId,清晰可控 |
| API 設計 | 舊式 mutable | 流式、不可變、鏈式調用 |
| 性能 | 較低 | 更優(無同步開銷) |
public final class DateUtils {
private static final DateTimeFormatter DEFAULT_FMT =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private DateUtils() {}
/** 毫秒時間戳 → 格式化字符串 */
public static String formatMillis(long millis, String pattern) {
DateTimeFormatter fmt = (pattern == null) ? DEFAULT_FMT
: DateTimeFormatter.ofPattern(pattern);
return Instant.ofEpochMilli(millis)
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
.format(fmt);
}
/** 字符串時間戳 → 格式化字符串 */
public static String formatMillis(String millisStr, String pattern) {
try {
return formatMillis(Long.parseLong(millisStr), pattern);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("無效時間戳:" + millisStr, e);
}
}
}
yyyy-MM-dd:日期HH:mm:ss:時間(24小時制)yyyy-MM-dd HH:mm:ss:日期時間yyyy-MM-dd'T'HH:mm:ss.SSSZ:ISO-8601 帶毫秒與時區新項目強烈建議使用 java.time 包,代碼更簡潔、線程安全、時區語義明確。維護舊代碼時,若無法升級 JDK,請務必用 ThreadLocal 包裝 SimpleDateFormat 避免並發問題。