Java 处理时间 一般通过 Date、Calendar 获取 之后 进行 DateFormat、SimpleDateFormat 等 格式转换类 进行处理。

这里强调一点 日期:2021年2月22日,在我们编码过程中,一律写成 2021-02-22,不论月还是日,必须是2位数,Mysql 的sql中一样需要这样写!!!

Date

Date时 JDK1.0的产品,易用性不是很好

案例

展示 当前时间 :星期 月 天 时 分 表 时区 年

@Test
    public void newDate(){
        System.out.println(new Date());  //Mon Feb 22 14:57:23 CST 2021
    }

在时间戳 其实原点 加上 1000毫秒

@Test
    public void newDateADD1000L(){
        // 在 1970年 1月 1日 8 点 加上1000 毫秒
        System.out.println(new Date(1000L));  //Thu Jan 01 08:00:01 CST 1970
    }

下面代码 时间 都设置为了时区问题

关于 会变更的日期,请不要尝试 使用Date 切记

用起来 太繁琐,不如用 Calendar

  • 第一点 getTime() 算的是时间原点 1970年 1月 1日 0时0分的时间
  • new Date(year,month,day,hour,minute,second) 你添加的时间是 1899年 12月 31日 0点 0分 0秒 起步算的
    @Test
    public void newDateADDAnyYMD() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd E HH:mm:ss");
        System.out.println(simpleDateFormat.format(new Date(0, 0, 0, 0, 0, 0)));
        //1899-12-31 星期日 00:00:00


        System.out.println(simpleDateFormat.format(new Date(70, 0, 1, 0, 0, 0)));
        //1970-01-01 星期四 00:00:00
    }

Calendar类

Calendar 是通过getInstance 进行创建的,创建时 可以选择时区

    @Test
    public void CalendarDefultGMT(){
        Calendar instance = Calendar.getInstance(); // 也是 获取当前时间
        System.out.println("获取到的年是:"+instance.get(Calendar.YEAR));
        System.out.println("获取到的月是:"+instance.get(Calendar.MONTH));
        System.out.println("获取到的日是:"+instance.get(Calendar.DATE));
        System.out.println("获取到的12小时制 时是:"+instance.get(Calendar.HOUR));
        System.out.println("获取到的24小时制 时是:"+instance.get(Calendar.HOUR_OF_DAY));
        System.out.println("获取到的分是:"+instance.get(Calendar.MINUTE));
        System.out.println("获取到的秒是:"+instance.get(Calendar.SECOND));
        System.out.println("获取到的星期是:"+(instance.get(Calendar.DAY_OF_WEEK)-1));

    }

输出的结果

获取到的年是:2021
获取到的月是:1
获取到的日是:22
获取到的12小时制 时是:4
获取到的24小时制 时是:16

获取到的分是:59
获取到的秒是:29
获取到的星期是:1

根据GMT 设置时间 (中国是GMT+8)

@Test
    public void CalendarSetGMT(){
        Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
        System.out.println("获取到的年是:"+instance.get(Calendar.YEAR));
        System.out.println("获取到的月是:"+instance.get(Calendar.MONTH));
        System.out.println("获取到的日是:"+instance.get(Calendar.DATE));
        System.out.println("获取到的12小时制 时是:"+instance.get(Calendar.HOUR));
        System.out.println("获取到的24小时制 时是:"+instance.get(Calendar.HOUR_OF_DAY));
        System.out.println("获取到的分是:"+instance.get(Calendar.MINUTE));
        System.out.println("获取到的秒是:"+instance.get(Calendar.SECOND));
        System.out.println("获取到的星期是:"+(instance.get(Calendar.DAY_OF_WEEK)-1));

    }

结果是

获取到的年是:2021
获取到的年是:2021
获取到的月是:1
获取到的日是:22
获取到的12小时制 时是:9
获取到的24小时制 时是:9

获取到的分是:2
获取到的秒是:12
获取到的星期是:1

日历类,通常可以做 时间的转化:

获取当前时间,并在此基础上,加一个月,问是第一年的第几天

// 获取当前时间,并在此基础上,加一个月,问是第一年的第几天
    @Test
    public void CalendarOperate(){
        Calendar instance = Calendar.getInstance();
        System.out.println("当前时间是:"+instance.getTime());
        System.out.println("当前是这一年的第:"+instance.get(Calendar.DAY_OF_YEAR)+" 天");
        instance.add(Calendar.DATE,1);
        System.out.println("处理后的时间是:"+instance.getTime());
        System.out.println("当前是这一年的第:"+instance.get(Calendar.DAY_OF_YEAR)+" 天");
    }

结果:

当前时间是:Mon Feb 22 17:14:09 CST 2021
当前是这一年的第:53 天
处理后的时间是:Tue Feb 23 17:14:09 CST 2021
当前是这一年的第:54 天

问:2020年 2月 多少天?

    // 问 2000 年 2月 多少天
    @Test
    public void Calendar2000FebsDays() throws ParseException {
        Calendar instance = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = simpleDateFormat.parse("2000-03-01");

        instance.setTime(parse);
        instance.add(Calendar.DATE,-1);

        System.out.println(instance.get(Calendar.DAY_OF_MONTH));
    }

结果

29

上述 代码已经用过的 SimpleDateFormat 的方法了,这里 简单 讲一下

SimpleDateFormat 长用于处理 时间格式的转化

经常调用的有2个方法

  • parse(String string) 转化为Date
  • format(Date date) 转化为String

注意:使用parse将字符串转为日期存在线程安全问题,而使用format将日期转为字符串不存在线程安全问题。

常用格式

24小时制 yyyy-MM-dd HH:mm:ss

12小时制 yyyy-MM-dd hh:mm:ss

转换的格式

字母含义示例
y年份。一般用 yy 表示两位年份,yyyy 表示 4 位年份使用 yy 表示的年扮,如 11;
使用 yyyy 表示的年份,如 2011
M月份。一般用 MM 表示月份,如果使用 MMM,则会
根据语言环境显示不同语言的月份
使用 MM 表示的月份,如 05;
使用 MMM 表示月份,在 Locale.CHINA
语言环境下,如“十月”;在 Locale.US
语言环境下,如 Oct
d月份中的天数。一般用 dd 表示天数使用 dd 表示的天数,如 10
D年份中的天数。表示当天是当年的第几天, 用 D 表示使用 D 表示的年份中的天数,如 295
E星期几。用 E 表示,会根据语言环境的不同, 显示不
同语言的星期几
使用 E 表示星期几,在 Locale.CHINA 语
言环境下,如“星期四”;在 Locale.US 语
言环境下,如 Thu
H一天中的小时数(0~23)。一般用 HH 表示小时数使用 HH 表示的小时数,如 18
h一天中的小时数(1~12)。一般使用 hh 表示小时数使用 hh 表示的小时数,如 10 (注意 10 有
可能是 10 点,也可能是 22 点)
m分钟数。一般使用 mm 表示分钟数使用 mm 表示的分钟数,如 29
s秒数。一般使用 ss 表示秒数使用 ss 表示的秒数,如 38
S毫秒数。一般使用 SSS 表示毫秒数使用 SSS 表示的毫秒数,如 156

案例

parse
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = simpleDateFormat.parse("2000-03-01");

format:

        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(date);

DateFormat

  • 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。

LocalDate、LocalTime、LocalDateTime是JDK1.8新出的类

优势:相对于Date、Calendar更加安全而且api更加丰富,对日期时间的操作更加容易,非常值得一试。

根据类 命名 我们就可以轻松知道

LocalDate是 处理 日期类

LocalTime是 处理 时间类

LocalDateTime是 处理 日期时间类

LocalDate

        /**
         *1. LocalDate常用方法
         */
        LocalDate today = LocalDate.now();//获取当前日期
        System.out.println(String.format("[当前日期]%d-%d-%d", today.getYear(), today.getMonthValue(), today.getDayOfMonth()));
        System.out.println("[今天所处一月的周数]" + today.get(ChronoField.ALIGNED_WEEK_OF_MONTH));
        System.out.println("[今天所处一年的周数]" + today.get(ChronoField.ALIGNED_WEEK_OF_YEAR));
        System.out.println("[今天所处一年的天数]" + today.getDayOfYear());

        LocalDate past = LocalDate.parse("2021-02-22"); //获取 2021-02-22

        System.out.println("[2021-02-22是否是闰年]" + past.isLeapYear());
        System.out.println("[2021-02-22星期几]" + past.getDayOfWeek());
        System.out.println("[2021-02-22所在月的第一天]" + past.with(TemporalAdjusters.firstDayOfMonth()));
        System.out.println("[2021-02-22所在月的第二天]" + past.withDayOfMonth(2));
        System.out.println("[2021-02-22所在月的最后一天]" + past.with(TemporalAdjusters.lastDayOfMonth()));
        System.out.println("[2021-02-22之后18年]" + past.plusYears(18));
        System.out.println("[2021-02-22之前18个月]" + past.plusMonths(-18));
        System.out.println("[2021-02-22所在月的第一个周一]" + past.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)));

结果是:

2021-02-22
[当前日期]2021-2-22
[今天所处一月的周数]4
[今天所处一年的周数]8
[今天所处一年的天数]53
[2021-02-22是否是闰年]false
[2021-02-22星期几]MONDAY
[2021-02-22所在月的第一天]2021-02-01
[2021-02-22所在月的第二天]2021-02-02
[2021-02-22所在月的最后一天]2021-02-28
[2021-02-22之后18年]2039-02-22
[2021-02-22之前18个月]2019-08-22
[2021-02-22所在月的第一个周一]2021-02-01
[LocalDateTime-->String]2021/02/22 17:49:00-845
[String-->LocalDateTime-->Date]Mon Feb 22 17:49:00 CST 2021

一般处理 Local 时间的时候,通过使用:DateFormat