java时间日期类

时间日期类

一、Date类

java.util.Date类封装当前的日期和时间,精确到毫秒,其中大部分方法都已过时

一)构造方法

方法描述
Date()根据当前的默认毫秒值创建日期对象
Date(long date)分配Date对象并初始化此对象,以表示自从标准基准时间以来的指定毫秒数
注意:标准基准时间也称为历元,即1970年1月1日00:00:00 GMT(注意时差)
// 分配一个 Date对象,并初始化,以便它代表它被分配的时间,精确到毫秒
Date d = new Date();
System.out.println(d);
// 格式;2022年9月13日 下午12:51:46   此方法已过期
System.out.println(d.toLocaleString()); 
// 分配一个 Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
long date = 1000*60*60;
Date d2 = new Date(date);
System.out.println(d2);

二)常用方法

方法描述
long getTime(); 获取当前时间,以毫秒为单位
void setTime(long time); 设置时间
boolean after(Date when)测试此日期是否晚于指定日期。
boolean before(Date when)测试此日期是否早于指定日期。
int compareTo(Date anotherDate)比较两个指定日期。
boolean equals(Object obj)比较两个相等的日期。
//1创建Date对象
//今天
Date d=new Date();
System.out.println(d.toLocaleString());
//昨天
Date d2=new Date(d.getTime()-(60*60*24*1000));
System.out.println(d2.toLocaleString());
//2方法after before
boolean b1=d.after(d2);
System.out.println(b1);
boolean b2=d.before(d2);
System.out.println(b2);

//比较 compareTo();
int d3=d2.compareTo(d);
System.out.println(d);
//比较是否相等 equals()
boolean b3=d.equals(d2);
System.out.println(b3);

三)Date子类

java.util.Date类的三个子类:

(1)java.sql.Date 只表示日期(JDBC日期转义格式:yyyy-mm-dd)

(2)java.sql.Time 只表示时间(JDBC时间转义格式:hh:mm:ss)

(3)java.sql.Timestamp 同时表示日期和时间(JDBC时间戳转义格式:yyyy-mm-dd hh:mm:ss.fffffffff)

构造方法:

public Date(long time); 使用给定毫秒时间值构造一个Date对象

public Time(long time); 使用毫秒时间值构造Time对象

public Timestamp(long time); 使用毫秒时间值构造Timestamp对象

成员方法:

public static Date valueOf(String s); 把JDBC日期转义格式的字符串转换为Date值

public static Time valueOf(String s); 将使用JDBC时间转义格式的字符串转换为Time值

public static Timestamp valueOf(String s); 将使用JDBC时间戳转义格式的字符串转换为Timestamp值

public String toString();

使用JDBC日期转义格式对日期进行格式化

使用JDBC时间戳转义格式编排时间戳

二、DateFormat类

概述:java.text.DateFormat类是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间

  • DateFormat类可以进行日期和字符串的格式化和解析,但是由于是抽象类,所以使用具体的子类SimpleDateFormat。

Date -> String (格式化)

Date date = new Date();
// 指定输出的日期格式,获取日期格式化类对象
DateFormat bf = new SimpleDateFormat("yyyy-MM-dd E a HH:mm:ss");
// 调用format(Date date)方法,将传入的date按指定方式格式化
String format = bf.format(date);
System.out.println(format);

String -> Date (解析)

Date date = new Date();
// 指定输出的日期格式,获取日期格式化类对象
DateFormat bf = new SimpleDateFormat("yyyy-MM-dd E a HH:mm:ss");
// 调用format(Date date)方法,将传入的date按指定方式格式化
String format = bf.format(date);
System.out.println(format);
try {
    // 调用parse(String)方法将字符串转为Date类型
    Date parse = bf.parse(format);
    System.out.println(parse);
} catch (ParseException e) {
    throw new RuntimeException(e);
}

三、SimpleDateFormat类

java.text.SimpleDateFormat类是以与语言环境有关的方式来格式化和解析日期的具体类。

作用:格式化时间,规定时间格式(一般使用它规定时间),可以把时间对象格式化成文本,把文本解析成时间对象

  • 进行格式化(日期 -> 文本)、解析(文本 -> 日期)。

一)构造方法

方法名说明
SimpleDateFormat()构造一个SimpleDateFormat,使用默认模式和日期格式
SimpleDateFormat(String pattern)构造一个SimpleDateFormat使用给定的模式和默认的日期格式

常用方法

方法名说明
final String format(Date date)将日期格式化成日期/时间字符串
Date parse(String source) throws ParseException从给定字符串开始解析文本,以生成一个日期
注意:在把一个字符串解析为日期的时候,日期和时间模式必须和给定的字符串格式相匹配。

时间模式字母

字母日期或时间
ya上/下午 am/pm标记
M年中月份H1天中小时数(0-23)
w年中的周数k一天中的小时 (1-24)
W月中的周数K上午/下午一小时 (0-11)
D年中的天数h上午/下午一小时 (1-12)
d月中天数m分钟(小时)
F月中的星期几s
E星期几名称(以星期为单位)S毫秒
u星期几(1 = 星期一,…,7 = 星期日)z一般时区
ZRFC 822时区XISO 8601 时区

演示:

String s = "2022年5月18日 22:15:38 星期四 下午";
// 当使用SimpleDateFormat将字符串转换为Date时,字符串格式必须与
// SimpleDateFormat构造器中定义的格式一致,标点符号和空格都必须一致,
// 否则parse方法会抛出转换异常:java.text.ParseException:
// Unparseable date: at  DateFormat.parse(DateFormat.java:399)
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss E a");
Date date = null;
try {
    // 调用parse(String)方法将字符串转为Date类型
    date = simpleDateFormat.parse(s);
    // 调用format(Date date)方法,将传入的date按指定方式格式化
    String format = simpleDateFormat.format(date);
    System.out.println(format);
} catch (ParseException e) {
    throw new RuntimeException(e);
}
System.out.println(date);

四、Calendar类

概述:java.util.Calendar类是一个抽象类,它提供了日期计算的相关功能、获取或设置各种日历字段的方法

  • protected Calendar() 构造方法为protected修饰,无法直接创建该对象

一)常用字段(都是静态常量)

字段描述
YEAR指示年的get和set的字段数字 ,即一般充当get和set方法的参数
MONTH指月份的get和set的字段数字,注意:月份从零开始,使用时要加一
DATEget和set的字段数字,指示一个月中的某天
HOURget和set的字段数字,指示上午或下午的小时
MINUTEget和set的字段数字,指示一小时中的分钟
SECONDget和set的字段数字,指示一分钟中的秒

二)常用方法

方法名说明
static Calendar getInstance()使用默认时区和区域获取日历
void set(int year,int month,int date,int hourofday,int minute,int second)设置日历的年、月、日、时、分、秒。
int get(int field)返回给定日历字段的值。字段比如年、月、日等
void set(int year, int month,int date);设置日历字段YEAR、MONTH和DAY_OF_MONTH的值
void setTime(Date date)用给定的Date设置此日历的时间。Date - >Calendar
Date getTime()返回一个Date表示此日历的时间。Calendar- >Date
void add(int field,int amount)按照日历的规则,给指定字段添加或减少时间量
long getTimeInMillis()毫秒为单位返回该日历的时间值

示例:

public static void main(String[] args) {
    /**
     * Calendar类的构造方法使用了protected方法修饰,所以不能直接使用构造方法创建对象
     * 可以调用getInstance静态方法获取当前系统时间
     */
    Calendar calendar = Calendar.getInstance() ;//获取当前系统时间
    System.out.println(calendar.getTime().toLocaleString());
    /**
     * get(要获取的时间):获取指定的时间
     * 注意:语言的月份是从0开始的,即0~11代表常规的1~12月,所以要加1
     */
    int year = calendar.get(Calendar.YEAR);//获取指定年份
    int month = calendar.get(Calendar.MONTH);//只能获取指定月份的上个月
    System.out.println(year + "年" + (month + 1) + "月");//(month + 1)获取当前系统月份
    /**
     * set(【年】,【月】,【日】,【时】,【分】,【秒】):设置时间
     */
    calendar.set(Calendar.YEAR, Calendar.JUNE,Calendar.JUNE);//设置指定年月日
    System.out.println(calendar);
    //第二种方式
    Calendar calendar1 = Calendar.getInstance();
    calendar1.set(Calendar.MONTH,5);//要设置的是月份,把月份设为5月
    /**
     * add(要修改的时间,修改值):可以增加或减少时间,修改值为正,则加,为负数,就减
     */
    calendar.add(Calendar.MONTH,5);//月份数加5
    calendar.add(Calendar.MONTH,-5);//月份数减5
    System.out.println(calendar);
    /**
     *getActualMaximum():获取时间的最大数
     *getActualMinimum():获取时间的最小数
     */
    calendar.getActualMaximum(Calendar.MONTH);//获取月份的最大数
    calendar.getActualMaximum(Calendar.DAY_OF_MONTH);//获取当前月份的最大天数
    calendar.getActualMinimum(Calendar.MONTH);//获取月份的最小数
    /**
     * getTime():获取一个Date类型的时间
     * setTime():用给定的Date类型设置此时间
     */
    Date date = new Date();
    calendar.setTime(date);
    System.out.println(calendar.getTime());
/**
    *getTimeInMillis():获取从1970年至今的毫秒总数
    */
    System.out.println( calendar.getTimeInMillis());

}
需求:键盘录入年份,求当年二月份的最大天数
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入年份:");
        int year = scanner.nextInt();
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, 2, 1);//键盘输入年份,月份从0开始计算,设置为三月
        calendar.add(Calendar.DAY_OF_MONTH,-1);// 从3月1日回推一天即为2月最后一天
        int date = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(year + "年2月份有" + date + "天");

五、JDK8 第三代时间类

JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。而Calendar也存在问题是:

​ 1)可变性:像曰期和时间这样的类应该是不可变的。

​ 2)偏移性:Date中的年份是从1970开始的,而月份都从0开始。

​ 3)格式化:格式化只对Date有用,Calendar则不行。

​ 4)此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)

为了解决此类问题,JDK新增了3个时间日期类:

  • LocalDate
  • LocalTime
  • LocalDateTime

一)LocalDate类

LocalDate是表示日期(通常视为年-月-日)的不可变日期时间对象,采用了系统的默认时区。只包含日期,可以获取日期字段

1、常用方法
方法描述
static LocalDate now()从默认时区的系统时钟中获取当前日期
static LocalDate now(ZoneId zone)从指定时区的系统时钟中获取当前日期
static LocalDate of(int year, int month, int dayOfMonth)指定年、月、日
String format(DateTimeFormatter formatter)使用指定的格式化程序设置此日期的格式
getYear()获取年份
getMonth()获取月份(月份英文名)
getMonthValue()获取月份(月份值,数字)
getDayOfMonth()获取日期
getDayOfWeek()获取星期(英文名)
getDayOfYear()获取这一年的第几天
withYear(int)设置年
withMonth(int)设置月
withDayOfMonth(int)设置日
withDayOfYear(int)设置年中第几天
plusXXXs(long)将当前年、月、日、星期后移指定值,如:当前2022年,年份加两年:plusYears(2) ==> 2024年
minusXXXs(long)将当前年、月、日、星期前移指定值,即减去指定的年、月、日、周数
DateTimeFormatter类

DateTimeFormatter是时间格式化类。

public static void main(String[] args) {
    //创建DateTimeFormatter
    DateTimeFormatter dtf=DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
    //1 把时间格式化成字符串
    String format = dtf.format(LocalDateTime.now());
    System.out.println(format);
    //2 把字符串解析成时间
    LocalDateTime localDateTime = LocalDateTime.parse("2020/03/10 10:20:35", dtf);
    System.out.println(localDateTime);
}

注意:DateTimeFormatter格式化类与SimpleDateFormat类相似,其ofPattern()方法传入的参数与SimpleDateFormat.parse()传入的参数格式类似,如:DateTimeFormatter.ofPattern("yyyy年MM月dd日 E"),但是要注意调用该方法的是哪个类,比如调用类是LocalDate类,此时不要传入与时间相关的,因为LocalDate类不能获取时间

二)LocalTime类

LocalTime类表示一天中的时间,只包含时间,可以获取时间字段

1、常用方法
方法描述
static LocalTime now()从默认时区的系统时钟中获取当前时间
static LocalTime now(ZoneId zone)从指定时区的系统时钟中获取当前时间
static LocalTime of(int hour, int minute, int second,int nanoOfSecond)指定时、分、秒、纳秒
String format(DateTimeFormatte formatter)使用指定的格式化程序设置此日期的格式
getHour()获取小时信息
getMinute()获取分钟信息
getSecond()获取秒
getNano()获取纳秒
withHour(int)设置小时
withMinute(int)设置分钟
withSecond(int)设置秒
withNano(int)设置纳秒
plusXXXs(long)将当前时、分、秒、纳秒后移指定值,如:当前22点,小时加两小时:plusHours(2) ==> 0点
minusXXXs(long)将当前时、分、秒、纳秒前移指定值,即减去指定的时、分、秒、纳秒数

三)LocalDateTime类

日期 + 时间,可以获取日期和时间字段,表示本地日期时间,默认使用系统时区

1、常用方法
方法描述
static LocalDateTime now()从默认时区的系统时钟中获取当前日期时间。
static LocalDateTime now(ZoneId zone)从指定时区的系统时钟中获取当前日期时间
static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond)指定年、月、日、时、分、秒、纳秒
String format(DateTimeFormatte formatter)使用指定的格式化程序设置此日期时间的格式
getXXX()分别获取年、月(英文名)、时、分、秒、纳秒
getMonthValue()获取1~12之间的月份值
getDayOfMonth()获取“月份中的某一天”字段
getDayOfWeek()获取星期几的英文名
getDayOfYear()获取“一年中的某一天”字段
withXXX(int)设置年、月、时、分、秒、纳秒
withDayOfMonth(int)设置日期
withDayOfYear(int)设置一年中的多少天
plusXXXs(long)将当前年、月、日、时、分、秒、纳秒、周数后移指定值,如:当前22点,小时加两小时:plusHours(2) ==> 0点
minusXXXs(long)将当前年、月、日、时、分、秒、纳秒、周数前移指定值,即减去指定的年、月、日、时、分、秒、纳秒、周数
public static void main(String[] args) {
		//1创建本地时间
		LocalDateTime localDateTime=LocalDateTime.now();
		//LocalDateTime localDateTime2=LocalDateTime.of(year, month, dayOfMonth, hour, minute)
		System.out.println(localDateTime);
		System.out.println(localDateTime.getYear());
		System.out.println(localDateTime.getMonthValue());
		System.out.println(localDateTime.getDayOfMonth());
		
		//2添加两天
		LocalDateTime localDateTime2 = localDateTime.plusDays(2);
		System.out.println(localDateTime2);
		
		//3减少一个月
		LocalDateTime localDateTime3 = localDateTime.minusMonths(1);
		System.out.println(localDateTime3);
	}

四)Instant 时间戳类

Instant表示瞬间,和前面Date类相似。

相较于 System.currentTimeMillis()获取到【毫秒】,Instant 可以更为精确的获取到【纳秒】。Instant提供了大量与Date相互转换的方法

public static void main(String[] args) {
    //1 创建Instant:时间戳
    Instant instant=Instant.now();
    System.out.println(instant.toString());
    System.out.println(instant.toEpochMilli());
    System.out.println(System.currentTimeMillis());
    //2 添加减少时间

    Instant instant2 = instant.plusSeconds(10);

    System.out.println(Duration.between(instant, instant2).toMillis());

    //1 Date --->Instant--->LocalDateTime
    System.out.println("-------------Date --->Instant---->LocalDateTime-----------");
    Date date=new Date();
    Instant instant3 = date.toInstant();
    System.out.println(instant3);

    // ZoneId类是时区类
    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant3, ZoneId.systemDefault());
    System.out.println(localDateTime);

    //2 LocalDateTime --->Instant--->Date
    System.out.println("-------------LocalDateTime --->Instant---->Date-----------");

    Instant instant4 = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    System.out.println(instant4);
    Date from = Date.from(instant4);
    System.out.println(from);

}