13.5. 日期时间相关类

13.5.1. Date类

Date的基本用法

package Data_class;

import java.util.Date;

public class simaple01 {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date.getYear() + 1900);
        System.out.println(date.getMonth() + 1); // 0~11,必须加上1
        System.out.println(date.getDate()); // 1~31,不能加1

        // 转换为String:
        System.out.println(date.toString());
        // 转换为GMT时区:
        System.out.println(date.toGMTString());
        // 转换为本地时区:
        System.out.println(date.toLocaleString());
    }
}


/**
 *
 * 注意getYear()返回的年份必须加上1900,getMonth()返回的月份是0~11分别表示1~12月,所以要加1,而getDate()返回的日期范围是1~31,又不能加1。
 2020
 7
 1
 Wed Jul 01 09:45:31 CST 2020
 1 Jul 2020 01:45:31 GMT
 2020-7-1 9:45:31
 **/

代码示例

package com.a51work6;

import java.util.Date;

public class Hellowrld {
 public static void main(String[] args) {
  Date now = new Date();
  System.out.println("now = "+ now);
  System.out.println("now.getTime() = " + now.getTime());
  System.out.println();

  Date date = new Date(1234567890123L);
  System.out.println("date = "+ date);

  // 测试now和date日期
  display(now, date);

  // 重新设置日期time
  date.setTime(9999999999999L);
  System.out.println("修改之后的date = " + date);

  // 重新测试now和date日期
  display(now, date);
 }
  // 测试after、before和compareTo方法
  public static void display(Date now, Date date) {
  System.out.println();
  System.out.println("now.after(date) = " + now.after(date));
  System.out.println("now.before(date) = " + now.before(date));
  System.out.println("now.compareTo(date) = " + now.compareTo(date));
  System.out.println();
 }

}

/*
now = Sun Sep 15 13:59:48 CST 2019
now.getTime() = 1568527188613

date = Sat Feb 14 07:31:30 CST 2009

now.after(date) = true
now.before(date) = false
now.compareTo(date) = 1

修改之后的date = Sun Nov 21 01:46:39 CST 2286

now.after(date) = false
now.before(date) = true
now.compareTo(date) = -1

*
*/

13.5.2. 日期格式化和解析

打印本地时区表示的日期和时间时,不同的计算机可能会有不同的结果。如果我们想要针对用户的偏好精确地控制日期和时间的格式,就可以使用SimpleDateFormat对一个Date进行转换。它用预定义的字符串表示格式化:

  • yyyy:年
  • MM:月
  • dd: 日
  • HH: 小时
  • mm: 分钟
  • ss: 秒

我们来看如何以自定义的格式输出:

package Data_class;

import java.text.*;
import java.util.*;


public class simple02 {
    public static void main(String[] args) {
        // 获取当前时间:
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");   //2020-07-01 09:52:59
//        SimpleDateFormat sdf = new SimpleDateFormat("E MMM dd, yyyy");      //星期三 七月 01, 2020
        System.out.println(sdf.format(date));
    }

}

代码示例

package com.a51work7;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class HelloWorld {
 public static void main(String[] args) throws ParseException {
  Date date = new Date(1234567890123L);
  System.out.println("格式化前date = "+ date);

  DateFormat df = new SimpleDateFormat();
  System.out.println("格式化后date = " + df.format(date));
  df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  System.out.println("格式化后date = " + df.format(date));

  String dateString = "2018-08-18 08:18:58";
  Date date1 = df.parse(dateString);
  System.out.println("从字符串获得日期对象 = "+ date1);
 }
}


/*
格式化前date = Sat Feb 14 07:31:30 CST 2009
格式化后date = 09-2-14 上午7:31
格式化后date = 2009-02-14 07:31:30
从字符串获得日期对象 = Sat Aug 18 08:18:58 CST 2018
*
*/

13.5.3. Calendar类

可以使用java.util.Calendar类, Calendar是一个抽象类,不能实例化,但是通过静态工厂方法getInstance()获得Calendar实例。

代码示例

package com.a51work6;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class Helloworld2 {
 public static void main(String[] args) throws ParseException {
// 获得默认的日历对象
  Calendar calendar = Calendar.getInstance();
// 设置日期2018年8月18日
  calendar.set(2018, 7, 18);
// 通过日历获得Date对象
  Date date = calendar.getTime();
  System.out.println("格式化前date = " + date);
  DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  System.out.println("格式化后date = " + df.format(date));
  System.out.println();
  calendar.clear();
// 设置日期2018年8月28日
  calendar.set(Calendar.YEAR, 2018);
  calendar.set(Calendar.MONTH, 7);
  calendar.set(Calendar.DATE, 28);
// 通过日历获得Date对象
  date = calendar.getTime();
  System.out.println("格式化前date = " + date);
  System.out.println("格式化后date = " + df.format(date));
 }
}

/*

格式化前date = Sat Aug 18 14:11:44 CST 2018
格式化后date = 2018-08-18

格式化前date = Tue Aug 28 00:00:00 CST 2018
格式化后date = 2018-08-28
*
*/

simple03.java

package Data_class;

import java.util.Calendar;

public class simple03 {
    public static void main(String[] args) {
        // 获取当前时间:
        Calendar c = Calendar.getInstance();
        int y = c.get(Calendar.YEAR);
        int m = 1 + c.get(Calendar.MONTH);
        int d = c.get(Calendar.DAY_OF_MONTH);
        int w = c.get(Calendar.DAY_OF_WEEK);
        int hh = c.get(Calendar.HOUR_OF_DAY);
        int mm = c.get(Calendar.MINUTE);
        int ss = c.get(Calendar.SECOND);
        int ms = c.get(Calendar.MILLISECOND);
        System.out.println(y + "-" + m + "-" + d + " " + w + " " + hh + ":" + mm + ":" + ss + "." + ms);    //2020-7-1 4 9:55:36.483
    }
}

Calendar只有一种方式获取,即Calendar.getInstance(),而且一获取到就是当前时间。如果我们想给它设置成特定的一个日期和时间,就必须先清除所有字段:

simple04.java

package Data_class;

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class simple04 {
    public static void main(String[] args) {
        // 当前时间:
        Calendar c = Calendar.getInstance();
        // 清除所有:
        c.clear();
        // 设置2019年:
        c.set(Calendar.YEAR, 2019);
        // 设置9月:注意8表示9月:
        c.set(Calendar.MONTH, 8);
        // 设置2日:
        c.set(Calendar.DATE, 2);
        // 设置时间:
        c.set(Calendar.HOUR_OF_DAY, 21);
        c.set(Calendar.MINUTE, 22);
        c.set(Calendar.SECOND, 23);
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(c.getTime()));    //2019-09-02 21:22:23
    }
}

13.5.4. TimeZone

CalendarDate相比,它提供了时区转换的功能。时区用TimeZone对象表示:

simpl05.java

package Data_class;

import java.util.Arrays;
import java.util.TimeZone;

public class simpl05 {
    public static void main(String[] args) {
        TimeZone tzDefault = TimeZone.getDefault(); // 当前时区
        TimeZone tzGMT9 = TimeZone.getTimeZone("GMT+09:00"); // GMT+9:00时区
        TimeZone tzNY = TimeZone.getTimeZone("America/New_York"); // 纽约时区
        System.out.println(tzDefault.getID()); // Asia/Shanghai
        System.out.println(Arrays.toString(TimeZone.getAvailableIDs()));    //// Asia/Shanghai, Asia/Chongqing, Asia/Hong_Kong, Asia/Macao, .
        System.out.println(tzGMT9.getID()); // GMT+09:00
        System.out.println(tzNY.getID()); // America/New_York
    }
}

要列出系统支持的所有ID,请使用TimeZone.getAvailableIDs()

有了时区,我们就可以对指定时间进行转换。例如,下面的例子演示了如何将北京时间2019-11-20 8:15:00转换为纽约时间:

simpl05.java

package Data_class;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

public class simpl05 {
    public static void main(String[] args) {
        // 当前时间:
        Calendar c = Calendar.getInstance();
        // 清除所有:
        c.clear();
        // 设置为北京时区:
        c.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        // 设置年月日时分秒:
        c.set(2019, 10 /* 11 */, 20, 8, 15, 0);
        // 显示时间:
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
        System.out.println(sdf.format(c.getTime()));
    }
}

Calendar也可以对日期和时间进行简单的加减:

simple05.java

package Data_class;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class simpl05 {
    public static void main(String[] args) {
        // 当前时间:
        Calendar c = Calendar.getInstance();
        // 清除所有:
        c.clear();
        // 设置年月日时分秒:
        c.set(2019, 10 /* 11 */, 20, 8, 15, 0);
        // 加5天并减去2小时:
        c.add(Calendar.DAY_OF_MONTH, 5);
        c.add(Calendar.HOUR_OF_DAY, -2);
        // 显示时间:
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = c.getTime();
        System.out.println(sdf.format(d));
        // 2019-11-25 6:15:00
    }
}

13.5.5. Java8新日期时间相关类

时间和日期

HelloWorld.java

package com.a51work8;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class HelloWorld {

 public static void main(String[] args) {
  // TODO 自动生成的方法存根
//  使用now方法獲得LocalDate對象
  LocalDate date1 = LocalDate.now();
  System.out.println("date1 = " + date1);

//  使用of方法獲得LocalDate對象2018-08-18
  LocalDate date2 = LocalDate.of(2018, 8, 18);
  System.out.println("date2 = " + date2);

//  使用now方法獲得LocalTime對象
  LocalTime time1 = LocalTime.now();
  System.out.println("time1 = " + time1);

//  使用of方法獲得LocalTime對象08:58:18
  LocalTime time2 = LocalTime.of(8, 58,18);
  System.out.println("time2 = " + time2);

//  使用now方法获得LocalDateTime对象
  LocalDateTime dateTime1 = LocalDateTime.now();
  System.out.println("dateTime1 = "+ dateTime1);

  // 使用of方法获得LocalDateTime对象2018-08-18T08:58:18
  LocalDateTime dateTime2 = LocalDateTime.of(2018, 8, 18, 8, 58, 18);
  System.out.println("dateTime2 = " + dateTime2);

 }

}

/*

date1 = 2019-09-15
date2 = 2018-08-18
time1 = 14:21:53.185
time2 = 08:58:18
dateTime1 = 2019-09-15T14:21:53.185
dateTime2 = 2018-08-18T08:58:18

*/

日期格式化和解析

HelloWorld9.java

package com.a51work6;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class HelloWorld9 {
 public static void main(String[] args) {
  // 创建LocalDateTime对象
  LocalDateTime dateTime = LocalDateTime.now();
  System.out.println("dateTime格式化之前:" + dateTime);

  // 设置格式化类
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm:ss");
  String text = dateTime.format(formatter);
  System.out.println("dateTime 格式化之后:" + text);

  // 格式化字符串“2018-08-18 08:58:18”,返回LocalDateTime
  LocalDateTime parsedDateTime = LocalDateTime.parse("2018-08-18 08:58:18", formatter);
  System.out.println("LocalDateTime解析之后:" + parsedDateTime);

  ////创建LocalDate对象
  LocalDate date = LocalDate.now();
  System.out.println("date格式化之前:" + date);
  //重新设置格式化类
  formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  text = date.format(formatter);
  System.out.println("date格式化之后:" + text);
  //格式化字符串"2018-08-18",返回LocalDate对象
  LocalDate parsedDate = LocalDate.parse("2018-08-18", formatter);
  System.out.println("LocalDate解析之后:" + parsedDate);

  //// 创建LocalTime对象
  LocalTime time = LocalTime.now();
  System.out.println("time格式化之前:" + time);
  // 重新设置格式化类
  formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
  text = time.format(formatter);
  System.out.println("time格式化之后:" + text);
  // 格式化字符串"08:58:18",返回LocalTime对象
  LocalTime parsedTime = LocalTime.parse("08:58:18", formatter);
  System.out.println("LocalTime解析之后:" + parsedTime);

 }
}

/*
dateTime格式化之前:2019-09-15T14:35:16.639
dateTime 格式化之后:2019-09-15 14:35:16
LocalDateTime解析之后:2018-08-18T08:58:18
date格式化之前:2019-09-15
date格式化之后:2019-09-15
LocalDate解析之后:2018-08-18
time格式化之前:14:35:16.657
time格式化之后:14:35:16
LocalTime解析之后:08:58:18
*/

13.5.6. LocalDateTime

我们首先来看最常用的LocalDateTime,它表示一个本地日期和时间:

package Local_date;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        LocalDate d = LocalDate.now(); // 当前日期
        LocalTime t = LocalTime.now(); // 当前时间
        LocalDateTime dt = LocalDateTime.now(); // 当前日期和时间
        System.out.println(d); // 严格按照ISO 8601格式打印  //2020-07-01
        System.out.println(t); // 严格按照ISO 8601格式打印  //10:24:41.429
        System.out.println(dt); // 严格按照ISO 8601格式打印 //2020-07-01T10:24:41.429
    }
}
package Local_date;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
//        LocalDate d = LocalDate.now(); // 当前日期
//        LocalTime t = LocalTime.now(); // 当前时间
//        LocalDateTime dt = LocalDateTime.now(); // 当前日期和时间
//        System.out.println(d); // 严格按照ISO 8601格式打印  //2020-07-01
//        System.out.println(t); // 严格按照ISO 8601格式打印  //10:24:41.429
//        System.out.println(dt); // 严格按照ISO 8601格式打印 //2020-07-01T10:24:41.429


//        上述代码其实有一个小问题,在获取3个类型的时候,由于执行一行代码总会消耗一点时间,
//        因此,3个类型的日期和时间很可能对不上(时间的毫秒数基本上不同)。为了保证获取到同一时刻的日期和时间,可以改写如下:
        LocalDateTime dt = LocalDateTime.now(); // 当前日期和时间
        LocalDate d = dt.toLocalDate(); // 转换到当前日期
        LocalTime t = dt.toLocalTime(); // 转换到当前时间
        System.out.println(dt);
        System.out.println(d);
        System.out.println(t);

    }
}