Java日期时间格式化核心是选用合适的API实现字符串与日期对象的转换,推荐使用JDK 8的DateTimeFormatter,因其线程安全、设计清晰,优于旧的SimpleDateFormat。

在Java里处理日期时间格式化,核心在于选择恰当的API来定义你想要的显示样式,并确保数据在不同场景下(比如存储、显示、跨时区通信)的准确性。无论是早期的
java.util.Date
SimpleDateFormat
java.time
要实现日期时间的格式化,Java提供了两种主要的方式,一种是老旧但仍广泛存在的
java.text.SimpleDateFormat
java.time.format.DateTimeFormatter
使用java.text.SimpleDateFormat
这个类允许你使用模式字符串(如"yyyy-MM-dd HH:mm:ss")来格式化或解析日期。
立即学习“Java免费学习笔记(深入)”;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatOldApi {
public static void main(String[] args) {
Date now = new Date();
// 定义格式模式
SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String formattedDate = formatter.format(now);
System.out.println("格式化后的日期 (旧API): " + formattedDate);
// 解析字符串到Date对象
String dateString = "2023年10月26日 14:30:00";
try {
Date parsedDate = formatter.parse(dateString);
System.out.println("解析后的日期 (旧API): " + parsedDate);
} catch (java.text.ParseException e) {
System.err.println("日期解析失败: " + e.getMessage());
}
}
}使用java.time.format.DateTimeFormatter
这是Java 8及以后版本推荐的日期时间处理方式,它更加健壮、线程安全,并且设计更合理。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class DateFormatNewApi {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
// 定义格式模式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = now.format(formatter);
System.out.println("格式化后的日期时间 (新API): " + formattedDateTime);
// 解析字符串到LocalDateTime对象
String dateTimeString = "2023-10-26 14:30:00";
try {
LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println("解析后的日期时间 (新API): " + parsedDateTime);
} catch (DateTimeParseException e) {
System.err.println("日期时间解析失败: " + e.getMessage());
}
// 使用预定义的格式
String isoFormatted = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println("ISO格式: " + isoFormatted);
}
}在日期时间格式化这块,我踩过不少坑,特别是早期使用
SimpleDateFormat
1. SimpleDateFormat
这真的是个老生常谈的问题了。
SimpleDateFormat
format()
parse()
SimpleDateFormat
SimpleDateFormat
规避策略:
不要共享实例: 最简单粗暴的方法就是在每次需要格式化或解析时,都创建一个新的
SimpleDateFormat
使用ThreadLocal
SimpleDateFormat
// 示例:使用ThreadLocal
public class DateFormatThreadSafe {
private static final ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
public static String format(Date date) {
return formatter.get().format(date);
}
public static Date parse(String dateString) throws java.text.ParseException {
return formatter.get().parse(dateString);
}
}切换到DateTimeFormatter
DateTimeFormatter
java.time
2. 时区和本地化(Locale)问题
日期时间格式化不仅仅是数字和符号的排列,它还涉及到时区和不同地域的习惯。比如,同一个时间点,在北京显示是上午,在纽约可能就是前一天晚上了。或者,有些国家习惯用“月/日/年”,有些则是“日/月/年”。
规避策略:
明确指定Locale
SimpleDateFormat
DateTimeFormatter
Locale
// SimpleDateFormat
SimpleDateFormat usFormatter = new SimpleDateFormat("MM/dd/yyyy", java.util.Locale.US);
SimpleDateFormat cnFormatter = new SimpleDateFormat("yyyy年MM月dd日", java.util.Locale.CHINA);
// DateTimeFormatter
DateTimeFormatter usDtFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy").withLocale(java.util.Locale.US);
DateTimeFormatter cnDtFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日").withLocale(java.util.Locale.CHINA);处理时区: 对于需要精确到时区的时间,一定要使用带时区概念的类,比如
ZonedDateTime
OffsetDateTime
3. 解析的严格性
SimpleDateFormat
规避策略:
设置setLenient(false)
SimpleDateFormat
setLenient(false)
SimpleDateFormat strictFormatter = new SimpleDateFormat("yyyy-MM-dd");
strictFormatter.setLenient(false); // 设置为严格模式
try {
strictFormatter.parse("2023-13-32"); // 会抛出ParseException
} catch (java.text.ParseException e) {
System.err.println("严格解析错误: " + e.getMessage());
}DateTimeFormatter
DateTimeFormatter
DateTimeParseException
说实话,如果你的项目还在用
java.util.Date
Calendar
java.time
核心优势:
java.time
LocalDateTime.now().plusDays(1).minusHours(2)
LocalDate
LocalTime
LocalDateTime
Instant
ZonedDateTime
LocalDateTime
ZoneId
OffsetDateTime
LocalDateTime
ZoneOffset
Duration
Instant
LocalTime
Period
LocalDate
DateTimeFormatter
java.time
实用示例:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;
public class NewApiExamples {
public static void main(String[] args) {
// 创建日期、时间、日期时间对象
LocalDate today = LocalDate.now(); // 2023-10-26 (假设今天)
LocalDate specificDate = LocalDate.of(2024, Month.JANUARY, 1); // 2024-01-01
LocalTime nowTime = LocalTime.now(); // 14:30:00.123 (假设现在)
LocalTime specificTime = LocalTime.of(9, 30, 0); // 09:30:00
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDateTime specificDateTime = LocalDateTime.of(2023, 11, 1, 10, 0, 0); // 2023-11-01T10:00:00
System.out.println("今天: " + today);
System.out.println("特定日期: " + specificDate);
System.out.println("现在时间: " + nowTime);
System.out.println("特定时间: " + specificTime);
System.out.println("当前日期时间: " + currentDateTime);
System.out.println("特定日期时间: " + specificDateTime);
// 日期时间操作 (不可变性体现)
LocalDate nextWeek = today.plusWeeks(1);
System.out.println("下周的今天: " + nextWeek);
LocalDateTime twoHoursLater = currentDateTime.plusHours(2);
System.out.println("两小时后: " + twoHoursLater);
// 格式化
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss E"); // E代表星期几
String formatted = currentDateTime.format(customFormatter);
System.out.println("自定义格式化: " + formatted);
// 解析
String dateToParse = "2025-05-20 10:00:00";
LocalDateTime parsed = LocalDateTime.parse(dateToParse, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println("解析字符串: " + parsed);
}
}在实际开发中,仅仅格式化日期是远远不够的。很多时候我们需要进行日期计算(比如计算两个日期之间的天数,或者某个日期几天后是什么时候),以及处理跨时区的日期时间。这些场景,
java.time
1. 日期计算:plus()
minus()
until()
java.time
plus
minus
until
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
public class DateCalculation {
public static void main(String[] args) {
LocalDate date1 = LocalDate.of(2023, 1, 15);
LocalDate date2 = LocalDate.of(2023, 3, 10);
// 计算两个日期之间的天数
long daysBetween = ChronoUnit.DAYS.between(date1, date2);
System.out.println(date1 + " 和 " + date2 + " 之间相差 " + daysBetween + " 天"); // 54天
// 计算两个日期之间的年、月、日
Period period = Period.between(date1, date2);
System.out.println("相差: " + period.getYears() + " 年 " + period.getMonths() + " 月 " + period.getDays() + " 天"); // 0 年 1 月 23 天
LocalDateTime dateTime1 = LocalDateTime.of(2023, 10, 26, 10, 0, 0);
LocalDateTime dateTime2 = LocalDateTime.of(2023, 10, 26, 12, 30, 0);
// 计算两个时间点之间的持续时间
Duration duration = Duration.between(dateTime1, dateTime2);
System.out.println(dateTime1 + " 和 " + dateTime2 + " 之间相差 " + duration.toMinutes() + " 分钟"); // 150分钟
System.out.println("持续时间 (小时): " + duration.toHours()); // 2小时
// 某个日期加上或减去时间
LocalDate futureDate = LocalDate.now().plusMonths(3).plusDays(5);
System.out.println("三个月零五天后: " + futureDate);
LocalDateTime pastTime = LocalDateTime.now().minusHours(1).minusMinutes(30);
System.out.println("一个半小时前: " + pastTime);
}
}2. 时区处理:ZoneId
ZonedDateTime
OffsetDateTime
时区真的是个复杂又容易出错的地方。想象一下,一个用户在北京提交了一个订单,服务器在美国,数据库在欧洲,你得确保时间在任何环节都准确无误。
ZoneId
Instant
ZonedDateTime
ZoneId
OffsetDateTime
实用示例:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class TimeZoneHandling {
public static void main(String[] args) {
// 获取系统默认时区
ZoneId defaultZone = ZoneId.systemDefault();
System.out.println("系统默认时区: " + defaultZone); // 例如: Asia/Shanghai
// 获取特定时区
ZoneId shanghaiZone = ZoneId.of("Asia/Shanghai");
ZoneId newYorkZone = ZoneId.of("America/New_York");
// 1. 从LocalDateTime到ZonedDateTime
LocalDateTime localDateTime = LocalDateTime.of(2023, 10, 26, 10, 0, 0); // 本地时间 2023-10-26 10:00:00
ZonedDateTime shanghaiTime = localDateTime.atZone(shanghaiZone);
System.out.println("上海时间: " + shanghaiTime); // 2023-10-26T10:00+08:00[Asia/Shanghai]
// 2. 将一个ZonedDateTime转换到另一个时区
ZonedDateTime newYorkTime = shanghaiTime.withZoneSameInstant(newYorkZone);
System.out.println("纽约时间 (与上海时间同一瞬时): " + newYorkTime); // 2023-10-25T22:00-04:00[America/New_York] (夏令时)
// 3. Instant的使用:存储和传输的理想选择
// 假设从数据库或网络获取了一个UTC时间戳
Instant nowInstant = Instant.now();
System.out.println("当前瞬时 (UTC): " + nowInstant); // 例如: 2023-10-26T06:00:00Z (Z代表Zulu time, 即UTC)
// 将Instant转换为特定时区的ZonedDateTime进行显示
ZonedDateTime zdtInShanghai = nowInstant.atZone(shanghaiZone);
System.out.println("UTC瞬时在上海时区: " + zdtInShanghai.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
ZonedDateTime zdtInNewYork = nowInstant.atZone(newYorkZone);
System.out.println("UTC瞬时在纽约时区: " + zdtInNewYork.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// 4. OffsetDateTime:固定偏移量,不关心具体时区规则(如夏令时)
// 假设我们知道一个时间是UTC+8
java.time.OffsetDateTime offsetDt = java.time.OffsetDateTime.of(2023, 10, 26, 10, 0, 0, 0, java.time.ZoneOffset.ofHours(8));
System.out.println("固定偏移量时间: " + offsetDt); // 2023-10-26T10:00+08:00
// 5. 将ZonedDateTime转换为Instant(丢失时区信息,只保留瞬时点)
Instant instantFromZdt = shanghaiTime.toInstant();
System.out.println("从上海时间转换的瞬时: " + instantFromZdt);
}
}处理时区时,最关键的是要理解
Instant
ZonedDateTime
OffsetDateTime
Instant
以上就是java代码怎样实现日期时间的格式化 java代码日期处理的实用方法的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号