Java获取当前的UTC时间
- Java获取当前的UTC时间
- Calendar与TimeZone
- 结论:因此想要获取UTC时间可以修改系统默认时区或转换时区
- 修改系统默认时区
- SimpleDateFormat 转换时区
- Instant
Java获取当前的UTC时间
java中如何获取utc时间,并转为Date对象,这是一个常见的问题。可能会找到如下代码的回答:
public static void main(String[] args) {
Date current = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTime();
System.out.println(current);
}
但是运行过后发现不能获取带UTC时间
Tue Mar 20 13:05:22 CST 2023
那么为什么不能获取,如何正确获取utc时间呢?
Calendar与TimeZone
分析一下上述代码为什么不能获取正确的UTC时间
看一下Calendar.getTime()
方法
public final Date getTime() {
return new Date(getTimeInMillis());
}
本质上是通过getTimeInMillis()
获取了UTC的毫秒时间,然后new一个Date对象。
Date对象保存的是毫秒数,本身不带时区信息。但是如果想要把Date展现出来(比如System.out.println(new Date())
实际上是生成了当前时间并调用了Date.toString()
方法)时就会存在时区的概念转换,因为不是所有人都只想要UTC时间。所以当调用Date.toString()
、Date.parse()
等方法时,就会存在时区信息。
public String toString() {
BaseCalendar.Date date = normalize();
StringBuilder sb = new StringBuilder(28);
int index = date.getDayOfWeek();
if (index == BaseCalendar.SUNDAY) {
index = 8;
}
convertToAbbr(sb, wtb[index]).append(' ');
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' ');
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':');
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' ');
TimeZone zi = date.getZone();
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US));
} else {
sb.append("GMT");
}
sb.append(' ').append(date.getYear());
return sb.toString();
}
private final BaseCalendar.Date normalize() {
if (cdate == null) {
BaseCalendar cal = getCalendarSystem(fastTime);
cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
TimeZone.getDefaultRef());
return cdate;
}
}
可以发现toString()方法使用了normalize()
初始化了一个带时区信息的BaseCalendar,而会默认使用TimeZone.getDefaultRef()
,即JVM的系统默认时区。所以这里可以解释System.out.println(new Date())
时打印的是带时区的时间,而非UTC时间。
结论:因此想要获取UTC时间可以修改系统默认时区或转换时区
修改系统默认时区
public static void main(String[] args) {
Date current = Calendar.getInstance().getTime();
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(current);
}
但是此修改可能是全局性的,建议在代码启动之初设定全部使用同一时区时间,后面就不再频繁更改,避免产生时间错乱问题。
SimpleDateFormat 转换时区
public static void main(String[] args) {
Date current = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTime();
System.out.println(current);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(format.format(current));
};
输出
Wed Mar 22 00:29:11 CST 2023
2023-03-21 16:29:11
Instant
jdk8提供了Instant对象,Instant获取的是格林威治标准时间(UTC时间)。因为Instant是表示时间戳的对象,它不依赖于时区信息。但是在显示Instant对象时,需要将其转换为特定时区的本地时间。
public static void main(String[] args) {
Date current= Date.from(Instant.now());
System.out.println(current);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(format.format(current));
}
输出
Wed Mar 22 00:29:11 CST 2023
2023-03-21 16:29:11
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)