java.time
旧的日期时间 API(java.util
日期时间类型及其格式类型SimpleDateFormat
等)已过时且容易出错。建议完全停止使用它并切换到java.time
现代日期时间 API *。
使用java.time
现代 API 的解决方案:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.now();
System.out.println(instant);
ZonedDateTime zdtIndia = instant.atZone(ZoneId.of("Asia/Calcutta"));
ZonedDateTime zdtNewYork = instant.atZone(ZoneId.of("America/New_York"));
System.out.println(zdtIndia);
System.out.println(zdtNewYork);
}
}
输出:
2021-05-19T21:08:54.241341Z
2021-05-20T02:38:54.241341+05:30[Asia/Calcutta]
2021-05-19T17:08:54.241341-04:00[America/New_York]
Instant
表示时间线上的一个瞬时点。Z
输出中的 是零时区偏移的时区指示符。它代表 Zulu 并指定Etc/UTC
时区(时区偏移量为+00:00
小时)。
从Trail: Date Time了解更多关于java.time
现代日期时间 API *的信息。
使用旧版 API 的解决方案:
该java.util.Date
对象不是像现代日期时间类型那样的真实日期时间对象;相反,它表示自称为“纪元” January 1, 1970, 00:00:00 GMT
(或 UTC)的标准基准时间以来的毫秒数。当您打印 的对象时java.util.Date
,其toString
方法会返回 JVM 时区中的日期时间,根据此毫秒值计算得出。如果您需要在不同的时区打印日期时间,则需要将时区设置为SimpleDateFormat
并从中获取格式化字符串。
演示:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS[zzzzz]");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
String dtIndia = sdf.format(date);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String dtNewYork = sdf.format(date);
System.out.println(dtIndia);
System.out.println(dtNewYork);
}
}
输出:
Wed May 19 22:16:08 BST 2021
2021-05-20T02:46:08.024[India Standard Time]
2021-05-19T17:16:08.024[Eastern Daylight Time]
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和您的 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring和How to use ThreeTenABP in Android Project。