zoukankan      html  css  js  c++  java
  • 6.4 Java 8的日期、时间类

    一、Date类——java.util.Date

    Date对象既包含时间也包含日期,但是由于Date类从JDK1.0就开始存在了,所以它大部分方法和构造器都显示过时了,不推荐使用。
    Date类提供了6个构造器,剩下2个构造器:
    (1)Date():生成一个代表当前日期时间的对象。该构造器在底层调用System.currentTimeMillis()获取long整数作为日期的参数。
    (2)Date(long date):根据long型整数生成一个Date对象,该构造器的参数表示的Date对象与GMT 1970年1月1日00:00:00之间的时间差,以毫秒作为计时单位。
    Date类未过时的方法:
    (1)boolean after(Date when):测试该日期在指定日期When之后
    (2)boolean before(Date when):测试该日期在指定日期When之前
    (3)long getTime():返回该时间对应的long型整数。以时间戳返回,单位为毫秒
    (4)void setTime(long time):设置该对象的时间

    import java.util.Date;
    public class DateTest
    {
    	public static void main(String[] args)
    	{
    		var d1=new Date();
    		//获取当前时间的后100ms
    		var d2=new Date(System.currentTimeMillis()+100);
    		System.out.println(d2);
    		System.out.println(d1.compareTo(d2));
    		System.out.println(d1.before(d2));
    	}
    }
    ---------- 运行Java捕获输出窗 ----------
    Thu Mar 12 11:40:03 CST 2020
    -1
    true
    
    输出完成 (耗时 0 秒) - 正常终止
    

    二、Calendar类

    由于Date类在设计上的一些缺陷,所以Java提供了Calendar类来更好地处理日期和时间。Calendar是一个抽象类,它用于表示日历。
    为了统一计时,全球通常选择最普及和最通用的日历:Gregorian Calendar,也就是介绍年份时最常用的“公元几年”。
    Calendar是一个抽象类,它是所有日历类的模板,并提供了一些日历中通用的方法;但它本身不能直接实例化,程序只能创建Calendar子类的实例,Java本身提供了GregorianCalendar类,一个代表格里高利日历的子类,它代表了我们通常所说的公历。
    当然也可以创建自己的Calendar子类,可以自己通过互联网查看Calendar各子类的源代码学习。
    Calendar类是一个抽象类,所以不能通过Calendar构造器来创建Calendar对象,但它提供了几个静态方法 getInstance()方法来获取Calendar对象,这些方法根据TimeZone,Locale类来获取特定的Calendar,如果不指定TimeZone,Locale ,则默认使用TimeZone,Locale来创建Calendar。
    Calendar类与Date类都是表示日期的工具类,它们可以直接自由转换:

    //创建一个Calendar实例
    var canlendar=Calendar.getInstance();
    //从Canlendar对象中取出Date对象
    var date=calendar.getTime();
    //通过Date对象获得Canlendar对象
    //因为Calendar/GregorianCalendar没有构造器可以接受Date对象
    //所以必须先获得一个Calendar实例,然后调用其setTime()方法
    var canlendar2=Calendar.getInstance();
    calendar2.setTime(date);
    

    Calendar提供了大量访问、修改日期时间的方法:
    (1)void add(int field,int amount):根据日历的规则给指定日历字段添加和减去指定时间量
    (2)int get(int field):获取指定日历字段的值
    (3)int getActualMaximum(int field):返回指定日历字段可能拥有的最大值。例如:月,最大值为11
    (4)int getActualMinimum(int field):返回指定日历字段可能拥有的最小值。例如:月,最大值为0
    (5)int roll(int field,int amount):与add()方法相似,区别在于加上amount后超过了该字段所能表示的最大范围,也并不会向上一个字段进位。
    (6)void set(int year,int month,int date):设置Calenar年月日三个字段的值。
    (7)void set(int year,int month,int date,int hourOfDay,int minute,int second):设置Calenar年月日时分秒6个字段的值。
    上面的方法都需要一个int类型的field参数,field是Calendar类的类变量,如Calendar.YEAR、Calendar.MONTH等。

    import java.util.*;
    import static java.util.Calendar.*;
    public class CalendarTest
    {
    	public static void main(String[] args)
    	{
    		var c = Calendar.getInstance();
    		// 取出年
    		System.out.println(c.get(YEAR));
    		// 取出月份
    		System.out.println(c.get(MONTH));
    		// 取出日
    		System.out.println(c.get(DATE));
    		// 分别设置年、月、日、小时、分钟、秒
    		c.set(2003, 10, 23, 12, 32, 23); //2003-11-23 12:32:23
    		System.out.println(c.getTime());
    		// 将Calendar的年前推1年
    		c.add(YEAR, -1); //2002-11-23 12:32:23
    		System.out.println(c.getTime());
    		// 将Calendar的月前推8个月
    		c.roll(MONTH, -8); //2002-03-23 12:32:23
    		System.out.println(c.getTime());
    
    
    		var cal1 = Calendar.getInstance();
    		cal1.set(2003, 7, 23, 0, 0, 0); // 2003-8-23
    		cal1.add(MONTH, 6); //2003-8-23 => 2004-2-23
    		System.out.println(cal1.getTime());
    
    
    		var cal2 = Calendar.getInstance();
    		cal2.set(2003, 7, 31, 0, 0, 0); // 2003-8-31
    		// 因为进位到后月份改为2月,2月没有31日,自动变成29日
    		cal2.add(MONTH, 6); // 2003-8-31 => 2004-2-29
    		System.out.println(cal2.getTime());
    
    
    		var cal3 = Calendar.getInstance();
    		cal3.set(2003, 7, 23, 0, 0, 0); //2003-8-23
    		// MONTH字段“进位”,但YEAR字段并不增加
    		cal3.roll(MONTH, 6); //2003-8-23 => 2003-2-23
    		System.out.println(cal3.getTime());
    
    
    		var cal4 = Calendar.getInstance();
    		cal4.set(2003, 7, 31, 0, 0, 0); //2003-8-31
    		// MONTH字段“进位”后变成2,2月没有31日,
    		// YEAR字段不会改变,2003年2月只有28天
    		cal4.roll(MONTH, 6); //2003-8-31 => 2003-2-28
    		System.out.println(cal4.getTime());
    	}
    }
    
    ---------- 运行Java捕获输出窗 ----------
    2020
    2
    12
    Sun Nov 23 12:32:23 CST 2003
    Sat Nov 23 12:32:23 CST 2002
    Sat Mar 23 12:32:23 CST 2002
    Mon Feb 23 00:00:00 CST 2004
    Sun Feb 29 00:00:00 CST 2004
    Sun Feb 23 00:00:00 CST 2003
    Fri Feb 28 00:00:00 CST 2003
    
    输出完成 (耗时 0 秒) - 正常终止
    

    1、add和roll的区别

    add(int field,int amount),add主要用于改变Calendar的特定字段的值。如果需要增加,则让amount为正,如果需要减少某字段的值,则让amount为负。
    add(int field,int amount)有两条规则:
    (1)当修改的字段超过了它允许的范围,会发生进位,则上一级字段增大。
    (2)如果下一级字段也需要改变,那么该字段会修正到变化最小的值。

    	cal2.set(2003, 7, 31, 0, 0, 0); // 2003-8-31
    	// 因为进位到后月份改为2月,2月没有31日,自动变成29日
    	cal2.add(MONTH, 6); // 2003-8-31 => 2004-2-29
    

    roll()的规则与add()不同:当被处理的字段超过它允许的范围,则上一级字段不会增大

    	cal3.set(2003, 7, 23, 0, 0, 0); //2003-8-23
    	// MONTH字段“进位”,但YEAR字段并不增加
    	cal3.roll(MONTH, 6); //2003-8-23 => 2003-2-23
    

    下一级处理规则与add()类似

    	cal4.set(2003, 7, 31, 0, 0, 0); //2003-8-31
    	// MONTH字段“进位”后变成2,2月没有31日,
    	// YEAR字段不会改变,2003年2月只有28天
    	cal4.roll(MONTH, 6); //2003-8-31 => 2003-2-28
    

    2、设置Calendar的容错性

    例如set()方法传入一个不合法的参数,比如MONTH字段设置为13

    import java.util.Calendar;
    import static java.util.Calendar.*;
    public class LenientTest
    {
    	public static void main(String[] args)
    	{
    		Calendar cal=Calendar.getInstance();
    		System.out.println(cal.getTime());//Thu Mar 12 21:16:52 CST 2020
    		//结果是YEAR增加1,MOMTH字段为1(2月)
    		cal.set(MONTH,13);
    		System.out.println(cal.getTime());//Fri Feb 12 21:16:52 CST 2021
    		//关闭容错性
    		cal.setLenient(false);
    		//导致运行时异常
    		cal.set(MONTH,13);
    		System.out.println(cal.getTime());
    
    	}
    }
    

    Calendar有两种解释日历字段的模式:lenient模式和non-lenient模式。当Calendar处于lenient模式时,每个字段可接受超出它允许范围的值;当Calendar处于non-lenient模式时,每个字段不可接受超出它允许范围的值,将会抛出异常;

    3、set()方法延迟修改

    set(f,value)方法将日历字段f更改为value,此外他还有一个内部成员变量,以指示日历字段f已被更改。尽管日历字段f是立即更改的,但该Calendar所代表的时间不会立即修改,直到下次调用get()getTime()getTimeMillis()add() oll()时才会重新计算日历时间,这被称作set()方法的延迟修改,采用延迟修改的优势是多次调用set()不会触发多次不必要的计算(需要计算出一个代表时间的long型整数)。

    import java.util.Calendar;
    import static java.util.Calendar.*;
    public class LazyTest
    {
    	public static void main(String[] args)
    	{
    		Calendar cal=Calendar.getInstance();
    		cal.set(2003,7,31);
    		//将年份设置为9,但9月31日不存在
    		//如果立即修改,系统会把cal自动调节到10,1
    		cal.set(MONTH,8);
    		//下面代码将输出10.1
    		//System.out.println(cal.getTime());//Wed Oct 01 21:29:39 CST 2003
    		cal.set(DATE,5);
    		System.out.println(cal.getTime());//Fri Sep 05 21:30:55 CST 2003
    	}
    }
    

    三、Java 8新增的日期、时间包——java.time

    具体这些类的用法查看API文档

  • 相关阅读:
    (网页)中的简单的遮罩层
    (后端)shiro:Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.
    (网页)jQuery的时间datetime控件在AngularJs中使用实例
    Maven Myeclipse 搭建项目
    MyBatis 环境搭建 (一)
    java 常用方法
    XML 基础
    JS BOM
    js 事件
    js 的使用原则
  • 原文地址:https://www.cnblogs.com/weststar/p/12468072.html
Copyright © 2011-2022 走看看