问题:为何Calendar设置timezone后,时间戳没变
我想设置成雅加达时区(东7区,即北京时间-1h),我是这样设置时间戳的:
//我想设置成雅加达时区(东7区,即北京时间-1h)
Date now = new Date();
System.out.println(now);
System.out.println(now.getTime());
System.out.println(TimeZone.getDefault().getDisplayName());
System.out.println("=================");
Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Jakarta"));
Date date1 = cal1.getTime();
System.out.println(date1);
System.out.println(date1.getTime());
System.out.println(cal1.getTimeZone().getDisplayName());
System.out.println("=================");
输出:
=================
Sun Sep 06 23:39:43 CST 2020
1599406783471
中国标准时间
=================
Sun Sep 06 23:39:43 CST 2020
1599406783501
西印度尼西亚时间
=================
我惊呆了,为何设置了timezone,时间和北京时间还是一样呢??
找了网上答案,需要这样才可以达到我想要的,这是为什么呢?:
//TimeZone设置默认时区,设置一次永久生效
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Jakarta"));
Calendar cal2 = Calendar.getInstance();
Date date2 = cal2.getTime();
System.out.println(date2);
System.out.println(date2.getTime());
System.out.println(cal2.getTimeZone().getDisplayName());
输出:
Sun Sep 06 22:39:43 WIB 2020
1599406783504
西印度尼西亚时间
同时有个结论:date.getTime得到的时间戳几乎是一样的,只是后三位毫秒数不一样
看了网上的答案:
即:
时间和日历是两个不同的概念。
Date代表的是一个绝对时间,也就是说,不管你在哪个时区,Date都是一样的,都是从1970年1月1日0点0分GMT时间起,到目前这一刻的毫秒数。所以,你第一段代码和第二段代码里面,得到的date对象所代表的时间其实是一样的。
而日历是人们对绝对时间的一种描述方法,例如某年某月某日几时几分几秒,这,随着你当前所处的时区和地区而不同。
你在观察date对象的时候,你肯定没有去看它的毫秒数,而是先把毫秒数转换成一个日历。你没有写出你是怎么把date转换成日历的,但假如你是用默认的Date.toString()的话,那么,这是根据当前的默认时区来把毫秒数转换成日历的。因此,你在第一段代码里没有修改默认时区,得到的还是北京时间。而在第二段代码里,因为修改了默认时区,所以虽然绝对时间没有变化,但是你转换得到的日历不一样了。
其实,如果你是要获取当前时间,那么直接用new Date()就可以了,跟你先创建一个Calendar对象,再指定一个时区后获取的date是完全一样的。只有在你需要把一个date用日历来表示的时候,才需要用到Calendar和TimeZone。
Date的toString(),可以看下源码
public String toString() {
// "EEE MMM dd HH:mm:ss zzz yyyy";
BaseCalendar.Date date = normalize();
StringBuilder sb = new StringBuilder(28);
int index = date.getDayOfWeek();
if (index == BaseCalendar.SUNDAY) {
index = 8;
}
convertToAbbr(sb, wtb[index]).append(' '); // EEE
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
TimeZone zi = date.getZone();//这行
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
} else {
sb.append("GMT");
}
sb.append(' ').append(date.getYear()); // yyyy
return sb.toString();
}