当前位置: 主页 > JAVA语言

java时区转换 夏令时-墨西哥夏令时区和标准时区

发布时间:2023-06-01 09:14   浏览次数:次   作者:佚名

一、简介

全球一共分为24个时区,伦敦所在的时区称为标准时区,其他时区按东/西偏移的小时区分

北京所在的时区是东八区,GMT+08:00或者UTC+08:00表示东八区。

GMT和UTC可以认为基本是等价的,只是UTC使用更精确的原子钟计时,每隔几年会有一个闰秒,我们在开发程序的时候可以忽略两者的误差,因为计算机的时钟在联网的时候会自动与时间服务器同步时间。

Asia/Shanghai,表示上海所在地的时区。特别注意城市名称不是任意的城市,而是由国际标准组织规定的城市。

夏令时:所谓夏令时,就是夏天开始的时候,把时间往后拨1小时,夏天结束的时候java时区转换 夏令时,再把时间往前拨1小时,时间换算更加复杂。我们国家实行过一段时间夏令时,1992年就废除了,但美国到现在还在使用。 计算夏令时请使用标准库提供的相关类,不要试图自己计算夏令时。

在计算机中,通常使用Locale表示一个国家或地区的日期、时间、数字、货币等格式。

例如:(语言使用小写,国家使用大写)

要获取当前时间戳,可以使用System.currentTimeMillis(),这是Java程序获取时间戳最常用的方法。(计算机存储的当前时间,本质上只是一个不断递增的整数。 )

由于Java提供了新旧两套日期和时间的API,除非涉及到遗留代码,否则我们应该坚持使用新的API,新旧转换:博客地址

标准库API:

c datetime 时区转换_墨西哥夏令时区和标准时区_java时区转换 夏令时

​ Java标准库有两套处理日期和时间的API,为什么会有新旧两套API呢?因为历史遗留原因,旧的API存在很多问题,所以引入了新的API。

二、旧的Date体系

Date

​ java.util.Date是用于表示一个日期和时间的对象,注意与java.sql.Date区分,后者用在数据库中。如果观察Date的源码,可以发现它实际上存储了一个long类型的以毫秒表示的时间戳

private transient long fastTime;

基本用法:

// 获取当前时间:
Date date = new Date();
System.out.println(date.getYear() + 1900); // 必须加上1900
System.out.println(date.getMonth() + 1); // 0~11,必须加上1
System.out.println(date.getDate()); // 1~31,不能加1
// 转换为GMT时区:
System.out.println(date.toGMTString());
// 转换为本地时区:
System.out.println(date.toLocaleString());

SimpleDateFormat

​ 对 Date 数据使用预定义的字符串进行格式转换。

注意:(具体见 JDK 文档详细格式说明)

// 获取当前时间:
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(date));

java时区转换 夏令时_墨西哥夏令时区和标准时区_c datetime 时区转换

Date弊端

​ Date对象有几个严重的问题:它不能转换时区java时区转换 夏令时,除了toGMTString()可以按GMT+0:00输出外,Date总是以当前计算机系统的默认时区为基础进行输出。此外,我们也很难对日期和时间进行加减,计算两个日期相差多少天,计算某个月第一个星期一的日期等。

Calender

​ Calendar可以用于获取并设置年、月、日、时、分、秒,它和Date比,主要多了一个可以做简单的日期和时间运算的功能。注意到Calendar获取年月日这些信息变成了get(int field),返回的年份不必转换,返回的月份仍然要加1,返回的星期要特别注意,1~7分别表示周日,周一,……,周六。

​ 利用Calendar.getTime()可以将一个Calendar对象转换成Date对象,然后就可以用SimpleDateFormat进行格式化了。

TimeZone:时区用TimeZone对象表示。

三、新的 LocalDateTime体系

墨西哥夏令时区和标准时区_java时区转换 夏令时_c datetime 时区转换

1、LocalDateTime

与之前的区别:

最后,新API的类型几乎全部是不变类型(和String类似),可以放心使用不必担心被修改。

java时区转换 夏令时_c datetime 时区转换_墨西哥夏令时区和标准时区

一些特性:

当前时间戳在java.time中以Instant类型表示,我们用Instant.now()获取当前时间戳,效果和System.currentTimeMillis()类似。(原此,本质上是一样的)

简单实现

public class Main {
    public static void main(String[] args) {
        LocalDate d = LocalDate.now(); // 当前日期
        LocalTime t = LocalTime.now(); // 当前时间
        LocalDateTime dt = LocalDateTime.now(); // 当前日期和时间
        System.out.println(d); // 严格按照ISO 8601格式打印
        System.out.println(t); // 严格按照ISO 8601格式打印
        System.out.println(dt); // 严格按照ISO 8601格式打印
}}

指定日期of()

LocalDateTime dt2 = LocalDateTime.of(2019, 11, 30, 15, 16, 17);
LocalDateTime dt3 = LocalDateTime.of(d2, t2);

按照默认格式(ISO 8601)解析parse()

LocalDateTime dt = LocalDateTime.parse("2019-11-19T15:16:17");
LocalDate d = LocalDate.parse("2019-11-19");
LocalTime t = LocalTime.parse("15:16:17");

DateTimeFormatter:自定义格式,用于输入或者输出均可。

c datetime 时区转换_墨西哥夏令时区和标准时区_java时区转换 夏令时

LocalDateTime日期增减

墨西哥夏令时区和标准时区_java时区转换 夏令时_c datetime 时区转换

LocalDateTime dt = LocalDateTime.of(2019, 10, 26, 20, 30, 59);
// 加5天减3小时:
LocalDateTime dt2 = dt.plusDays(5).minusHours(3);
System.out.println(dt2); // 2019-10-31T17:30:59
// 减1月:
LocalDateTime dt3 = dt2.minusMonths(1);
System.out.println(dt3); // 2019-09-30T17:30:59
// with
LocalDateTime dt2 = dt.withDayOfMonth(31);
// 本月最后1天:
LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
// 本月第1个周一(对于计算某个月第1个周日这样的问题,新的API可以轻松完成。)
LocalDate firstWeekday = LocalDate.now()
  .with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));

要判断两个LocalDateTime的先后,可以使用isBefore()、isAfter()方法,对于LocalDate和LocalTime类似:

Boolean b=LocalDate.now().isBefore(LocalDate.of(2019, 11, 19));

Duration和Period

java时区转换 夏令时_墨西哥夏令时区和标准时区_c datetime 时区转换

​ 注意到两个LocalDateTime之间的差值使用Duration表示,类似PT1235H10M30S,表示1235小时10分钟30秒。而两个LocalDate之间的差值用Period表示,类似P1M21D,表示1个月21天。

Duration和Period的表示方法也符合ISO 8601的格式,它以P…T…的形式表示

利用ofXxx()或者parse()方法也可以直接创建Duration:

(用作时间单位嘛,这我之前接触过!)

Duration d1 = Duration.ofHours(10); // 10 hours
Duration d2 = Duration.parse("P1DT2H3M"); //1day,2hours,3 minutes

2、ZonedDateTime

java时区转换 夏令时_墨西哥夏令时区和标准时区_c datetime 时区转换

ZonedDateTime:

// 默认时区
ZonedDateTime zbj = ZonedDateTime.now(); 
// 用指定时区获取当前时间,用到了 ZoneId。
ZonedDateTime z = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
// 另一种方式是通过给一个LocalDateTime附加一个ZoneId
LocalDateTime ldt = LocalDateTime.of(2019, 9, 15, 15, 16, 17);
ZonedDateTime zbj = ldt.atZone(ZoneId.of("Asia/Shanghai"));

// 以中国时区获取当前时间:
ZonedDateTime zbj = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
// 转换为东京时间:
ZonedDateTime z = zbj.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
// 转换为本地时间(十分简单)
z.toLocalDateTime();

要特别注意:

​ 时区转换的时候,由于夏令时的存在,不同的日期转换的结果很可能是不同的。涉及到时区时,千万不要自己计算时差,否则难以正确处理夏令时。

java时区转换 夏令时_墨西哥夏令时区和标准时区_c datetime 时区转换

3、DateTimeFormatter

旧SimpleDateFormat与新DateTimeFormatter对比:

简单使用

(注意使用方法,是谁包括了谁!)

墨西哥夏令时区和标准时区_c datetime 时区转换_java时区转换 夏令时