首先来聊聊冬夏令时
冬令时和夏令时是为了节约能源和充分利用光照资源而设立的时间制度。在夏季,许多国家和地区会将时钟拨快一小时,称为夏令时,以便让人们早起早睡,减少照明用电。而在冬季,时钟会拨回标准时间,称为冬令时。
历史背景和实施国家
夏令时的概念最早由新西兰昆虫学家George Vernon Hudson在1895年提出,但未得到广泛响应。1907年,英国建筑师威廉·维莱特向英国议会提出了夏令时的构思,但未被采纳。德国于1916年首次正式使用夏令时,随后英国、法国和俄罗斯也开始执行。目前,全世界有近110个国家每年实行夏令时。
中国的实施情况
中国在1986年至1991年间曾实行夏令时制度。具体做法是每年从4月中旬的第一个星期日起将时钟拨快一小时,称为夏令时开始;到9月中旬的第一个星期日再拨回一小时,称为夏令时结束。然而,自1992年起,中国暂停实行夏令时
java 中获取时区的方式
1指定时区,这种就会忽略夏令时 因为指定了 -4
TimeZone tz = TimeZone.getTimeZone("GMT-04:00");
2指定地点城市,会自动计算夏令时
TimeZone tz = TimeZone.getTimeZone("America/New_York");
以new york为例
2024年 11 月 3 号调整了冬令时, 时区由-4 调整为 -5
参考网站:
https://time.is/
我们来实际计算下 2024-11-02 13:00:00 的时区
public static void main(String[] args) throws ParseException {//1指定时区为纽约ZoneId newYorkZoneId = ZoneId.of("America/New_York");TimeZone tz = TimeZone.getTimeZone(newYorkZoneId);//初始化一个时间格式化,并指定纽约时区FastDateFormat format = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss", tz);//使用纽约时区,反序列化一个时间Date date = format.parse("2024-11-02 13:00:00");//获取时区ZonedDateTime pastTimeInNewYork = ZonedDateTime.ofInstant(date.toInstant(), newYorkZoneId);System.out.println("过去时间点的时区信息: " + pastTimeInNewYork.getOffset());}
上面结果输出为
过去时间点的时区信息: -04:00
当我们将反序列化的时间 修改为 11月3号,
可以看到这里同样是纽约, 3号的时区已经变为-5, 因为调整了冬令时
这样的话我们就可以得到某个城市,某个时刻的 具体时区,这样就可以 准确的进行时间转换, 比如我们是东八区, 没有冬夏令时, 我们需要将时间转换为纽约时间
拓展:
介绍下时间转换方法
/*** 将sourceDate转换成指定时区的时间** @param sourceDate* @param sourceTimezone sourceDate所在的时区* @param targetTimezone 转化成目标时间所在的时区* @return*/
public static Date convertTimezone(Date sourceDate, TimeZone sourceTimezone, TimeZone targetTimezone) {Calendar calendar = Calendar.getInstance();//原时间long sourceTime = sourceDate.getTime();calendar.setTimeZone(sourceTimezone);calendar.setTimeInMillis(sourceTime);//获取源时区的到UTC的时区差int sourceZoneOffset = calendar.get(Calendar.ZONE_OFFSET);//目标时区calendar.setTimeZone(targetTimezone);calendar.setTimeInMillis(sourceTime);//获取目标时区的到UTC的时区差int targetZoneOffset = calendar.get(Calendar.ZONE_OFFSET);long targetTime = sourceTime + targetZoneOffset - sourceZoneOffset;return new Date(targetTime);
}
请注意,上面的targetTimezonetimeZone一定要是 根据城市获取的,而不是固定偏移量的
TimeZone.getTimeZone("America/New_York")