Java:Date类、Calendar类、java.time包的简单介绍,收藏他,就对了!!!


在这里插入图片描述

这日子呀真是过完一天就会少一天,那我们一生到底有多少个日子呢?如果不清楚,那么就让我们来了解一下__Java__当中的__时间、日期类__吧日期时间类在Java开发中得到了广泛的应用,今天有我这个帅气又迷人的大帅锅“thadqy”来给大家讲一讲这个时间、日期类吧!

Date类

Java给我们提供了Date类来处理时间以及日期。大家要注意哦,这儿的Date类是在__java.util包下__,而不是__java.sql包下的Date类__。

Date构造器

Date类给我们提供了六个构造器。不过,Java官方已经不再推荐其中的4个;如果使用不再推荐的构造器编译器会发出警告,还会影响程序性能和安全方面等。下面是仅剩的两个构造器:

  • Date() :改构造器代表生成当前时间的Date对象。并且,再底层调用了System.currentTimeMillis()以获得Long类型的日期参数

  • Date date1 = new Date();
    System.out.println(date1);
    
    //Fri Jul 03 16:53:55 CST 2020
    
  • Date(long date) :根据指定的long类型整数生成Date对象。构造器参数表示创建的Date对象与GMT1970年1月1日00:00:00之间的时间差,以毫秒作为计时单位

  • Date date2 = new Date(56354646);
    System.out.println(date2);
    
    //Thu Jan 01 23:39:14 CST 1970
    

Date类的方法

与Date类的构造器一样,它的方法大部分也已经过时。下面就是位数的几个方法:

  • boolean after(Date when) :测试该日期是否在指定日期when之后

  • Date date3 = new Date(System.currentTimeMillis() + 10);
    Date date4 = new Date();
    System.out.println(date3.after(date4));
    
    //true
    
  • boolean before(Date when) :测试改日期是否在指定日期when之前

  • Date date1 = new Date();
    Date date3 = new Date(System.currentTimeMillis() + 10);
    System.out.println(date1.before(date3));
    
    //true
    
  • long getTime() :返回改时间与GMT 1970年1月1日00:00:00之间的时间差,返回long类型的以毫秒为单位的时间

  • Date date = new Date();
    long timeMillis = date.getTime();
    System.out.println(timeMillis + " ms");
    
    //1593767166696 ms
    
  • void setTime(long time) :设置改Date对象时间

  • Date date = new Date();
    long timeMillis = date.getTime();
    Date date5 = new Date();
    date5.setTime(timeMillis);
    System.out.println(date5);
    
    //Fri Jul 03 17:16:16 CST 2020
    

Date类的实例

public class DateTest(){
    public static void main(String[] args){
        Date date1 = new Date(); // 获取当前时间
        Date date2 = new Date(System.currentTimeMillis() + 10); // 获取当前时间后的10秒
        System.out.println("当前时间:" + date1);
        System.out.println("当前时间后的10秒:" + date2);
        System.out.println(date1.compareTo(date2));
        System.out.println(date1.after(date2));
    }
}

//输出结构为:
//当前时间:Fri Jul 03 17:22:33 CST 2020
//当前时间后的10秒:Fri Jul 03 17:22:33 CST 2020
//-1
//false

总的来说,Java提供的Date类是一个对操作时间、日期并不高效、方便的类。因此Java官方并不推荐使用Date类。但是,如果你需要对时间、日期进行加减运算,获取指定的年、月、日、时、分、秒等信息应该怎么办呢?

在这里插入图片描述

不要慌张!!!,考虑到Date类的糟糕设计,又出现了Calendar工具类。我们可以使用Calendar类来完成一些Date类完不成的任务。

Calendar类

Calendar本身是一个抽象类,它是所有的日历类的模板,并提供一些所有日历通用的方法。Java给我们提供了一个Calendar的子类Gregorian Calendar类,他就是我们通常所说的公历。

Calendar对象的创建

因为Calendar是一个抽像类,所有Calendar不能用构造器来创建。但是Calendar提供了几个静态方法来获取Calendar类。如,getInstance()。

Calendar与Date

Calendar与Date都是用来表示时间日期的工具类。所以,Calendar与Date类是可以自由转换的。如下所示:

//创建Calendar对象
Calendar calendar = Calendar.getInstance();

//从Calendar对象中取出Date对象
Date date = calendat.getTime();

//通过Date获取Calendat对象,因为Calendar类没有构造函数可以接受Date对象,所以必须先获取Calendar实例,然后再通过setTime()方法
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date);

Calendar类的方法

  • void add(int field, int amount) :为给定的日历字段添加或减去指定的时间量

  • //给当前日期减去5天
    Calendar calendar = Calendar.getInstance();
    System.out.println("当前日期为:" + calendar.getTime());
    //减去5天
    calendar.add(calendar.DAY_OF_MONTH, -5);
    System.out.pringln("当前日期减去5天为:" + calendar.getTime());
    
    //当前日期为:Fri Jul 03 17:57:44 CST 2020
    //当前日期减去5天为:Sun Jun 28 17:57:44 CST 2020
    
  • void roll(int field, int amount) :与add()方法类是,但是有一点不同,就是roll再amount后如果超过最大值,也不会向上一位进位

  • Calendar calendar = Calendar.getInstance();
    calendar.set(2020, 7, 3, 18, 13, 25);
    System.out.println(calendar.getTime());
    calendar.roll(calendar.MONTH, 6);
    System.out.println(calendar.getTime());
    
    //Mon Aug 03 18:13:25 CST 2020
    //Mon Feb 03 18:13:25 CST 2020+
    
  • int getActualMaximum(int field) :返回指定日历字段的最大值。例如月,最大值为11

  • int maxMonth = calendar.getActualMaximum(calendar.MONTH);
    System.out.println("月份最大为:" + maxMonth);
    
    //月份最大为:11
    
  • int getActualMinimum(int field) :返回指定日历字段的最小值。例如,月,最小值为0

  • int miniMonth = calendar.getAtualMinimum(calendar.MONTH);
    System.out.println("月份最小为:" + miniMonth);
    
    //0
    
  • int get(int field) :返回指定日历字段的值

  • Calendar c = Calendar.getInstance();
    int day = c.get(c.DAY_OF_MONTH);
    System.out.println("当前为"+day+"日");
    
    //当前为3日
    
  • void set(int field, int value) :将给定的日历字段设置为给定的值

  • Calendar c1 = Calendar.getInstance();
    c1.set(c1.MONTH, 11);
    System.out.println(c1.get(c1.MONTH));
    
    //11
    
  • void set(int field, int month, int date) : 设置Calendar对象的年月日

  • Calendar c12 = Calendar.getInstance();
    c12.set(2000, 7, 20);
    System.out.println(c12.getTime());
    //Sun Aug 20 22:10:36 CST 2000
    
  • void set(int field, int month, int date, int hourofDay, int minute, int second) :设置Calendar对象的年月日时分秒

  • Calendar c = Calendar.getInstance();
    c.set(2000, 8, 20, 7, 25, 0);
    System.out.println(c.getTime());
    
    //Wed Sep 20 07:25:00 CST 2000
    

set()方法的延迟修改

Calendar类的set()方法在修改时具有延迟效果。这主要是因为:Calendar在修改字段时并没有立即修改,而是使用成员变量表将修改值记录下来。因此,Calendar类在修改时并未进行真实值的计算。下面举一个简单的例子:

public class LazyTest{
    public static void main(String[] args){
        Calendar cal = Calendar.getInstance();
		cal.set(2000, 7, 31); // 2000年8月31日
		
		//将月份修改为9月
		//如果立即修改,系统将会自动把cal调为10月1日
		cal.set(cal.MONTH, 8);

		System.out.println(cal.getTime()); // ①
		
		//设置DATE字段为5
		cal.set(cal.DATE, 5); // ②
		
		System.out.println(cal.getTime()); // ③
    }
}
在上面的代码中我们运行后得到输出结果为:
Sun Oct 01 22:32:06 CST 2000
__Thu Oct 05 22:32:06 CST 2000__
但是,当我们将第①行的代码注释掉后,我们在运行,就会发现得出的结果为:
__Tue Sep 05 22:38:45 CST 2000__

在这儿我们明显看到,结果是不一样的,这就是Calendar类的set()方法修改延迟带来的后果

在Java 8以后有新增了一个日期、时间包。这个包的出现又给我们操作日期、时间数据提供了遍历。那么接下来,就继续来看看这个__java.time包__下有什么神奇的方面。

java.time包

java.time包包含了几个常用的类。下面就来看看这类吧。

java.time包下的常用类

Clock类
  • 该类的实例用于查询当前时刻,可以使用储存的时区来解释当前时刻。
  • 同时,可以使用该类替代System.currentTimeMillis()方法和TimeZone.getDefault()。并且提供了跟多的方法来获取当前日期、时间。
  • 这个类是抽象类和不可变的,同时也是线程安全的。
Duration类
  • 该类代表持续时间,可以非常方便的获取一段时间。
  • 这个类是不可变的,同时也是线程安全的。
Instant类
  • 该类在时间线上建立单个瞬时点。这可能用于应用程序中记录事件的时间戳。
  • 该类提供了静态方法now()来获取当前时刻。
  • 提供静态方法now(Clock clock)方法来获取clock对象的时刻。
  • 同时还有minusXxx()方法在当前时刻的基础上减去一段时间,也提供了plusXxx()方法在当前时刻的基础上加上一段时间。
LocalDate类
  • 是一个不可变的日期时间对象,表示日期,通常是年月日。例如,值”2000年8月20日“可储存在LocalDate。该类不储存或表示时间或时区。它是日期的描述,用于生日。
  • 该类提供了静态方法now()获取当前日期
  • 提供了now(Clock clock)静态方法来获取clock对应的日期。
  • 还提供了minusXxx()、plusXxx()等方法在其日期基础上进行减、加
LocalTime类
  • 这个类是线程安全且不可变的
  • 该类代表一个时间,通常看作小时、分、秒,时间精度为纳秒。
  • 该类引用相等时,应使用equals()方法
  • 该类提供了静态方法now()获取当前时间
  • 提供了now(Clock clock)静态方法来获取clock对应的时间
  • 该类提供了minusXxx()方法在当前年份的基础上减去几小时、几分钟、几秒
  • 提供了plusXxx()方法在当前年份的基础上加上几小时、几分钟、几秒
LocalDateTime类
  • 该类是一个不可变的日期时间对象,代表日期时间,通常被视为年月日时分秒。时间精度为纳秒。例如,值“2000年8月20日12:45:123456789”可以储存在LocalDateTime
  • 该类引用相等时,应使用equals()方法
  • 这个类是线程安全且不可变的
  • 该类提供了静态方法now()获取当前时间
  • 提供了now(Clock clock)静态方法来获取clock对应的时间
  • 该类提供了minusXxx()方法在当前年份的基础上减去几年、几月、几日、几小时、几分钟、几秒
  • 提供了plusXxx()方法在当前年份的基础上加上几年、几月、几日、几小时、几分钟、几秒
MonthDay类
  • 该类代表月日, 例如,04-12
  • 使用静态方法now()、now(Clock clock)获取当前月日、和clock对象对应的月日
Year类
  • 该类仅代表年, 例如,2000
  • 使用静态方法now()、now(Clock clock)获取当前月日、和clock对象对应的年份
  • 使用minusYears()方法在当前年份的基础上减去几年
  • 使用plusYears()方法在当前年份的基础上加上几年
YearMonth类
  • 该类仅代表年月, 例如,2000-08
  • 使用静态方法now()、now(Clock clock)获取当前月日、和clock对象对应的年月
  • 使用minusXxx()方法在当前年份的基础上减去几年、几月
  • 使用plusXxx()方法在当前年份的基础上加上几年、几月
ZoneId类
  • 该类代表一个时区
ZoneDateTime
  • 该类代表一个时区化的日期、时间
DayOfWeek类

这是一个枚举类,定义了周日到周六的枚举值

Month类
  • 这是一个枚举类,定义了一月到十二月的枚举值

下面就用一个简单的程序来示范这些用法

代码示范

public class NewDatePackageTest{
    publc static void main(String[] args){
// 		获取当前Clock
		Clock clock = Clock.systemUTC();
		
//		通过Clock获取当前时刻
		Instant nowTime = clock.instant();
		System.out.println("当前时间为:" + nowTime);
		
//		获取clock对应的毫秒数,与System.currenTimeMillis()输出相同
		long millis = clock.millis();
		System.out.println("clock对应的毫秒数为:" + millis);
		System.out.println(System.currentTimeMillis());
		
		System.out.println("关于Duration的用法");
		Duration d = Duration.ofSeconds(6000);
		System.out.println("6000相当于" + d.toMinutes() + "分");
		System.out.println("6000相当于" + d.toHours() + "小时");
		System.out.println("6000相当于" + d.toDays() + "天");
		
//		在clock基础上增加6000秒,返回新的Clock
		Clock clock2 = Clock.offset(clock, d);
		
//		可以看到clock2与clock相差1小时40分钟
		System.out.println("当前时刻加6000秒为:" + clock2.instant());
		
		System.out.println("关于Instant用法");
		
//		获取当前时间
		Instant instant1 = Instant.now();
		System.out.println("当前时间为:" + instant1);
		
//		instant新增6000秒,返回新的Instant
		Instant instant2 = instant1.minusSeconds(6000);
		System.out.println("insatnt1增加6000秒为:" + instant2);
		
//		根据字符串解析Instant对象
//		Instant instant3 = Instant.parse("2014-02-23T10:12:35.3422");
//		System.out.println(instant3);
		
		System.out.println("关于LocalDate的方法");
		
//		获取当前年月日
		LocalDate localDate = LocalDate.now();
		System.out.println("当前日期为:" + localDate);
		
//		获取2014年的第146天
		localDate  = LocalDate.ofYearDay(2014, 146);
		System.out.println("2014年第146天日期为:" + localDate);
		
//		将日期设置为2014年5月21日 两种方法任选其一
//		localDate = LocalDate.of(2014, 5, 21);
		localDate = LocalDate.of(2014, Month.MAY, 21);
		System.out.println("设置日期为:" + localDate);
		
		System.out.println("关于LocalTime的方法");
//		获取当前时间
		LocalTime localTime = LocalTime.now();
		System.out.println("当前时间为:" + localTime);
//		LocalDate ld = LocalDate.now();
//		System.out.println(ld.toString() + " "+ localTime.toString());
		
//		设置为22点30分
		localTime = LocalTime.ofSecondOfDay(5503);
		System.out.println(localTime);
		
		System.out.println("关于LocalDateTime的用法");
//		获取当前日期、时间
		LocalDateTime localDateTime = LocalDateTime.now();
		System.out.println("当前时间为:" + localDateTime);
		
//		当前时间加上25小时3分钟
		LocalDateTime future = localDateTime.plusHours(25).plusMinutes(3);
		System.out.println("当前时间加上25小时3分钟为:" + future);
		
		System.out.println("关于Year、YearMonth、MonthDay");
//		获取当前年份
		Year year = Year.now();
		System.out.println("当前年份为:" + year);
		
//		当前年份再加5年
		year = year.plusYears(5);
		System.out.println("当前年份再加5年为:" + year);
		
//		根据指定当年的月份获取YearMonth
		YearMonth yearMonth =  year.atMonth(10);
		System.out.println("根据指定当年的月份获取YearMonth为:" + yearMonth);
		
//		当前年月再加5年、减3个月
		yearMonth = yearMonth.plusYears(5).minusMonths(3);
		System.out.println("当前年月再加5年、减3个月为:" + yearMonth);
		
//		获取当前月日
		MonthDay monthDay = MonthDay.now();
		System.out.println("获取当前月日为:" + monthDay);
		
//		设置为5月23日
		MonthDay monthDay2 = MonthDay.of(5, 23);
		System.out.println("将当前日期设置为5月23日:" + monthDay2);
    }
}

//输出结果为:
//关于Clock的用法
//当前时间为:2020-07-03T15:38:58.283744800Z
//clock对应的毫秒数为:1593790738327
//1593790738327
//关于Duration的用法
//6000相当于100分
//6000相当于1小时
6000相当于0天
//当前时刻加6000秒为:2020-07-03T17:18:58.330218700Z
//关于Instant用法
//当前时间为:2020-07-03T15:38:58.330537400Z
//insatnt1增加6000秒为:2020-07-03T13:58:58.330537400Z
//关于LocalDate的方法
//当前日期为:2020-07-03
//2014年第146天日期为:2014-05-26
//设置日期为:2014-05-21
//关于LocalTime的方法
//当前时间为:23:38:58.385770200
//01:31:43
//关于LocalDateTime的用法
//当前时间为:2020-07-03T23:38:58.385770200
//当前时间加上25小时3分钟为:2020-07-05T00:41:58.385770200
//关于Year、YearMonth、MonthDay
//当前年份为:2020
//当前年份再加5年为:2025
//根据指定当年的月份获取YearMonth为:2025-10
//当前年月再加5年、减3个月为:2030-07
//获取当前月日为:--07-03
//将当前日期设置为5月23日:--05-23

结语

今天关于Java的日期、时间类的介绍就到这里啦!多谢客官的支持。本人学识有限,万望大家海涵。同时对于文中有误之处,也希望大家之处。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值