Java 时间日期处理,工作必用(建议收藏)

工作中经常会遇到对时间日期进行处理的业务,像日期类的API个人觉得不需要背,需要的时候去查资料就行。我整理了Java8之前及之后日期类常用的时间日期处理方法,方便工作需要时查找,觉得有用的朋友可以收藏。

在这里插入图片描述

一、日期格式化和解析

java.util.Date类

格式化操作

public void oldFormat(){Date now = new Date();//format yyyy-MM-ddSimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String date  = sdf.format(now);System.out.println(String.format("date format : %s", date));//format HH:mm:ssSimpleDateFormat sdft = new SimpleDateFormat("HH:mm:ss");String time = sdft.format(now);System.out.println(String.format("time format : %s", time));//format yyyy-MM-dd HH:mm:ssSimpleDateFormat sdfdt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String datetime = sdfdt.format(now);System.out.println(String.format("dateTime format : %s", datetime));
}

解析:字符串转日期格式

//已弃用
Date date = new Date("2021-01-26");
//替换为
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse("2021-01-26");

LocalDate、LocalTime、LocalDateTIme类

格式化:

public void newFormat(){//format yyyy-MM-ddLocalDate date = LocalDate.now();System.out.println(String.format("date format : %s", date));//format HH:mm:ssLocalTime time = LocalTime.now().withNano(0);System.out.println(String.format("time format : %s", time));//format yyyy-MM-dd HH:mm:ssLocalDateTime dateTime = LocalDateTime.now();DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String dateTimeStr = dateTime.format(dateTimeFormatter);System.out.println(String.format("dateTime format : %s", dateTimeStr));
}

解析:字符串转日期格式

LocalDate date = LocalDate.of(2021, 1, 26);
// 或
LocalDate date1 = LocalDate.parse("2021-01-26");
System.out.println(date);LocalDateTime dateTime = LocalDateTime.of(2021, 1, 26, 12, 12, 22);
// 或
LocalDateTime dateTime1 = LocalDateTime.parse("2021-01-26T12:12:22");
System.out.println(dateTime);LocalTime time = LocalTime.of(12, 12, 22);
// 或
LocalTime time1 = LocalTime.parse("12:12:22");
System.out.println(time);

二、日期对象转换

Date转LocalDate类

如果要将java.util.Date转换为java.time.LocalDate,可以使用以下步骤:

1)将java.util.Date转换为ZonedDateTime。

2)使用它的toLocalDate()方法从ZonedDateTime获取LocalDate。

Date date = new Date();
Instant instant = date.toInstant();
ZoneId zoneId = ZoneId.systemDefault();// atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
LocalDate localDate = instant.atZone(zoneId).toLocalDate();
System.out.println("Date = " + date);
System.out.println("LocalDate = " + localDate);

LocalDate转Date类

如果要将LocalDate转换回java.util.Date,可以使用以下步骤:

1)使用ZonedDateTime将LocalDate转换为Instant。

2)使用from()方法从Instant对象获取Date的实例

ZoneId zoneId = ZoneId.systemDefault();
LocalDate localDate = LocalDate.now();
ZonedDateTime zdt = localDate.atStartOfDay(zoneId);Date date = Date.from(zdt.toInstant());System.out.println("LocalDate = " + localDate);
System.out.println("Date = " + date);

三、日期间隔计算

java.util.Date类

 //算两个日期间隔多少天,计算间隔多少年,多少月方法类似String dates1 = "2022-08-23";String dates2 = "2022-02-26";SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");Date date1 = format.parse(dates1);Date date2 = format.parse(dates2);int day = (int) ((date1.getTime() - date2.getTime()) / (1000 * 3600 * 24));System.out.println(dates1 + "和" + dates2 + "相差" + day + "天");//结果:2022-08-23和2022-02-26相差178天

java.time.LocalDate类

//算两个日期间隔多少天,计算间隔多少年,多少月
LocalDate date1 = LocalDate.parse("2022-08-23");
LocalDate date2 = LocalDate.parse("2022-02-26");
Period period = Period.between(date1, date2);
System.out.println("date1 到 date2 相隔:"+ period.getYears() + "年"+ period.getMonths() + "月"+ period.getDays() + "天");
//打印结果是date1 到 date2 相隔:0年-5月-25天
//这里period.getDays()得到的天是抛去年月以外的天数,并不是总天数//如果要获取纯粹的总天数应该用下面的方法,toEpochDay返回距离1970年1月1日的天数的long值
long day = date1.toEpochDay() - date2.toEpochDay();
System.out.println(date1 + "和" + date2 + "相差" + day + "天");
//打印结果:2022-08-23和2022-02-26相差178天

Java8中引入了两个与日期相关的新类:

  • Period - 计算两个“日期”间隔的类
  • Duration - 计算两个“时间”间隔的类

Period 类与 Duration 类都是一段持续时间的概念,如果需要对比时间,它们就需要一个固定的时间值,所以就需要 LocalDate 类与 Instant 、LocalTime、LocalDateTime类来配合它们使用:

Period 对应使用 LocalDate ,它们的作用范围域都是日期(年/月/日)
Duration 对应使用 Instant、LocalTime、LocalDateTime,它们的作用范围域都是时间(天/时/分/秒/毫秒/纳秒)

Duration常用API:

在这里插入图片描述

LocalDateTime start = LocalDateTime.parse("2022-12-03T10:15:30");
LocalDateTime end = LocalDateTime.parse("2023-12-01T10:25:33");//between的用法是end-start的时间,若start的时间大于end的时间,则所有的值是负的
Duration duration = Duration.between(start, end);String timeString = duration.toString(); //此持续时间的字符串表示形式,使用基于ISO-8601秒*的表示形式,例如 PT8H6M12.345S
System.out.println("相差的天数="+duration.toDays());
System.out.println("相差的小时="+ duration.toHours());
System.out.println("相差的分钟="+duration.toMinutes());
System.out.println("相差的毫秒="+duration.toMillis());
System.out.println("相差的纳秒="+duration.toNanos());
System.out.println("timeString时间="+timeString);//isNegative返回Duration实例对象是否为负
System.out.println(Duration.between(start, end).isNegative());//false  end-start为正,所以此处返回false
System.out.println(Duration.between(end, start).isNegative());//true   start-end为负,所以此处返回true
System.out.println(Duration.between(start, start).isNegative());//false start-start为0,所以此处为false执行结果:
相差的天数=363
相差的小时=8712
相差的分钟=522730
相差的毫秒=31363803000
相差的纳秒=31363803000000000
timeString时间=PT8712H10M3S
false
true
false

Period常用API:

在这里插入图片描述

LocalDate start = LocalDate.of(2022,12,3);
LocalDate end = LocalDate.of(2023,12,1);
Period period = Period.between(start,end);
System.out.println("两个时间之间的差值  年:"+period.getYears()+",月:"+period.getMonths()+",日:"+period.getDays());结果:
两个时间之间的差值  年:0,月:11,日:28

ChronoUnit也可以计算两个单元之间的天数、月数或年数。

LocalDate start = LocalDate.of(2022,12,3);
LocalDate end = LocalDate.of(2023,12,1);
long day = ChronoUnit.DAYS.between(start , end );
System.out.println("相差天数:" + day);
long month= ChronoUnit.MONTHS.between(start , end );
System.out.println("相差月数:" + month);
long year= ChronoUnit.YEARS.between(start , end );
System.out.println("相差年数:" + year);// 结果:
相差天数:363
相差月数:11
相差年数:0

四、获取指定日期

java.util.Date类

下面仅以部分日期为例,其他单位(年、月、日、1/2 日、时等等)大同小异。

//一周后的日期
SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd");
Calendar ca = Calendar.getInstance();
ca.add(Calendar.DATE, 7);
Date d = ca.getTime();
String after = formatDate.format(d);
System.out.println("当前日期:" + formatDate.format(new Date()));
System.out.println("一周后日期:" + after);
//当前日期:2023-08-26
//一周后日期:2023-09-02SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//获取当前月第一天:
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, 1);
String first = format.format(c.getTime());
System.out.println("first day:" + first);//获取当前月最后一天
Calendar ca = Calendar.getInstance();
ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
String last = format.format(ca.getTime());
System.out.println("last day:" + last);//当年最后一天
Calendar currCal = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, currCal.get(Calendar.YEAR));
calendar.roll(Calendar.DAY_OF_YEAR, -1);
Date time = calendar.getTime();
System.out.println("last day:" + format.format(time));//first day:2023-08-01
//last day:2023-08-31
//last day:2023-12-31

java.time.LocalDate类

下面仅以部分日期为例,其他单位(年、月、日、1/2 日、时等等)大同小异。另外,这些单位都在 java.time.temporal.ChronoUnit 枚举中定义。

//一周后的日期
LocalDate localDate = LocalDate.now();
//方法1
LocalDate after = localDate.plus(1, ChronoUnit.WEEKS);
//方法2
LocalDate after2 = localDate.plusWeeks(1);
System.out.println("一周后日期:" + after);
System.out.println("一周后日期:" + after2);
//一周后日期:2023-09-02
//一周后日期:2023-09-02LocalDate today = LocalDate.now();
//获取当前月第一天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth());
// 取本月最后一天
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth());
//取下一天:
LocalDate nextDay = lastDayOfThisMonth.plusDays(1);
//当年最后一天
LocalDate lastDay = today.with(TemporalAdjusters.lastDayOfYear());
//2023年最后一个周日
LocalDate lastMondayOf2021 = LocalDate.parse("2023-12-31").with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));

五、时区

java.util.Date类

java.util.Date 对象实质上存的是 1970 年 1 月 1 日 0 点( GMT)至 Date 对象所表示时刻所经过的毫秒数。也就是说不管在哪个时区 new Date,它记录的毫秒数都一样,和时区无关。但在使用上应该把它转换成当地时间,这就涉及到了时间的国际化。
java.util.Date 本身并不支持国际化,需要借助 TimeZone。

// 北京时间:Sat Aug 26 14:52:29 CST 2023
Date date = new Date();SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 北京时区
bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
System.out.println("毫秒数:" + date.getTime() + ", 北京时间:" + bjSdf.format(date));
// 东京时区
SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo"));  // 设置东京时区
System.out.println("毫秒数:" + date.getTime() + ", 东京时间:" + tokyoSdf.format(date));
// 如果直接print会自动转成当前时区的时间
System.out.println(date);//毫秒数:1693032749431, 北京时间:2023-08-26 14:52:29
//毫秒数:1693032749431, 东京时间:2023-08-26 15:52:29
//Sat Aug 26 14:52:29 CST 2023

ZonedDateTime类

Java8引入了java.time.ZonedDateTime 来表示带时区的时间。它可以看成是 LocalDateTime + ZoneId。

//当前时区时间
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println("当前时区时间: " + zonedDateTime);//东京时间
ZoneId zoneId = ZoneId.of(ZoneId.SHORT_IDS.get("JST"));
ZonedDateTime tokyoTime = zonedDateTime.withZoneSameInstant(zoneId);
System.out.println("东京时间: " + tokyoTime);// ZonedDateTime 转 LocalDateTime
LocalDateTime localDateTime = tokyoTime.toLocalDateTime();
System.out.println("东京时间转当地时间: " + localDateTime);//LocalDateTime 转 ZonedDateTime
ZonedDateTime localZoned = localDateTime.atZone(ZoneId.systemDefault());
System.out.println("本地时区时间: " + localZoned);当前时区时间: 2023-08-26T14:55:47.669+08:00[Asia/Shanghai]
东京时间: 2023-08-26T15:55:47.669+09:00[Asia/Tokyo]
东京时间转当地时间: 2023-08-26T15:55:47.669
本地时区时间: 2023-08-26T15:55:47.669+08:00[Asia/Shanghai]

后续遇到常用的API会继续补充。。。

好了,看到了这里觉得有用的朋友们点个赞吧,博主整理资料还是很累的,需要一点正反馈。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/84124.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式事务-seata框架

文章目录 分布式事务0.学习目标1.分布式事务问题1.1.本地事务1.2.分布式事务1.3.演示分布式事务问题 2.理论基础2.1.CAP定理2.1.1.一致性2.1.2.可用性2.1.3.分区容错2.1.4.矛盾 2.2.BASE理论2.3.解决分布式事务的思路 3.初识Seata3.1.Seata的架构3.2.部署TC服务3.3.微服务集成S…

C++避坑——most vexing parse问题

1."坑"的问题是什么&#xff1f; 先看一段代码&#xff1a; class Functor { public:void operator()(){std::cout << "我是线程的初始函数" << std::endl;} };int main() {std::thread t(Functor());// 强制高速编译器这是一个构造函数!t.j…

前端进阶之———浏览器调试巧技

有幸的参加了一次腾讯的面试&#xff0c;被面试官问到了JS能不能在浏览器上import依赖已经遇到一个错误函数应该怎么解决。之前的经验是做一些简单的html&#xff0c;css样式调试以及他的报错信息&#xff0c;忽略了浏览器js调试的强大功能。觉得还是非常有必要的&#xff0c;很…

锁的相关策略

乐观锁vs悲观锁 指的不是具体的锁,是一个抽象的概念,描述的是锁的特性,描述的是一类锁 乐观锁 假设数据一般情况下不会产生并发冲突,所以在数据进行提交更新的时候,才会正式对数据是否产生并发冲突进行检测,如果发现并发冲突了,就让返回用户错误的信息,让用户决定如何去做.(…

从爬楼梯到斐波那契数列:解密数学之美

题目描述 我们来看看力扣的一道经典问题70. 爬楼梯 递归 假设n级台阶有climbStairs(n)种方法爬到楼梯顶。如果有n级台阶&#xff0c;如果第一次往上爬1级台阶&#xff0c;就会剩下n-1级台阶&#xff0c;这n-1级台阶就有climbStairs(n-1)种方法爬到楼梯顶&#xff1b;如果第一…

es的索引管理

概念 &#xff08;1&#xff09;集群&#xff08;Cluster&#xff09;&#xff1a; ES可以作为一个独立的单个搜索服务器。不过&#xff0c;为了处理大型数据集&#xff0c;实现容错和高可用性&#xff0c;ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。 &…

uniapp使用uni.chooseLocation()打开地图选择位置

使用uni.chooseLocation()打开地址选择位置&#xff1a; 在Uniapp源码视图进行设置 添加这个属性&#xff1a;"requiredPrivateInfos":["chooseLocation"] ​ </template><view class"location_box"><view class"locatio…

企业博客搭建:经营好企业博客,能让你的业务蹭蹭上涨!

企业博客本身作为企业产品知识的沉淀&#xff0c;搭建并且经营好企业博客不仅有利于企业文化建设&#xff0c;更可以利用博客来推动业务增长。 何谓企业博客营销&#xff1f;简单地说&#xff0c;就是利用HelpLook这种工具创建并开展网络营销活动&#xff0c;称之为博客营销。 …

CH02_重构的原则(什么是重构、为什么重构、何时重构)

什么是重构 重构&#xff08;名词&#xff09;&#xff1a;对软件内部结构的一种调整&#xff0c;目的是在不改变软件可观察行为的前提下&#xff0c;提高其可理解性&#xff0c;降低其修改成本。 重构&#xff08;动词&#xff09;&#xff1a;使用一系列重构手法&#xff0…

云原生之使用Docker部署SSCMS内容管理系统

云原生之使用Docker部署SSCMS内容管理系统 一、SSCMS介绍二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载SSCMS镜像五、部署SSCMS内容管理系统5.1 创建SSCMS容器5.2 检查SSC…

SpeedBI数据可视化工具:丰富图表,提高报表易读性

数据可视化工具一大作用就是能把复杂数据可视化、直观化&#xff0c;更容易看懂&#xff0c;也就更容易实现以数据驱动业务管理升级&#xff0c;因此一般的数据可视化工具都会提供大量图形化的数据可视化图表&#xff0c;以提高报表的易懂性&#xff0c;更好地服务企业运营决策…

【React基础全篇】

文章目录 一、关于 React二、脚手架2.1 create-react-app 脚手架的使用2.2 项目目录解析2.3 抽离配置文件2.4 webpack 二次封装2.4.1 集成 css 预处理器2.4.2 配置解析别名 2.5 setupProxy 代理 三、JSX3.1 jsx 语法详解3.2 React.createElement 四、组件定义4.1 类组件4.2 函数…