失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【Java 8系列】Java日期时间的新主宰者:LocalDate LocalTime LocalDateTime ZonedDateTime

【Java 8系列】Java日期时间的新主宰者:LocalDate LocalTime LocalDateTime ZonedDateTime

时间:2023-09-12 10:12:44

相关推荐

【Java 8系列】Java日期时间的新主宰者:LocalDate LocalTime LocalDateTime ZonedDateTime

热门系列:

【Java 8系列】收集器Collector与工具类Collectors

【Java 8系列】Stream详解,看这一篇就够啦

【Java 8系列】Lambda 表达式,一看就废

【Java 8系列】Java开发者的判空利器 – Optional

程序人生,精彩抢先看

目录

1、前言

2、正文

2.1LocalDate、LocalTime、LocalDateTime

2.1.1 获取当前时间

2.1.2 获取当前时间毫秒数/时间戳

2.1.3 获取年、月、日与星期几

2.1.4设置自定义时间

2.1.5日期/时间替换成指定的日期/时间

2.1.6日期时间与字符串相互转换

2.1.7Date与LocalDateTime相互转换

2.1.8 获取偏移日期时间

2.2ZonedDateTime

2.3ZoneId

2.4Instant

2.5时间工具类

3、总结

1、前言

本系列一直在分享Java8的新增特性与API,今天和大家一起扒一扒Java的新时间类库:java.time;

之前我在往期博文:【Java编程系列】Java判断世界各时区的夏令时、冬令时中就有提到过,为什么现在不适用Date时间类,而改用java.time库中的时间类。答案很简单:就是多线程安全性问题!

2、正文

本文主要分享和举例一些常用的类,下面正式开整!!本篇的时间类,都是使用的ISO-8601日历系统时间

ISO-8601日历系统是当今世界上大多数地方使用的现代民用日历系统。它等效于多用的格里高利历系统,该系统在今天一直适用today年的规则。对于当今编写的大多数应用程序,ISO-8601规则完全适用。但是,任何利用历史日期并要求它们准确的应用程序都将发现ISO-8601方法不合适。

2.1LocalDate、LocalTime、LocalDateTime

注:以上3个类,在使用和功能上基本一样,只是所代表的对象不同,所以放在一起讲解!

LocalDate:是一个不可变的日期时间对象,代表一个日期,通常被视为年-月-日;此类是不可变的并且是线程安全的。LocalTime:是一个不可变的日期时间对象,代表一个时间,通常被视为时分秒。时间以纳秒精度表示;此类是不可变的并且是线程安全的。LocalDateTime:是一个不变的日期时间对象,代表一个日期时间,通常被视为年-月-日-时-分-秒。也可以访问其他日期和时间字段,例如,一年中的某天,一周中的某天和一周中的某周。时间以纳秒精度表示;此类是不可变的并且是线程安全的。

下面来看看常用的一些方法,三者取其一,咱们以LocalDateTime为例展开(举栗子一目了然,所以下面尽可能以代码形式讲解):

2.1.1 获取当前时间

public static void main(String[] args) {//获取当前时间LocalDateTime localDateTime = LocalDateTime.now();System.out.println("本地当前日期时间:"+localDateTime);System.out.println();//设置时区为美国纽约System.out.println("美国当前日期时间:"+LocalDateTime.now(ZoneId.of("America/New_York")));System.out.println();}

输出:

本地当前日期时间:-12-28T15:25:20.707美国当前日期时间:-12-28T02:25:20.708

2.1.2 获取当前时间毫秒数/时间戳

public static void main(String[] args) {//获取当前时间LocalDateTime localDateTime = LocalDateTime.now();System.out.println("本地当前日期时间:"+localDateTime);long millisecond = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();System.out.println("获取时间戳:"+millisecond/1000);System.out.println("获取毫秒数:"+millisecond);System.out.println();}

输出:

本地当前日期时间:-12-28T16:43:32.971获取时间戳:1609145012获取毫秒数:1609145012971

2.1.3 获取年、月、日与星期几

public static void main(String[] args) {//获取当前时间LocalDateTime localDateTime = LocalDateTime.now();System.out.println("本地当前日期时间:"+localDateTime);//获取年、月、日、星期几int year = localDateTime.getYear();System.out.println("获取年份(第一种方式):"+year);year = localDateTime.get(ChronoField.YEAR);System.out.println("获取年份(第二种方式):"+year);System.out.println();int month = localDateTime.getMonthValue();System.out.println("获取月份(第一种方式):"+month);month = localDateTime.getMonth().getValue();System.out.println("获取月份(第二种方式):"+month);month = localDateTime.get(ChronoField.MONTH_OF_YEAR);System.out.println("获取月份(第三种方式):"+month);System.out.println();int dayOfWeek = localDateTime.getDayOfWeek().getValue();System.out.println("获取星期几(第一种方式):"+dayOfWeek);dayOfWeek = localDateTime.get(ChronoField.DAY_OF_WEEK);System.out.println("获取星期几(第二种方式):"+dayOfWeek);System.out.println();int dayOfMonth = localDateTime.getDayOfMonth();System.out.println("获取本月当日(第一种方式):"+dayOfMonth);dayOfMonth = localDateTime.get(ChronoField.DAY_OF_MONTH);System.out.println("获取本月当日(第二种方式):"+dayOfMonth);System.out.println();int dayOfYear = localDateTime.getDayOfYear();System.out.println("获取本年当日(第一种方式):"+dayOfYear);dayOfYear = localDateTime.get(ChronoField.DAY_OF_YEAR);System.out.println("获取本年当日(第二种方式):"+dayOfYear);}

输出:

本地当前日期时间:-12-29T10:32:49.698获取年份(第一种方式):获取年份(第二种方式):获取月份(第一种方式):12获取月份(第二种方式):12获取月份(第三种方式):12获取星期几(第一种方式):2获取星期几(第二种方式):2获取本月当日(第一种方式):29获取本月当日(第二种方式):29获取本年当日(第一种方式):364获取本年当日(第二种方式):364

2.1.4设置自定义时间

public static void main(String[] args) {//设置自定义时间LocalDateTime tempTime = LocalDateTime.of(,11,28,15,00,01);System.out.println("自定义设置的日期时间:"+tempTime);System.out.println();//设置自定义日期LocalDate tempDate = LocalDate.of(,10,1);System.out.println("自定义设置的日期:"+tempDate);System.out.println();}

输出:

自定义设置的日期时间:-11-28T15:00:01自定义设置的日期:-10-01

2.1.5日期/时间替换成指定的日期/时间

这里会用到一个方法,adjustInto():将指定的时间对象调整为具有与此对象相同的日期和时间

public static void main(String[] args) {//获取当前时间LocalDateTime localDateTime = LocalDateTime.now();System.out.println("本地当前日期时间:"+localDateTime);System.out.println();//设置自定义时间LocalDateTime tempTime = LocalDateTime.of(,11,28,15,00,01);System.out.println("自定义设置的日期时间:"+tempTime);System.out.println();////设置自定义日期LocalDate tempDate = LocalDate.of(,10,1);System.out.println("自定义设置的日期:"+tempDate);System.out.println();//通过adjustInto方法实现日期转换//将指定的时间对象调整为具有与此对象相同的日期和时间localDateTime = (LocalDateTime)tempDate.adjustInto(localDateTime);tempTime = (LocalDateTime)tempDate.adjustInto(tempTime);System.out.println("转换后的localDateTime:"+localDateTime);System.out.println("转换后的tempTime:"+tempTime);System.out.println();}

输出:

本地当前日期时间:-12-28T15:30:20.609自定义设置的日期时间:-11-28T15:00:01自定义设置的日期:-10-01转换后的localDateTime:-10-01T15:30:20.609转换后的tempTime:-10-01T15:00:01

2.1.6日期时间与字符串相互转换

private static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";private static final String YYYYMMDD_HH_MM_SS = "yyyy/MM/dd HH:mm:ss";public static void main(String[] args) {//获取当前时间LocalDateTime localDateTime = LocalDateTime.now();System.out.println("本地当前日期时间:"+localDateTime);//日期与字符串相互转换//日期转字符串String dateTimeStr = localDateTime.format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));System.out.println("日期时间格式化成字符串后:"+dateTimeStr);//字符串转日期String convertTime = "/12/12 12:12:12";LocalDateTime convertLocalDateTime = LocalDateTime.parse(convertTime,DateTimeFormatter.ofPattern(YYYYMMDD_HH_MM_SS));System.out.println("由字符串转换成的日期时间为:"+convertLocalDateTime);}

输出:

本地当前日期时间:-12-29T10:43:45.295日期时间格式化成字符串后:-12-29 10:43:45由字符串转换成的日期时间为:-12-12T12:12:12

2.1.7Date与LocalDateTime相互转换

private static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";private static final String YYYYMMDD_HH_MM_SS = "yyyy/MM/dd HH:mm:ss";public static void main(String[] args) {//获取当前时间LocalDateTime localDateTime = LocalDateTime.now();System.out.println("本地当前日期时间:"+localDateTime);//Date转换成LocalDateTimeDate date = new Date();LocalDateTime date2LocalDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();System.out.println("Date转换成LocalDateTime后>>>>"+date2LocalDateTime);//LocalDateTime转换成DateDate localDateTime2Date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());System.out.println("LocalDateTime转换成Date后>>>>"+localDateTime2Date);System.out.println("格式化一下>>>>"+FastDateFormat.getInstance(YYYY_MM_DD_HH_MM_SS).format(localDateTime2Date));}

输出:

本地当前日期时间:-12-29T11:02:16.883Date转换成LocalDateTime后>>>>-12-29T11:02:16.884LocalDateTime转换成Date后>>>>Tue Dec 29 11:02:16 CST 格式化一下>>>>-12-29 11:02:16

2.1.8 获取偏移日期时间

此处需要提一下,会常用的两个类似功能的方法:minus()plus()其中还有一些类似的指定方法,如:

下面列举几个常用栗子:

public static void main(String[] args) {//获取当前时间LocalDateTime localDateTime = LocalDateTime.now(ZoneId.systemDefault());System.out.println("本地当前日期时间:"+localDateTime);//获取偏移时间//偏移天(正数:往后偏移;负数:往过去时间偏移)System.out.println("明日此时:"+localDateTime.plusDays(1));System.out.println("明日此时1:"+localDateTime.minusDays(-1));System.out.println("前天此时:"+localDateTime.plusDays(-2));//偏移时System.out.println("当前时间后2个小时:"+localDateTime.plusHours(2));System.out.println("当前时间前5个小时:"+localDateTime.plusHours(-5));//偏移年System.out.println("去年此时:"+localDateTime.plusYears(-1));//偏移月System.out.println("下月此时:"+localDateTime.plusMonths(1));//偏移周System.out.println("上周此时:"+localDateTime.plusWeeks(-1));}

输出:

本地当前日期时间:-12-29T11:22:24.914明日此时:-12-30T11:22:24.914明日此时1:-12-30T11:22:24.914前天此时:-12-27T11:22:24.914当前时间后2个小时:-12-29T13:22:24.914当前时间前5个小时:-12-29T06:22:24.914去年此时:-12-29T11:22:24.914下月此时:-01-29T11:22:24.914上周此时:-12-22T11:22:24.914

2.2ZonedDateTime

ZonedDateTime其实就是含有时区的LocalDateTime,其实就是LocalDateTime+ZoneId,其对照关系可以如图:

所以,其对应的功能基本与上述一致,因此不再赘述!

2.3ZoneId

ZoneId是时区ID类,主要包含了各时区信息!一般对时区没有要求的情况,我们会使用:

ZoneId.systemDefault()

来设置默认时区!

通过源代码查看,目前常用的时区映射关系有如下这些:

public static final Map<String, String> SHORT_IDS;/** * 当前为ZoneId源码,除了 * 以下中文注释为作者个人翻译而来,非源码注释**/static {Map<String, String> map = new HashMap<>(64);//"Australia/Darwin","澳洲/达尔文"map.put("ACT", "Australia/Darwin");//"Australia/Sydney","澳洲/悉尼"map.put("AET", "Australia/Sydney");//"America/Argentina/Buenos_Aires","美洲/阿根廷/布宜诺斯艾利斯"map.put("AGT", "America/Argentina/Buenos_Aires");//"Africa/Cairo","非洲/开罗"map.put("ART", "Africa/Cairo");//"America/Anchorage","美洲/安克雷奇"map.put("AST", "America/Anchorage");//"America/Sao_Paulo","美洲/圣保罗"map.put("BET", "America/Sao_Paulo");//"Asia/Dhaka","亚洲/达卡"map.put("BST", "Asia/Dhaka");//"Africa/Harare","非洲/哈拉雷"map.put("CAT", "Africa/Harare");//"America/St_Johns","美洲/圣约翰"map.put("CNT", "America/St_Johns");//"America/Chicago","美洲/芝加哥"map.put("CST", "America/Chicago");//"Asia/Shanghai","亚洲/上海"map.put("CTT", "Asia/Shanghai");//"Africa/Addis_Ababa","非洲/亚的斯亚贝巴"map.put("EAT", "Africa/Addis_Ababa");//"Europe/Paris","欧洲/巴黎"map.put("ECT", "Europe/Paris");//"America/Indiana/Indianapolis","美洲/印第安纳州/印第安纳波利斯"map.put("IET", "America/Indiana/Indianapolis");//"Asia/Kolkata","亚洲/加尔各答"map.put("IST", "Asia/Kolkata");//"Asia/Tokyo","亚洲/东京"map.put("JST", "Asia/Tokyo");//"Pacific/Apia","太平洋/阿皮亚"map.put("MIT", "Pacific/Apia");//"Asia/Yerevan","亚洲/埃里温"map.put("NET", "Asia/Yerevan");//"Pacific/Auckland","太平洋/奥克兰"map.put("NST", "Pacific/Auckland");//"Asia/Karachi","亚洲/卡拉奇"map.put("PLT", "Asia/Karachi");//"America/Phoenix","美洲/凤凰城"map.put("PNT", "America/Phoenix");//"America/Puerto_Rico","美洲/波多黎各"map.put("PRT", "America/Puerto_Rico");//"America/Los_Angeles","美洲/洛杉矶"map.put("PST", "America/Los_Angeles");//"Pacific/Guadalcanal","太平洋/瓜达尔卡纳尔岛"map.put("SST", "Pacific/Guadalcanal");//"Asia/Ho_Chi_Minh","亚洲/胡志明市"map.put("VST", "Asia/Ho_Chi_Minh");//"-05:00","东部标准时间"(纽约、华盛顿)map.put("EST", "-05:00");//"-07:00","山地标准时间"map.put("MST", "-07:00");//"-10:00","夏威夷-阿留申标准时区"map.put("HST", "-10:00");SHORT_IDS = Collections.unmodifiableMap(map);}

举个栗子:

System.out.println("美国纽约当前日期时间:"+LocalDateTime.now(ZoneId.of("America/New_York")));//输出:美国纽约当前日期时间:-12-29T04:10:53.257

2.4Instant

Instant类,是包含时间线上的某一个瞬时点。

举个栗子:

public static void main(String[] args) {//获取当前时间LocalDateTime localDateTime = LocalDateTime.now(ZoneId.systemDefault());System.out.println("本地当前日期时间戳:"+localDateTime.atZone(ZoneId.systemDefault()).toEpochSecond());System.out.println();Instant instant = Instant.from(localDateTime.atZone(ZoneId.systemDefault()).plusHours(-1));System.out.println("前一小时此时的时间戳:"+instant.getEpochSecond());System.out.println("前一小时此时的毫秒数:"+instant.toEpochMilli());}

输出:

本地当前日期时间戳:1609235707//刚好相差3600秒前一小时此时的时间戳:1609232107前一小时此时的毫秒数:1609232107078

2.5时间工具类

/*** Date工具类* @author Yangy*/public class DateUtils {private static final ZoneId ZONE_ID = ZoneId.systemDefault();/*** LocalDateTime转化为Date* * @param localDateTime* @return*/public static Date toDate(LocalDateTime localDateTime) {return Date.from(localDateTime.atZone(ZONE_ID).toInstant());}/*** LocalDateTime转化为Date* * @param localDateTime* @return*/public static Date toDate(LocalDate localDate) {return Date.from(localDate.atStartOfDay(ZONE_ID).toInstant());}/*** Date转化为LocalDateTime* * @param date* @return*/public static LocalDateTime toLocalDateTime(Date date) {return LocalDateTime.ofInstant(date.toInstant(), ZONE_ID);}/*** LocalDate转化为LocalDateTime* * @param localDate* @return*/public static LocalDateTime toLocalDateTime(LocalDate localDate) {return LocalDateTime.of(localDate, LocalTime.MIN);}/*** Date转化为LocalDate* * @param date* @return*/public static LocalDate toLocalDate(Date date) {return date.toInstant().atZone(ZONE_ID).toLocalDate();}/*** Date转化为字符串* * @param date* @param formatter* @return*/public static String format(Date date, DateFormatter formatter) {LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZONE_ID);return formatter.getDateTimeFormatter().format(localDateTime);}/*** 字符串转化为Date* * @param text* @param formatter* @return*/public static Date parse(String text, DateFormatter formatter) {return formatter.parse(text);}public static enum DateFormatter {/*** 格式yyyy**/YEAR_FORMATTER(DateTimeFormatter.ofPattern("yyyy", Locale.CHINA)) {@Overridepublic Date parse(String text) {Year year = Year.parse(text, dateTimeFormatter);return Date.from(year.atDay(1).atStartOfDay(ZONE_ID).toInstant());}},/*** * 格式yyyy-MM**/YEAR_MONTH_FORMATTER(DateTimeFormatter.ofPattern("yyyy-MM", Locale.CHINA)) {@Overridepublic Date parse(String text) {YearMonth yearMonth = YearMonth.parse(text, dateTimeFormatter);return Date.from(yearMonth.atDay(1).atStartOfDay(ZONE_ID).toInstant());}},/*** * 格式yyyy-MM-dd* * @author Val Song Dec 17, 7:26:25 PM**/DATE_FORMATTER(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.CHINA)) {@Overridepublic Date parse(String text) {LocalDate localDate = LocalDate.parse(text, dateTimeFormatter);return Date.from(localDate.atStartOfDay(ZONE_ID).toInstant());}},/*** 格式yyyy-MM-dd HH:mm:ss**/DATE_TIME_FORMATTER(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA)) {@Overridepublic Date parse(String text) {LocalDateTime localDateTime = LocalDateTime.parse(text, dateTimeFormatter);return Date.from(localDateTime.atZone(ZONE_ID).toInstant());}},/*** 格式yyyyMMdd_HHmmss**/YYYYMMDD_HHMMSS_FORMATTER(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss", Locale.CHINA)) {@Overridepublic Date parse(String text) {LocalDateTime localDateTime = LocalDateTime.parse(text, dateTimeFormatter);return Date.from(localDateTime.atZone(ZONE_ID).toInstant());}};protected DateTimeFormatter dateTimeFormatter;private DateFormatter(DateTimeFormatter dateTimeFormatter) {this.dateTimeFormatter = dateTimeFormatter;}public DateTimeFormatter getDateTimeFormatter() {return dateTimeFormatter;}public abstract Date parse(String text);}}

3、总结

1.切记,LocalDate、LocalTime、LocalDateTime这几个类,都是没有设置时区的日期时间类,所以,对时区有要求的时候,必须手动设置指定时区;否则,采用默认时区即可

2.除了国内,世界其他很多地区都有夏冬令时的区分!所以,业务针对时区和夏冬令时有区别的,需要注意这一点!

最后,希望此文如果对你有帮助的话,请点赞、留言、关注我吧!

扫描左侧二维码,即可查看作者公众号内的更多精彩内容,先感谢各位朋友的支持啦!!!

如果觉得《【Java 8系列】Java日期时间的新主宰者:LocalDate LocalTime LocalDateTime ZonedDateTime》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。