使用 java.time 包将字符串转换为 Date 类型
使用 java.time 包将字符串转换为 Date 类型
1. 完整的转换方法
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
public class StringToDateConverter {
public static void main(String[] args) {
// 目标字符串
String dateString = "2025-12-17 10:56:42.031";
// 方法1:完整转换步骤
Date date1 = convertStringToDate(dateString);
System.out.println("方法1结果: " + date1);
// 方法2:使用工具方法
Date date2 = parseToDate(dateString);
System.out.println("方法2结果: " + date2);
// 方法3:指定时区
Date date3 = parseToDateWithZone(dateString, "Asia/Shanghai");
System.out.println("方法3结果(上海时区): " + date3);
// 验证转换准确性
System.out.println("\n验证转换:");
System.out.println("原始字符串: " + dateString);
System.out.println("转换后Date: " + date1);
// 反向验证:将Date转回字符串
String formatted = formatDateToString(date1);
System.out.println("Date转回字符串: " + formatted);
}
/**
* 方法1:将字符串转换为 Date(使用默认时区)
*/
public static Date convertStringToDate(String dateString) {
try {
// 1. 创建格式化器,匹配字符串格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
// 2. 解析字符串为 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
// 3. 将 LocalDateTime 转换为 Instant(需要时区信息)
// 使用系统默认时区
java.time.Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
// 4. 将 Instant 转换为 Date
return Date.from(instant);
} catch (Exception e) {
throw new RuntimeException("日期格式转换失败: " + dateString, e);
}
}
/**
* 方法2:使用预定义格式化器的工具方法
*/
private static final DateTimeFormatter DEFAULT_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
public static Date parseToDate(String dateString) {
LocalDateTime localDateTime = LocalDateTime.parse(dateString, DEFAULT_FORMATTER);
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
/**
* 方法3:指定特定时区
*/
public static Date parseToDateWithZone(String dateString, String zoneId) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
// 使用指定的时区
ZoneId zone = ZoneId.of(zoneId);
return Date.from(localDateTime.atZone(zone).toInstant());
}
/**
* 将 Date 转换回字符串格式
*/
public static String formatDateToString(Date date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
// 将 Date 转换为 LocalDateTime
LocalDateTime localDateTime = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
return localDateTime.format(formatter);
}
}
2. 灵活的转换工具类
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class DateTimeConverter {
// 预定义的常用格式
public static final String PATTERN_ISO = "yyyy-MM-dd HH:mm:ss.SSS";
public static final String PATTERN_DATE_ONLY = "yyyy-MM-dd";
public static final String PATTERN_TIME_ONLY = "HH:mm:ss.SSS";
public static final String PATTERN_COMPACT = "yyyyMMddHHmmssSSS";
public static final String PATTERN_SLASH = "yyyy/MM/dd HH:mm:ss.SSS";
private static final Map<String, DateTimeFormatter> FORMATTER_CACHE = new HashMap<>();
static {
// 初始化常用格式化器缓存
cacheFormatter(PATTERN_ISO);
cacheFormatter(PATTERN_DATE_ONLY);
cacheFormatter(PATTERN_TIME_ONLY);
cacheFormatter(PATTERN_COMPACT);
cacheFormatter(PATTERN_SLASH);
}
private static void cacheFormatter(String pattern) {
FORMATTER_CACHE.put(pattern, DateTimeFormatter.ofPattern(pattern));
}
/**
* 将字符串转换为 Date(自动检测格式)
*/
public static Date stringToDate(String dateString) {
// 尝试多种格式
String[] patterns = {
"yyyy-MM-dd HH:mm:ss.SSS",
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd HH:mm",
"yyyy-MM-dd",
"yyyy/MM/dd HH:mm:ss.SSS",
"yyyy/MM/dd HH:mm:ss",
"yyyy.MM.dd HH:mm:ss.SSS"
};
for (String pattern : patterns) {
try {
return parseWithPattern(dateString, pattern);
} catch (DateTimeParseException e) {
// 尝试下一个格式
continue;
}
}
throw new IllegalArgumentException("无法解析日期字符串: " + dateString);
}
/**
* 使用指定格式将字符串转换为 Date
*/
public static Date parseWithPattern(String dateString, String pattern) {
DateTimeFormatter formatter = FORMATTER_CACHE.computeIfAbsent(
pattern, DateTimeFormatter::ofPattern
);
// 判断字符串是否包含时间部分
if (pattern.contains("HH") || pattern.contains("mm") || pattern.contains("ss")) {
// 包含时间部分
if (pattern.contains("HH:mm:ss.SSS")) {
// 包含毫秒
LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
} else {
// 不包含毫秒
LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
} else {
// 只有日期部分
LocalDate localDate = LocalDate.parse(dateString, formatter);
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
}
/**
* 将字符串转换为 Date(指定时区)
*/
public static Date stringToDate(String dateString, String pattern, String zoneId) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
ZoneId zone = ZoneId.of(zoneId);
if (pattern.contains("HH:mm:ss.SSS")) {
LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
return Date.from(localDateTime.atZone(zone).toInstant());
} else if (pattern.contains("HH:mm:ss")) {
LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
return Date.from(localDateTime.atZone(zone).toInstant());
} else {
LocalDate localDate = LocalDate.parse(dateString, formatter);
return Date.from(localDate.atStartOfDay(zone).toInstant());
}
}
/**
* 将 Date 转换为指定格式的字符串
*/
public static String dateToString(Date date, String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime localDateTime = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
return localDateTime.format(formatter);
}
/**
* 获取 Date 的各个部分
*/
public static void printDateComponents(Date date) {
LocalDateTime localDateTime = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
System.out.println("年: " + localDateTime.getYear());
System.out.println("月: " + localDateTime.getMonthValue());
System.out.println("日: " + localDateTime.getDayOfMonth());
System.out.println("时: " + localDateTime.getHour());
System.out.println("分: " + localDateTime.getMinute());
System.out.println("秒: " + localDateTime.getSecond());
System.out.println("毫秒: " + localDateTime.getNano() / 1_000_000);
System.out.println("星期: " + localDateTime.getDayOfWeek());
}
public static void main(String[] args) {
// 测试各种格式
String dateString1 = "2025-12-17 10:56:42.031";
String dateString2 = "2025-12-17 10:56:42";
String dateString3 = "2025-12-17";
System.out.println("=== 转换测试 ===");
// 转换带毫秒的字符串
Date date1 = parseWithPattern(dateString1, PATTERN_ISO);
System.out.println("带毫秒: " + date1);
System.out.println("格式化为字符串: " + dateToString(date1, PATTERN_ISO));
// 转换不带毫秒的字符串
Date date2 = parseWithPattern(dateString2, "yyyy-MM-dd HH:mm:ss");
System.out.println("\n不带毫秒: " + date2);
// 转换只有日期的字符串
Date date3 = parseWithPattern(dateString3, PATTERN_DATE_ONLY);
System.out.println("\n只有日期: " + date3);
System.out.println("格式化为日期: " + dateToString(date3, PATTERN_DATE_ONLY));
// 自动检测格式
System.out.println("\n=== 自动检测格式 ===");
Date autoDate = stringToDate("2025/12/17 10:56:42.031");
System.out.println("自动检测结果: " + autoDate);
// 显示日期组成部分
System.out.println("\n=== 日期组成部分 ===");
printDateComponents(date1);
}
}
3. 处理时区问题的转换
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.TimeZone;
public class TimeZoneConverter {
/**
* 将字符串转换为 Date,考虑时区偏移
*/
public static Date convertWithTimeZone(String dateString, String sourceZone, String targetZone) {
// 解析字符串,假设字符串时间是在sourceZone时区
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
// 创建源时区的时间
ZonedDateTime sourceZonedDateTime = localDateTime.atZone(ZoneId.of(sourceZone));
// 转换为目标时区
ZonedDateTime targetZonedDateTime = sourceZonedDateTime.withZoneSameInstant(ZoneId.of(targetZone));
// 转换为 Date(Date 内部存储的是 UTC 时间戳)
return Date.from(targetZonedDateTime.toInstant());
}
/**
* 显示不同时区的同一时间
*/
public static void showInDifferentTimeZones(Date date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
String[] zones = {
"UTC",
"Asia/Shanghai",
"America/New_York",
"Europe/London",
"Asia/Tokyo"
};
System.out.println("同一时间在不同时区的表示:");
for (String zone : zones) {
ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.of(zone));
System.out.printf("%-20s: %s%n", zone, zonedDateTime.format(formatter));
}
}
public static void main(String[] args) {
String dateString = "2025-12-17 10:56:42.031";
System.out.println("原始字符串: " + dateString);
System.out.println("假设这个时间是北京时间");
// 将北京时间转换为Date
Date date = convertWithTimeZone(dateString, "Asia/Shanghai", "UTC");
System.out.println("\n转换为Date (UTC内部存储): " + date);
// 显示在不同时区
showInDifferentTimeZones(date);
// 验证:将Date转换回北京时间字符串
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
ZonedDateTime beijingTime = date.toInstant().atZone(ZoneId.of("Asia/Shanghai"));
System.out.println("\n转换回北京时间: " + beijingTime.format(formatter));
}
}
4. 批量转换和处理异常
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class BatchDateConverter {
/**
* 批量转换字符串为Date
*/
public static List<Date> batchConvert(List<String> dateStrings, String pattern) {
List<Date> results = new ArrayList<>();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
for (int i = 0; i < dateStrings.size(); i++) {
try {
LocalDateTime localDateTime = LocalDateTime.parse(dateStrings.get(i), formatter);
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
results.add(date);
} catch (DateTimeParseException e) {
System.err.printf("第 %d 个字符串解析失败: %s (原因: %s)%n",
i + 1, dateStrings.get(i), e.getMessage());
// 可以选择返回null或抛出异常
results.add(null);
}
}
return results;
}
/**
* 转换并验证日期范围
*/
public static Date convertWithValidation(String dateString, String pattern,
LocalDateTime minDate, LocalDateTime maxDate) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
// 验证日期范围
if (localDateTime.isBefore(minDate)) {
throw new IllegalArgumentException("日期不能早于 " + minDate);
}
if (localDateTime.isAfter(maxDate)) {
throw new IllegalArgumentException("日期不能晚于 " + maxDate);
}
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static void main(String[] args) {
// 批量转换示例
List<String> dateStrings = new ArrayList<>();
dateStrings.add("2025-12-17 10:56:42.031");
dateStrings.add("2025-12-18 14:30:00.500");
dateStrings.add("invalid-date"); // 无效日期
dateStrings.add("2025-12-19 23:59:59.999");
System.out.println("=== 批量转换 ===");
List<Date> dates = batchConvert(dateStrings, "yyyy-MM-dd HH:mm:ss.SSS");
for (int i = 0; i < dates.size(); i++) {
System.out.printf("字符串: %-25s -> Date: %s%n",
dateStrings.get(i), dates.get(i));
}
// 带验证的转换
System.out.println("\n=== 带验证的转换 ===");
try {
LocalDateTime minDate = LocalDateTime.of(2025, 1, 1, 0, 0);
LocalDateTime maxDate = LocalDateTime.of(2025, 12, 31, 23, 59);
Date validDate = convertWithValidation(
"2025-12-17 10:56:42.031",
"yyyy-MM-dd HH:mm:ss.SSS",
minDate, maxDate
);
System.out.println("验证通过的日期: " + validDate);
// 这会抛出异常
Date invalidDate = convertWithValidation(
"2026-01-01 00:00:00.000",
"yyyy-MM-dd HH:mm:ss.SSS",
minDate, maxDate
);
} catch (IllegalArgumentException e) {
System.out.println("验证失败: " + e.getMessage());
}
}
}
5. 实际应用示例
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
public class PracticalExample {
// 数据库中的日期格式
private static final String DB_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
/**
* 模拟从数据库读取字符串并转换为Date
*/
public static Date readFromDatabase(String dbDateString) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DB_DATE_PATTERN);
LocalDateTime localDateTime = LocalDateTime.parse(dbDateString, formatter);
return Date.from(localDateTime.atZone(ZoneId.of("UTC")).toInstant());
}
/**
* 准备写入数据库的Date转换
*/
public static String prepareForDatabase(Date date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DB_DATE_PATTERN);
LocalDateTime localDateTime = date.toInstant()
.atZone(ZoneId.of("UTC"))
.toLocalDateTime();
return localDateTime.format(formatter);
}
/**
* 生成日志时间戳
*/
public static String createLogTimestamp() {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
return now.format(formatter);
}
/**
* 解析日志时间戳为Date
*/
public static Date parseLogTimestamp(String logTimestamp) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse(logTimestamp, formatter);
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static void main(String[] args) {
System.out.println("=== 数据库操作示例 ===");
// 模拟数据库日期字符串
String dbDateStr = "2025-12-17 10:56:42.031";
// 读取并转换为Date
Date dateFromDB = readFromDatabase(dbDateStr);
System.out.println("从数据库读取: " + dbDateStr);
System.out.println("转换为Date: " + dateFromDB);
// 处理业务逻辑后写回数据库
Date processedDate = new Date(dateFromDB.getTime() + 3600000); // 加1小时
String dbWriteStr = prepareForDatabase(processedDate);
System.out.println("处理后写回数据库: " + dbWriteStr);
System.out.println("\n=== 日志处理示例 ===");
// 生成日志时间戳
String logTime = createLogTimestamp();
System.out.println("日志时间戳: " + logTime);
// 解析日志时间戳
Date logDate = parseLogTimestamp(logTime);
System.out.println("解析为Date: " + logDate);
// 计算时间差
long diff = System.currentTimeMillis() - logDate.getTime();
System.out.println("距离现在: " + diff + " 毫秒");
}
}
关键要点总结
-
核心转换步骤:
// 1. 定义格式化器 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); // 2. 解析为LocalDateTime LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter); // 3. 转换为Instant(需要时区) Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant(); // 4. 转换为Date Date date = Date.from(instant); -
时区注意事项:
- 明确你的字符串表示的是哪个时区的时间
- 数据库通常使用UTC时间
- 显示给用户时需要转换为本地时区
-
最佳实践:
- 使用常量定义日期格式模式
- 缓存DateTimeFormatter对象(线程安全)
- 总是处理DateTimeParseException异常
- 在团队中统一日期处理规范
-
性能优化:
- 复用DateTimeFormatter对象
- 使用预定义的ISO格式器(如
DateTimeFormatter.ISO_LOCAL_DATE_TIME)
根据你的具体需求选择合适的方法。如果需要处理大量日期转换,建议使用工具类并缓存格式化器。

浙公网安备 33010602011771号