Python 的 datetime 模块功能集中、设计简洁,而 Java 的日期时间 API 更为分散,但经过 Java 8 的 java.time 包重整后,已经非常强大和现代化。
核心对应关系
这是一个快速参考表,帮助你快速找到 Python 和 Java 中功能最接近的类。
Python (datetime 模块) |
Java (java.time 包) |
关键说明 |
|---|---|---|
datetime.datetime |
java.time.LocalDateTime |
都不带时区,表示一个日期和时间点。 |
datetime.date |
java.time.LocalDate |
都不带时区,只表示日期。 |
datetime.time |
java.time.LocalTime |
都不带时区,只表示时间。 |
datetime.timedelta |
java.time.Duration |
都表示两个时间点之间的时长。 |
datetime.timezone |
java.time.ZoneId |
都表示时区信息。 |
datetime.datetime + tzinfo |
java.time.ZonedDateTime |
都带时区,表示一个具体的、有时区的日期时间。 |
datetime.datetime.utcnow() |
java.time.Instant |
都表示 UTC (格林威治) 时间线上的一个瞬时点。 |
详细对比与代码示例
创建日期时间对象
Python:
# 从当前时间创建
now_dt = datetime.datetime.now()
now_utc_dt = datetime.datetime.utcnow()
# 从指定字符串创建 (格式需匹配)
str_dt = datetime.datetime.strptime("2025-10-27 10:30:00", "%Y-%m-%d %H:%M:%S")
# 从指定年月日时分秒创建
custom_dt = datetime.datetime(2025, 10, 27, 10, 30, 0)
# 创建带时区的 datetime
tz = datetime.timezone(datetime.timedelta(hours=8)) # 东八区
tz_dt = datetime.datetime(2025, 10, 27, 10, 30, 0, tzinfo=tz)
Java:
// 从当前时间创建 (系统默认时区)
LocalDateTime nowLdt = LocalDateTime.now();
// 从当前UTC时间创建
Instant nowInstant = Instant.now();
// 从指定字符串创建 (格式需匹配)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime strLdt = LocalDateTime.parse("2025-10-27 10:30:00", formatter);
// 从指定年月日时分秒创建
LocalDateTime customLdt = LocalDateTime.of(2025, 10, 27, 10, 30, 0);
// 创建带时区的 ZonedDateTime
ZoneId zoneId = ZoneId.of("Asia/Shanghai"); // 推荐使用时区ID
ZonedDateTime zonedDt = ZonedDateTime.of(2025, 10, 27, 10, 30, 0, 0, zoneId);
// 创建 Instant (UTC时间点)
Instant instant = Instant.ofEpochSecond(1698381000); // 从Unix时间戳创建
获取日期时间的各个部分
Python:
dt = datetime.datetime(2025, 10, 27, 10, 30, 45) print(dt.year) # 2025 print(dt.month) # 10 print(dt.day) # 27 print(dt.hour) # 10 print(dt.minute) # 30 print(dt.second) # 45 print(dt.weekday()) # 4 (周一是0, 周二是1, ..., 周五是4)
Java:
LocalDateTime ldt = LocalDateTime.of(2025, 10, 27, 10, 30, 45); System.out.println(ldt.getYear()); // 2025 System.out.println(ldt.getMonth()); // OCTOBER System.out.println(ldt.getDayOfMonth()); // 27 System.out.println(ldt.getHour()); // 10 System.out.println(ldt.getMinute()); // 30 System.out.println(ldt.getSecond()); // 45 System.out.println(ldt.getDayOfWeek()); // FRIDAY (枚举类型)
格式化与解析
Python:
dt = datetime.datetime(2025, 10, 27, 10, 30, 45)
# 格式化成字符串
formatted_str = dt.strftime("%Y-%m-%d %H:%M:%S")
print(formatted_str) # 输出: 2025-10-27 10:30:45
# 从字符串解析
parsed_dt = datetime.datetime.strptime("2025-10-27", "%Y-%m-%d")
Java:
LocalDateTime ldt = LocalDateTime.of(2025, 10, 27, 10, 30, 45);
// 格式化成字符串
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedStr = ldt.format(formatter);
System.out.println(formattedStr); // 输出: 2025-10-27 10:30:45
// 从字符串解析
LocalDateTime parsedLdt = LocalDateTime.parse("2025-10-27", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
日期时间计算
Python:
使用 timedelta 对象进行加减。
from datetime import datetime, timedelta dt = datetime(2025, 10, 27, 10, 30, 0) # 加上 5 天 new_dt = dt + timedelta(days=5) print(new_dt) # 2025-11-01 10:30:00 # 减去 2 小时 30 分钟 another_dt = dt - timedelta(hours=2, minutes=30) print(another_dt) # 2025-10-27 08:00:00
Java:
使用 plus...() 和 minus...() 方法,或者 Duration。
import java.time.LocalDateTime; import java.time.Duration; LocalDateTime ldt = LocalDateTime.of(2025, 10, 27, 10, 30, 0); // 加上 5 天 LocalDateTime newLdt = ldt.plusDays(5); System.out.println(newLdt); // 2025-11-01T10:30 // 减去 2 小时 30 分钟 LocalDateTime anotherLdt = ldt.minusHours(2).minusMinutes(30); System.out.println(anotherLdt); // 2025-10-27T08:00 // 使用 Duration (更灵活,用于计算时长) Duration duration = Duration.ofHours(2).plusMinutes(30); LocalWithDuration = ldt.minus(duration); System.out.println(localWithDuration); // 2025-10-27T08:00
时区转换
Python:
from datetime import datetime, timezone, timedelta # 创建一个带时区的 datetime shanghai_tz = timezone(timedelta(hours=8)) dt_sh = datetime(2025, 10, 27, 10, 30, 0, tzinfo=shanghai_tz) # 转换为 UTC dt_utc = dt_sh.astimezone(timezone.utc) print(dt_utc) # 2025-10-27 02:30:00+00:00 # 转换为纽约时区 new_york_tz = timezone(timedelta(hours=-4)) # 简化示例,实际应用 pytz dt_ny = dt_sh.astimezone(new_york_tz) print(dt_ny) # 2025-10-26 22:30:00-04:00
Java:
import java.time.ZoneId;
import java.time.ZonedDateTime;
// 创建一个带时区的 ZonedDateTime
ZoneId shanghaiZone = ZoneId.of("Asia/Shanghai");
ZonedDateTime zdtSh = ZonedDateTime.of(2025, 10, 27, 10, 30, 0, 0, shanghaiZone);
// 转换为 UTC
ZonedDateTime zdtUtc = zdtSh.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println(zdtUtc); // 2025-10-27T02:30Z[UTC]
// 转换为纽约时区
ZoneId newYorkZone = ZoneId.of("America/New_York");
ZonedDateTime zdtNy = zdtSh.withZoneSameInstant(newYorkZone);
System.out.println(zdtNy); // 2025-10-26T22:30-04:00[America/New_York]
重要差异与注意事项
-
API 设计哲学:
- Python:
datetime对象是不可变的,所有修改操作(如 , )都会返回一个新的datetime对象,原对象保持不变。 - Java:
java.time包中的类(如LocalDateTime)也是不可变的,所有修改操作(如plusDays(),minusHours())都返回一个新的实例,原实例保持不变,这与 Python 的设计一致。
- Python:
-
时区处理:
- Python (旧): 传统上使用第三方库
pytz来处理时区,它比标准库的datetime.timezone更强大(支持历史时区变更等)。 - Java:
java.time.ZoneId内置了非常完善的时区数据库(来自 IANA),推荐直接使用ZoneId.of("Continent/City")这样的字符串,如Asia/Shanghai,而不是像UTC+8这样的固定偏移。
- Python (旧): 传统上使用第三方库
-
Instant vs. ZonedDateTime:
Instant是时间线上的一个瞬时点,不关联时区,是计算机内部表示时间最精确的方式。ZonedDateTime是Instant加上一个ZoneId的组合,是人类可读的、有时区的日期时间。- 在 Python 中,
datetime.datetime.utcnow()接近Instant,但它没有纳秒级精度,并且返回的是一个datetime对象,Python 3.3+ 引入了datetime.timezone.utc,可以创建更标准的 UTCdatetime。
-
遗留 API (
java.util.Date和java.sql.Date):- 在 Java 8 之前,
java.util.Date是主要的日期时间类,但它有很多设计缺陷:- 年份从 1900 开始,月份从 0 开始。
- 同时包含日期和时间,又不带时区信息,非常混乱。
- 可变。
- 强烈建议在新项目中完全避免使用
java.util.Date和java.sql.Date,除非需要与旧的、未升级的代码库交互。java.sql.Date甚至只是java.util.Date的一个子集,只包含日期部分。
- 在 Java 8 之前,
| 特性 | Python (datetime) |
Java (java.time) |
|---|---|---|
| 核心类 | datetime, date, time, timedelta |
LocalDateTime, LocalDate, LocalTime, Duration, Instant |
| 时区类 | datetime.timezone (标准库较弱), pytz (第三方库强大) |
ZoneId, ZonedDateTime (非常强大) |
| 不变性 | 是 | 是 |
| 字符串格式化 | strftime(), strptime() |
DateTimeFormatter |
| 计算 | timedelta 对象 |
plus...(), minus...() 方法, Duration |
| 现代性 | 标准库,稳定,功能集中 | Java 8 引入,设计优秀,功能全面,是当前标准 |
如果你正在从 Python 迁移到 Java,或者需要在两者之间处理日期时间,datetime.datetime 通常对应 LocalDateTime,datetime.timedelta 对应 Duration,而处理带时区的时间时,则使用 ZonedDateTime。
