您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

Java好用的时间类,别再用Date了

时间:2022-08-30 14:37:29  来源:今日头条  作者:没有烦恼的河豚

前言

假设你想获取当前时间,那么你肯定看过这样的代码

public static void mAIn(String[] args) {

    Date date = new Date(System.currentTimeMillis());
    System.out.println(date.getYear());
    System.out.println(date.getMonth());
    System.out.println(date.getDate());
}

获取年份,获取月份,获取..日期?
运行一下

121
9
27

怎么回事?获取年份,日期怎么都不对,点开源码发现

/**
 * Returns a value that is the result of subtracting 1900 from the
 * year that contains or begins with the instant in time represented
 * by this <code>Date</code> object, as interpreted in the local
 * time zone.
 *
 * @return  the year represented by this date, minus 1900.
 * @see     JAVA.util.Calendar
 * @deprecated As of JDK version 1.1,
 * replaced by <code>Calendar.get(Calendar.YEAR) - 1900</code>.
 */
@Deprecated
public int getYear() {
    return normalize().getYear() - 1900;
}

原来是某个对象值 减去了 1900,注释也表示,返回值减去了1900,难道我们每次获取年份需要在 加上1900?注释也说明了让我们 用Calendar.get()替换,并且该方法已经被废弃了。点开getMonth()也是一样,返回了一个0到11的值。getDate()获取日期?不应该是getDay()吗?老外的day都是sunday、monday,getDate()才是获取日期。再注意到这些api都是在1.1的时候被废弃了,私以为是为了消除getYear减去1900等这些歧义。收~

Calendar 日历类

public static void main(String[] args) {

    Calendar calendar =  Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int dom = calendar.get(Calendar.DAY_OF_MONTH);
    int doy = calendar.get(Calendar.DAY_OF_YEAR);
    int dow = calendar.get(Calendar.DAY_OF_WEEK);
    int dowim = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH);
    System.out.println(year+"年"+ month+"月");
    System.out.println(dom+"日");
    System.out.println(doy+"日");
    System.out.println(dow+"日");
    System.out.println(dowim);
}

打印(运行时间2021年10月27日 星期三 晴)

2021年9月
27日
300日
4日
4

问:月份怎么是上个月的?
答:是为了计算方便,约是0到11之间的值。
问:计算方便?
答:比如月份从1月开始,增加一个月,12月+1=13,没有13月。假设区域,(12+1)%12=1 正好为1月,那11月增加一个月,(11+1)%12=0,这就有问题了。所以为了计算方便1月,返回了0值。date.getMonth()也是一个道理。 问:那下面的DAY_OF_XXX 又是什么意思?
答:猜!根据结果猜。
Calendar.DAY_OF_MONTH 在这个月 的这一天
Calendar.DAY_OF_YEAR 在这一年 的这一天
Calendar.DAY_OF_WEEK 在这一周 的这一天

Calendar.DAY_OF_WEEK_IN_MONTH 在这一个月 这一天在 第九周
到这里 Calendar.DAY_OF_WEEK 为什么是 4 ,你肯定也猜到了
Calendar.HOUR
Calendar.HOUR_OF_DAY
Calendar.SECOND
...其他的 你肯定也会用了

LocalDate 本地日期类

LocalDate localDate = LocalDate.now();
System.out.println("当前日期:"+localDate.getYear()+" 年 "+localDate.getMonthValue()+" 月 "+localDate.getDayOfMonth()+"日" );

//结果
当前日期:2021 年 10 月 27日

也可以通过 LocalDate.of(年,月,日)去构造

LocalDate pluslocalDate = localDate.plusDays(1);//增加一天
LocalDate pluslocalDate = localDate.plusYears(1);//增加一年

其他api

LocalDate.isBefore(LocalDate);
LocalDate.isAfter();
LocalDate.isEqual();

也就是对两个日期的判断,是在前、在后、或者相等。

LocalTime 本地时间类

LocalTime localTime = LocalTime.now();
System.out.println("当前时间:"+localTime.getHour()+"h "+localTime.getSecond()+"m "+localTime.getMinute()+"s" );

LocalDate和LocalTime 都有类似作用的api
LocalDate.plusDays(1) 增加一天
LocalTime.plusHours(1) 增加一小时 等等~
其他api

LocalTime.isBefore(LocalTime);
LocalTime.isAfter();

对两个时间的判断。肯定碰到过一个需求,今天离活动开始时间还剩多少天。

LocalDateTime 本地日期时间类

public final class LocalDateTime ...{
    
    private final LocalDate date;

    private final LocalTime time;
}

LocalDateTime = LocalDate + LocalTime 懂得都懂

Instant 类

Instant 是瞬间,某一时刻的意思

Instant.ofEpochMilli(System.currentTimeMillis())
Instant.now()

通过Instant可以创建一个 “瞬间” 对象,ofEpochMilli()可以接受某一个“瞬间”,比如当前时间,或者是过去、将来的一个时间。
比如,通过一个“瞬间”创建一个LocalDateTime对象

LocalDateTime now = LocalDateTime.ofInstant(
    Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.systemDefault());

System.out.println("当前日期:"+now.getYear()+" 年 "+now.getMonthValue()+" 月 "+now.getDayOfMonth()+"日" );

Period 类

Period 是 时期,一段时间 的意思
Period有个between方法专门比较两个 日期 的

LocalDate startDate = LocalDateTime.ofInstant(
    Instant.ofEpochMilli(1601175465000L), ZoneId.systemDefault()).toLocalDate();//1601175465000是2020-9-27 10:57:45
Period p  =  Period.between(startDate,  LocalDate.now());

System.out.println("目标日期距离今天的时间差:"+p.getYears()+" 年 "+p.getMonths()+" 个月 "+p.getDays()+" 天" );

//目标日期距离今天的时间差:1 年 1 个月 1 天

看一眼源码

public static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive) {
    return startDateInclusive.until(endDateExclusive);
}

public Period until(ChronoLocalDate endDateExclusive) {
    LocalDate end = LocalDate.from(endDateExclusive);
    long totalMonths = end.getProlepticMonth() - this.getProlepticMonth();  // safe
    int days = end.day - this.day;
    if (totalMonths > 0 && days < 0) {
        totalMonths--;
        LocalDate calcDate = this.plusMonths(totalMonths);
        days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
    } else if (totalMonths < 0 && days > 0) {
        totalMonths++;
        days -= end.lengthOfMonth();
    }
    long years = totalMonths / 12;  // safe
    int months = (int) (totalMonths % 12);  // safe
    return Period.of(Math.toIntExact(years), months, days);
}

他只接受两个LocalDate对象,对时间的计算,算好之后返回Period对象

Duration 类

Duration 是 期间 持续时间 的意思 上代码

LocalDateTime end = LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.systemDefault());
LocalDateTime start = LocalDateTime.ofInstant(Instant.ofEpochMilli(1601175465000L), ZoneId.systemDefault());
Duration duration = Duration.between(start, end);

System.out.println("开始时间到结束时间,持续了"+duration.toDays()+"天");
System.out.println("开始时间到结束时间,持续了"+duration.toHours()+"小时");
System.out.println("开始时间到结束时间,持续了"+duration.toMillis()/1000+"秒");

可以看到between也接受两个参数,LocalDateTime对象,源码是对两个时间的计算,并返回对象。

对象转换

再贴点api

//long -> LocalDateTime
LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault())

//String -> LocalDateTime
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime.parse("2021-10-28 00:00:00", dateTimeFormatter1);

//LocalDateTime -> long
LocalDateTime对象.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

//LocalDateTime -> String
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime对象.format(dateTimeFormatter1)

对象转换几乎都涵盖了,里面有个时区对象,这个一般用默认时区。

总结

用LocalDate、LocalTime、LocalDateTime代替了Date类。Date管日期,Time管时间
LocalDateTime = LocalDate + LocalTime
Period 只能用LocalDate
Duration 持续时间,所以LocalDate、LocalTime、LocalDateTime 都能处理
至于Calendar 日历类,这里面的api,都是针对日历的,比如这个月的第一天是星期几。
总体来说,都是api的使用,非常清晰,废弃date.getMonth()等,使用localDate.getMonthValue()来获取几月,更易理解,更易贴合使用。代码都贴在了Github上了



Tags:时间类   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
MySQL时间存储终极指南:选择最适合你的时间类型!
引言大家好,小米在这里!最近有很多小伙伴在群里问我一个问题:“MySQL数据库存储时间到底该用什么类型?”嗯哼,这可是一个技术派的好问题!时间在数据库中的存储可不是小菜一碟,所以...【详细内容】
2023-12-06  Search: 时间类  点击:(163)  评论:(0)  加入收藏
MySQL 时间类型用 datetime, timestamp 还是 integer?
从问题说起今天我们来探讨一个有意思的问题,先说场景: 这是一个做在线文档产品的业务,需要给用户展示文档的编辑记录,现在我们叫它【智能文档】。 智能文档会不定期给文档数据打...【详细内容】
2022-09-22  Search: 时间类  点击:(397)  评论:(0)  加入收藏
Java好用的时间类,别再用Date了
前言假设你想获取当前时间,那么你肯定看过这样的代码public static void main(String[] args) { Date date = new Date(System.currentTimeMillis()); System.out.prin...【详细内容】
2022-08-30  Search: 时间类  点击:(526)  评论:(0)  加入收藏
Java各个时间类总结归纳,最全一篇
前言本文主要针对Date、Calendar、Instant、LocalDate、LocalTime和LocalDateTime的使用做了介绍并进行了对比,同时对simpleDateFormat和simpleDateFormat进行了对比和介绍。...【详细内容】
2020-08-31  Search: 时间类  点击:(247)  评论:(0)  加入收藏
mysql数据库时间类型datetime、bigint、timestamp的查询效率比较 java互联网架构
数据库中可以用 datetime、bigint、timestamp 来表示时间,那么选择什么类型来存储时间比较合适呢?前期数据准备 通过程序往数据库插入 50w 数据 数据表:CREATE TABLE `users`...【详细内容】
2020-06-28  Search: 时间类  点击:(596)  评论:(0)  加入收藏
MySQL的5种时间类型的比较
DATETIME DATETIME 用于表示 年月日 时分秒,是 DATE 和 TIME 的组合,并且记录的年份(见上表)比较长久。 如果实际应用中有这样的需求,就可以使用 DATETIME 类型。1、DATETIME...【详细内容】
2019-12-10  Search: 时间类  点击:(542)  评论:(0)  加入收藏
java时间类型转换
Date类:1、Date类型转String类型(以时间格式1970-01-01 01:01:01为例)//yyyy-MM-dd HH:mm:ss表示24时间进制 SimpleDateFormat sDateFormat=new SimpleDateFormat("yyyy-MM-d...【详细内容】
2019-08-16  Search: 时间类  点击:(980)  评论:(0)  加入收藏
MySQL的五种日期和时间类型
MySQl中有多种表示日期和时间的数据类型。其中YEAR表示年份,DATE表示日期,TIME表示时间,DATETIME和TIMESTAMP表示日期和实践。它们的对比如下:YEAR ,字节数为1,取值范围为“1901&m...【详细内容】
2019-07-22  Search: 时间类  点击:(1091)  评论:(0)  加入收藏
▌简易百科推荐
Java 8 内存管理原理解析及内存故障排查实践
本文介绍Java8虚拟机的内存区域划分、内存垃圾回收工作原理解析、虚拟机内存分配配置,以及各垃圾收集器优缺点及场景应用、实践内存故障场景排查诊断,方便读者面临内存故障时...【详细内容】
2024-03-20  vivo互联网技术    Tags:Java 8   点击:(15)  评论:(0)  加入收藏
如何编写高性能的Java代码
作者 | 波哥审校 | 重楼在当今软件开发领域,编写高性能的Java代码是至关重要的。Java作为一种流行的编程语言,拥有强大的生态系统和丰富的工具链,但是要写出性能优异的Java代码...【详细内容】
2024-03-20    51CTO  Tags:Java代码   点击:(24)  评论:(0)  加入收藏
在Java应用程序中释放峰值性能:配置文件引导优化(PGO)概述
译者 | 李睿审校 | 重楼在Java开发领域,优化应用程序的性能是开发人员的持续追求。配置文件引导优化(Profile-Guided Optimization,PGO)是一种功能强大的技术,能够显著地提高Ja...【详细内容】
2024-03-18    51CTO  Tags:Java   点击:(26)  评论:(0)  加入收藏
Java生产环境下性能监控与调优详解
堆是 JVM 内存中最大的一块内存空间,该内存被所有线程共享,几乎所有对象和数组都被分配到了堆内存中。堆被划分为新生代和老年代,新生代又被进一步划分为 Eden 和 Survivor 区,...【详细内容】
2024-02-04  大雷家吃饭    Tags:Java   点击:(57)  评论:(0)  加入收藏
在项目中如何避免和解决Java内存泄漏问题
在Java中,内存泄漏通常指的是程序中存在一些不再使用的对象或数据结构仍然保持对内存的引用,从而导致这些对象无法被垃圾回收器回收,最终导致内存占用不断增加,进而影响程序的性...【详细内容】
2024-02-01  编程技术汇  今日头条  Tags:Java   点击:(70)  评论:(0)  加入收藏
Java中的缓存技术及其使用场景
Java中的缓存技术是一种优化手段,用于提高应用程序的性能和响应速度。缓存技术通过将计算结果或者经常访问的数据存储在快速访问的存储介质中,以便下次需要时可以更快地获取。...【详细内容】
2024-01-30  编程技术汇    Tags:Java   点击:(73)  评论:(0)  加入收藏
JDK17 与 JDK11 特性差异浅谈
从 JDK11 到 JDK17 ,Java 的发展经历了一系列重要的里程碑。其中最重要的是 JDK17 的发布,这是一个长期支持(LTS)版本,它将获得长期的更新和支持,有助于保持程序的稳定性和可靠性...【详细内容】
2024-01-26  政采云技术  51CTO  Tags:JDK17   点击:(90)  评论:(0)  加入收藏
Java并发编程高阶技术
随着计算机硬件的发展,多核处理器的普及和内存容量的增加,利用多线程实现异步并发成为提升程序性能的重要途径。在Java中,多线程的使用能够更好地发挥硬件资源,提高程序的响应...【详细内容】
2024-01-19  大雷家吃饭    Tags:Java   点击:(107)  评论:(0)  加入收藏
这篇文章彻底让你了解Java与RPA
前段时间更新系统的时候,发现多了一个名为Power Automate的应用,打开了解后发现是一个自动化应用,根据其描述,可以自动执行所有日常任务,说的还是比较夸张,简单用了下,对于office、...【详细内容】
2024-01-17  Java技术指北  微信公众号  Tags:Java   点击:(99)  评论:(0)  加入收藏
Java 在 2023 年仍然流行的 25 个原因
译者 | 刘汪洋审校 | 重楼学习 Java 的过程中,我意识到在 90 年代末 OOP 正值鼎盛时期,Java 作为能够真正实现这些概念的语言显得尤为突出(尽管我此前学过 C++,但相比 Java 影响...【详细内容】
2024-01-10  刘汪洋  51CTO  Tags:Java   点击:(78)  评论:(0)  加入收藏
站内最新
站内热门
站内头条