有什么问题?
java.util.Date 对象仅表示时间轴上的一个瞬间 — 自 UNIX 纪元(格林威治标准时间 1970 年 1 月 1 日 00:00:00)以来的毫秒数的包装。由于它不包含任何Timezone 和Locale 信息,它的toString 函数应用JVM 的Timezone 和Locale 以返回格式为EEE MMM dd HH:mm:ss zzz yyyy 的String ,从这个 毫秒 值得出。要以不同的格式获得java.util.Date 对象的String 表示,Timezone 和Locale,您需要使用具有所需格式的SimpleDateFormat 和适用的Timezone 和Locale,例如
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String strDateNewYork = sdf.format(date);
System.out.println(strDateNewYork);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDateUtc = sdf.format(date);
System.out.println(strDateUtc);
所以你会看到同一瞬间的不同表示,即
2021 年 10 月 27 日上午 11:23:48,美国/纽约 = 2021 年 10 月 27 日,下午 3:38:02,UTC
因为您的服务器默认应用服务器的时区。如果您希望值始终位于固定的Timezone 中,请明确指定如上所示。
我怎样才能拥有与旧服务器中相同的日期格式?
如果您希望值始终位于固定的Locale 中,请明确指定如上所示。
切换到java.time:
java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*。
您可以使用java.time.Instant,其toString 方法使用ISO-8601 表示,因此无论服务器的时区设置如何,输出都保持不变。
演示:
import java.time.Instant;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
System.out.println(now);
}
}
如果你想在不同的时区显示这个瞬间,你可以使用Instant.atZone获取各自的ZonedDateTime。
演示:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
System.out.println(now);
ZonedDateTime zdtNewYork = now.atZone(ZoneId.of("America/New_York"));
System.out.println(zdtNewYork);
ZonedDateTime zdtIndia = now.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);
}
}
通过 Trail: Date Time 了解有关现代日期时间 API 的更多信息。查看this answer 和this answer 了解如何将java.time API 与JDBC 结合使用。
* 如果您正在为一个 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring。请注意,Android 8.0 Oreo 已经提供了support for java.time。