Java开发中的日期处理

268 阅读5分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

1. 时区(TimeZone)

时区就是指地理上根据经度划分的时区,处于不同的时区,对应的标准时间不一样,时区跨度较大时就会出现常见的倒时差现象。

1.1 时区编号

首先看一下常见的有关时区的符号

  • GMT:Greenwich Mean TIme,英国格林威治时间,即0经度线对应的标准时间
  • UTC:Coordinated Universal Time,世界协调时间,比GMT更为精确的世界时间
  • DST:Daylight Saving Time,夏令时,为了夏天充足的光照而将时间提前一个小时,北美欧洲等实行夏令时
  • EDT:Eastern Daylight Time,指美国东部夏令时间,纽约、华盛顿所处时区时间,与北京时间相差12小时
  • CST:四种时区的缩写都可以表示为CST,在国内CST特指中国标准时间
    • Central Standran Time(USA)UTC-6:00,美国中部标准时间
    • Central Standrad Time(Australia)UTC+9:30,澳大利亚标准时间
    • Cuba Standrad TIme UTC-4:00,古巴标准时间
    • China Standrad Time UTC+8:00,中国标准时间

1.2 Java程序中使用时区

Java中的时区相关类时java.util包中的TimeZone,可以查看时区相关信息和设置使用时区。

Date date = new Date();
System.out.println(date); //Tue Nov 09 21:19:52 CST 2021,中国标准时间

TimeZone.getAvailableIDs(); //获取所有时区对应ID,如GMT、UTC、CST等

System.out.println(TimeZone.getDefault());
//sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null]
//默认为上海时区,与GMT标准时间的相差毫秒数28800000=8小时

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(new Date()); //Tue Nov 09 13:26:03 UTC 2021

1.3 其他日期相关符号

除了时区以外,使用Java开发的过程中,还会碰到与日期、时间相关的符号有:

  • T:ISO 8601标准时间格式中规定的日期和时间之间的分隔符使用T
    • ISO 8601标准的日期格式为:yyyy-MM-dd
    • ISO 8601标准的时间格式为:HH:mm:ss:SSS
    • ISO 8601标准的日期+时间格式为:yyyy-MM-dd'T'HH:mm:ss:SSS
  • timestamp:时间戳,表示从1970年1月1日00:00:00至现在所经历的秒数,与时区无关

2. 日期和时间操作

了解时区和时间相关定义后,实际开发中最主要的就是对时间数值的相关操作。

2.1 获取时间

Java程序中的三种时间格式:

  • 标准格式:Java中带时区的时间格式,一般为Date对象创建时间格式
  • 时间戳:timestamp,即从1970至当前时间的秒数,在Java中是一个Long值
  • 字符串:使用最多的时间格式,通常可以根据自定义的格式来展示时间

Java程序中获取时间的方法有:

//获取当前标准时间
Date curDate = new Date();
System.out.println(curDate); //Tue Nov 09 13:58:22 UTC 2021
System.out.println(curDate.getTime()); //1636466302242,标准时间转成时间戳

//获取当前时间戳
Long timestamp = System.currentTimeMillis();
System.out.println(timestamp); //1636466302242
System.out.println(new Date(timestamp)); // Tue Nov 09 13:58:22 UTC 2021,根据时间戳创建标准时间

//定义时间格式字符串
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
System.out.println(format.format(curDate)); //2021/11/09 13:58:22:242,标准时间格式化
System.out.println(format.format(timestamp)); //2021/11/09 13:58:22:242 时间戳格式化

//根据格式字符串创建指定时间
Date date = format.parse("2022/02/11 12:00:25:123");
System.out.println(date); //Fri Feb 11 12:00:25 CST 2022

2.2 比较时间大小

对于Java中的时间进行比较时,如果时间类型是时间戳类型,在Java中作为long类型,可以直接通过时间戳的大小进行比较;而如果是标准的Java时间Date对象,则可以通过Date对象提供的before()和after()方法比较两个时间的大小。

Date lastDate = new Date();
Thread.sleep(1000);
Date nowDate = new Date();
System.out.println(lastDate.compareTo(nowDate)); //-1  相等时为0,小于时为-1,大于时为1
System.out.println(lastDate.before(nowDate)); //true
System.out.println(lastDate.after(nowDate)); //false

2.3 Java8中日期操作

由于java.util中的Date对象是可变的,以及SimpleDateFormat对象是线程不安全的,因此在Java8时又在java.time包中引入了更加安全好用的日期处理对象LocalDateTime等。

相比于之前的日期对象,Java8中新增的日期对象有:

  • 时区相关对象:ZoneId、ZoneOffset
  • 本地日期和时间对象:LocalDate、LocalTime、LocalDateTime
  • 带时区的日期时间对象:ZoneDateTime
  • 时刻对象:Instant
  • 时间格式化对象:DateTimeFormatter

相关使用方式如下操作

//默认时区
System.out.println(ZoneId.systemDefault()); //Asia/Shanghai

//获取当前时间
System.out.println(LocalDate.now()); //2021-11-09
System.out.println(LocalTime.now()); //22:41:13.561
System.out.println(LocalDateTime.of(LocalDate.now(),LocalTime.now())); //2021-11-09T22:41:13.561

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime); //2021-11-09T22:41:13.562
System.out.println(localDateTime.toLocalDate()); //2021-11-09
System.out.println(localDateTime.toLocalTime()); //22:41:13.562

System.out.println(Instant.now()); //2021-11-09T14:41:13.562Z  UTC时间

//格式化时间字符串
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss:SSS");
System.out.println(formatter.format(localDateTime)); //2021/11/09 22:48:05:338