Java日期学习笔记(一)

Java中的日期概述

日期在Java中是一块非常复杂的内容,对于一个日期在不同的语言国别环境中,日期的国际化,日期和时间之间的转换,日期的加减运算,日期的展示格式都是非常复杂的问题。

在Java中,操作日期主要涉及到一下几个类:

1、java.util.Date

        类 Date 表示特定的瞬间,精确到毫秒。从 JDK 1.1 开始,应该使用 Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和分析日期字符串。Date 中的把日期解释为年、月、日、小时、分钟和秒值的方法已废弃。

2、java.text.DateFormat(抽象类)

        DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并分析日期或时间。日期/时间格式化子类(如 SimpleDateFormat)允许进行格式化(也就是日期 -> 文本)、分析(文本-> 日期)和标准化。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 年,1 月 1 日 00:00:00 这一刻开始的毫秒数。

3、java.text.SimpleDateFormat(DateFormat的直接子类)

        SimpleDateFormat 是一个以与语言环境相关的方式来格式化和分析日期的具体类。它允许进行格式化(日期 -> 文本)、分析(文本 -> 日期)和规范化。

        SimpleDateFormat 使得可以选择任何用户定义的日期-时间格式的模式。但是,仍然建议通过 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 来新的创建日期-时间格式化程序。

4、java.util.Calendar(抽象类)

        Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。

        与其他语言环境敏感类一样,Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar 的 getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化。

5、java.util.GregorianCalendar(Calendar的直接子类)

        GregorianCalendar 是 Calendar 的一个具体子类,提供了世界上大多数国家使用的标准日历系统。

        GregorianCalendar 是一种混合日历,在单一间断性的支持下同时支持儒略历和格里高利历系统,在默认情况下,它对应格里高利日历创立时的格里高利历日期(某些国家是在 1582 年 10 月 15 日创立,在其他国家要晚一些)。可由调用方通过调用 setGregorianChange() 来更改起始日期。

使用 getDateInstance 来获得该国家的标准日期格式。另外还提供了一些其他静态工厂方法。使用 getTimeInstance 可获得该国家的时间格式。使用 getDateTimeInstance 可获得日期和时间格式。可以将不同选项传入这些工厂方法,以控制结果的长度(从 SHORT 到 MEDIUM 到 LONG 再到 FULL)。确切的结果取决于语言环境,但是通常:

  •  SHORT:完全为数字,如 12.13.52 或 3:30pm
  •  MEDIUM:较长,如 Jan 12, 1952
  •  LONG:更长,如 January 12, 1952 或 3:30:32pm
  •  FULL:是完全指定,如 Tuesday, April 12, 1952 AD 或 3:30:42pm PST。

Date

类 java.util.Date 表示特定的瞬间,精确到毫秒。提供了很多的方法,但是很多已经过时,不推荐使用,下面仅仅列出没有过时的方法:

public void getCurrentDate() {
    System.out.println("---获取系统当前时间---");
    //创建并初始化一个日期(初始值为当前日期)
    Date date = new Date();
    System.out.println("现在的日期是 = " + date.toString());
    System.out.println("自1970年1月1日0时0分0秒开始至今所经历的毫秒数 = " + date.getTime());
}

Calendar(抽象类)

java.util.Calendar是个抽象类,是系统时间的抽象表示,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。

与其他语言环境敏感类一样,Calendar 提供了一个类方法 getInstance(),以获得此类型的一个通用的对象。Calendar 的 getInstance() 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化。

一个Calendar的实例是系统时间的抽象表示,从Calendar的实例可以知道年月日星期月份时区等信息。Calendar类中有一个静态方法get(int x),通过这个方法可以获取到相关实例的一些值(年月日星期月份等)信息。参数x是一个产量值,在Calendar中有定义。

Calendar c1 = Calendar.getInstance();

  • int year = c1.get(Calendar.YEAR); // 获得年份
  • int month = c1.get(Calendar.MONTH) + 1; // 获得月份
  • int date = c1.get(Calendar.DATE); // 获得日期
  • int hour = c1.get(Calendar.HOUR_OF_DAY); // 获得小时
  • int minute = c1.get(Calendar.MINUTE); // 获得分钟
  • int second = c1.get(Calendar.SECOND); // 获得秒
  • int day = c1.get(Calendar.DAY_OF_WEEK); // 获得星期几(注意(这个与Date类是不同的):1代表星期日、2代表星期1、3代表星期二,以此类推)

Calendar中些陷阱:

  1. Calendar的星期是从周日开始的,常量值为0。
  2. Calendar的月份是从一月开始的,常量值为0。
  3. Calendar的每个月的第一天值为1。

Calendar类对象字段类型

Calendar类中用以下这些常量表示不同的意义,jdk内的很多类其实都是采用的这种思想

常量

描述

Calendar.YEAR

年份

Calendar.MONTH

月份

Calendar.DATE

日期

Calendar.DAY_OF_MONTH

日期,和上面的字段意义完全相同

Calendar.HOUR

12小时制的小时

Calendar.HOUR_OF_DAY

24小时制的小时

Calendar.MINUTE

分钟

Calendar.SECOND

Calendar.DAY_OF_WEEK

星期几

GregorianCalendar类

Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。

Calendar 的getInstance()方法返回一个默认用当前的语言环境和时区初始化的GregorianCalendar对象。GregorianCalendar定义了两个字段:AD和BC。这是代表公历定义的两个时代。

Java日期格式类

Java 8有新的Date-Time API来处理日期和时间。 我们应该使用新的Java 8 Date-Time API来格式化和解析日期时间值。

如果我们正在编写与日期和时间相关的新代码,我们应该使用新的Date-Time API。

此部分适用于使用旧日期和日历类的旧代码。

DateFormat

DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并分析日期或时间。日期/时间格式化子类(如 SimpleDateFormat)允许进行格式化(也就是日期 -> 文本)、分析(文本-> 日期)和标准化。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 年,1 月 1 日 00:00:00 这一刻开始的毫秒数。

格式样式

Date Format类将五个样式定义为常量:

  • DateFormat.DEFAULT
  • DateFormat.SHORT
  • DateFormat.MEDIUM
  • DateFormat.LONG
  • DateFormat.FULL

DEFAULT格式与MEDIUM相同。getInstance()使用SHORT。

下表显示了对于美国区域设置以不同样式格式化的相同日期。

样式

格式化日期

DEFAULT

Mar 27, 2014

SHORT

3/27/14

MEDIUM

Mar 26, 2014

LONG

March 26, 2014

FULL

Sunday, November 2, 2014

SimpleDateFormat 

SimpleDateFormat 是一个以与语言环境相关的方式来格式化和分析日期的具体类。它允许进行格式化(日期 -> 文本)、分析(文本 -> 日期)和规范化。

SimpleDateFormat 使得可以选择任何用户定义的日期-时间格式的模式。但是,仍然建议通过 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 来新的创建日期-时间格式化程序。

要创建自定义日期格式,我们可以使用SimpleDateFormat类。

SimpleDateFormat类是对语言环境敏感的。

它的默认构造函数创建一个格式化程序,默认日期格式为默认语言环境。

SimpleDateFormat类中的format()方法执行日期格式。

日期和时间的格式化编码

时间模式字符串用来指定时间格式。在此模式中,所有的 ASCII 字母被保留为模式字母,定义如下:

字母

描述

示例

G

纪元标记

AD

y

四位年份

2001

M

月份

July or 07

d

一个月的日期

10

h

 A.M./P.M. (1~12)格式小时

12

H

一天中的小时 (0~23)

22

m

分钟数

30

s

秒数

55

S

毫秒数

234

E

星期几

Tuesday

D

一年中的日子

360

F

一个月中第几周的周几

2 (second Wed. in July)

w

一年中第几周

40

W

一个月中第几周

1

a

A.M./P.M. 标记

PM

k

一天中的小时(1~24)

24

K

 A.M./P.M. (0~11)格式小时

10

z

时区

Eastern Standard Time

'

文字定界符

Delimiter

"

单引号

`

将文本数据解析成日期对象 

假设我们有一个文本字符串包含了一个格式化了的日期对象,我们希望解析这个字符串并从文本日期数据创建一个日期对象。我们将再次以格式化字符串"MM-dd-yyyy" 调用SimpleDateFormat类。但是这一次,我们使用格式化解析而不是生成一个文本日期数据。我们的例子显示在下面,将解析文本字符串"3-02-2012"并创建一个值为1330617600000 的日期对象。

@Test
public void sdfTest() {
    SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
    String txtDate = "7-26-2018";
    try {
        Date date = dateFormat.parse(txtDate);
        System.out.println(date.getTime());// 1532534400000
        System.out.println(dateFormat.format(date));// 07-26-2018
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

使用标准的日期格式化过程 

既然我们已经可以生成和解析定制的日期格式了,让我们来看一看如何使用内建的格式化过程。方法 DateFormat.getDateTimeInstance() 让我们得以用几种不同的方法获得标准的日期格式化过程。下面是我们获取了六个内建的日期格式化过程。它们包括一个空,默认,短的,中等的,长的,完整的日期格式。 

@Test
    public void dfTest() {
        String strDate = null;
        Date date = new Date();
        System.out.println(date);// Thu Jul 26 14:17:51 CST 2018
        strDate = DateFormat.getDateInstance().format(date);
        System.out.println(strDate);// 2018-7-26
        //Date
        strDate = DateFormat.getDateInstance(DateFormat.DEFAULT).format(date);
        System.out.println(strDate);// 2018-7-26
        strDate = DateFormat.getDateInstance(DateFormat.SHORT).format(date);
        System.out.println(strDate);// 18-7-26
        strDate = DateFormat.getDateInstance(DateFormat.MEDIUM).format(date);
        System.out.println(strDate);// 2018-7-26
        strDate = DateFormat.getDateInstance(DateFormat.LONG).format(date);
        System.out.println(strDate);// 2018年7月26日
        strDate = DateFormat.getDateInstance(DateFormat.FULL).format(date);
        System.out.println(strDate);// 2018年7月26日 星期四
        //DateTime
        strDate = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT).format(date);
        System.out.println(strDate);// 2018-7-26 14:17:51
        strDate = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(date);
        System.out.println(strDate);// 18-7-26 下午2:17
        strDate = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(date);
        System.out.println(strDate);// 2018-7-26 14:17:51
        strDate = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(date);
        System.out.println(strDate);// 2018年7月26日 下午02时17分51秒
        strDate = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(date);
        System.out.println(strDate);// 2018年7月26日 星期四 下午02时17分51秒 CST
    }

自定义格式

@Test
public void customDateTest() {
    Date date = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE-MMMM-dd-yyyy");
    System.out.println(dateFormat.format(date)); // 星期四-七月-26-2018
}

只要通过向SimpleDateFormat 的构造函数传递格式字符串"EEE-MMMM-dd-yyyy",我们就能够指明自己想要的格式。格式字符串中的ASCII 字符告诉格式化函数下面显示日期数据的哪一个部分。EEEE是星期,MMMM是月,dd是日,yyyy是年,字符的个数决定了日期是如何格式化的。传递"EE-MM-dd-yy"会显示Friday-March-02-2012。 

日期处理

Calendar 类是一个抽象类,它为一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

当前毫秒值是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。

日期加减

// 使用默认时区和语言环境获得一个日历。
private static Calendar calendar;

public static void printResult(String description) {
    System.out.print(description + ": ");
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()));
    calendar = Calendar.getInstance();// 重置为当前时间
}

@Test
public void operateDate() {
    calendar = Calendar.getInstance();// 初始化
    printResult("当前时间 ");

    calendar.add(Calendar.HOUR_OF_DAY, 1);
    printResult("增加1小时");
    calendar.add(Calendar.DAY_OF_MONTH, 1);
    printResult("增加1天 ");
    calendar.add(Calendar.MONTH, 1);
    printResult("增加1个月");
    calendar.add(Calendar.YEAR, 1);
    printResult("增加1年 ");
    calendar.add(Calendar.YEAR, -2);
    printResult("减少2年 ");
}

输出

  • 当前时间 : 2018-07-26 14:55:23
  • 增加1小时: 2018-07-26 15:55:23
  • 增加1天 : 2018-07-27 14:55:23
  • 增加1个月: 2018-08-26 14:55:23
  • 增加1年 : 2019-07-26 14:55:23
  • 减少2年 : 2016-07-26 14:55:23

两个日期相差天数

@Test
public void dateSubtract() {
    long millisOfDay = 24 * 60 * 60 * 1000;
    Calendar calendar = new GregorianCalendar(2015, 9, 1);
    Calendar calendar1 = new GregorianCalendar(2016, 9, 1);
    Calendar calendar2 = new GregorianCalendar(2017, 9, 1);
    // 2016年是闰年,得到366天
    System.out.println((calendar1.getTimeInMillis() - calendar.getTimeInMillis()) / millisOfDay);
    // 2017年是平年,得到365天
    System.out.println((calendar2.getTimeInMillis() - calendar1.getTimeInMillis()) / millisOfDay);
}

 

参考:

https://www.cnblogs.com/lcngu/p/5154834.html

https://www.w3cschool.cn/java/java-date-format-class.html

https://blog.csdn.net/u011494050/article/details/44178795

https://baike.xsoftlab.net/view/148.html

http://www.runoob.com/java/java-date-time.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值