Java Calendar详解及常用场景

1概述

本文环境JDK1.8
Java Calendar是java.util.Calendar包下的常用类,项目中经常会对时间进行处理,获取时间啊或者判断是否在某个时间范围内等。
我们从源码中看看Calendar:

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>

该类被abstract所修饰,说明不能通过new的方式来获得实例,而Calendar提供了一个类方法getInstance,返回一个Calendar对象,接着我们看看getInstance方法:

    public static Calendar getInstance()
    {
        return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }

其中createCalendar方法就是根据不同国家地区返回对应的日期子类,那么就代表了,我们其实可以在getInstance方法中传递参数的 :TimeZone zone, Locale aLocale 指定时区和区域设置日历。

  1. 获取Calendar实例的四种方式:

     1.getInstance():使用默认的时区、默认的位置创建实例
     2.getInstance(TimeZone zone):使用指定的时区、默认的位置创建实例
     3.getInstance(Locale aLocale):使用默认的时区、指定的位置创建实例
     4.getInstance(TimeZone zone,Locale aLocale)使用指定的时区、指定的位置创建实例
    

2 常用方法

2.1 get 方法
Calendar calendar = Calendar.getInstance();
        // 获取年
        int year = calendar.get(Calendar.YEAR);
        // 获取月,注意月份下标从0开始,所以取月份要+1
        int month = calendar.get(Calendar.MONTH) + 1;
        // 星期,英语国家星期从星期日开始计算
        int weekday = calendar.get(Calendar.DAY_OF_WEEK);
        // 获取日
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        // 获取时
        int hour = calendar.get(Calendar.HOUR);
        // int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24小时表示
        // 获取分
        int minute = calendar.get(Calendar.MINUTE);
        // 获取秒
        int second = calendar.get(Calendar.SECOND);

        System.out.println("年:"+ year + "\n月:" + month + "\n日:" + day + "\n时:" + hour
                                 + "\n分:" + minute + "\n秒:" + second +  "\n星期:" + weekday);
  • 结果
年:2019
月:4
日:28
时:9
分:58
秒:53
星期:1

可以很方便的获取当前的时间。

2.2 set 方法
  • 整体设置:
        // 如果想设置为某个日期,可以一次设置年月日时分秒,由于月份下标从0开始赋值月份要-1
        // cal.set(year, month, date, hourOfDay, minute, second);
        calendar.set(2019, 4, 28, 9, 58, 53);
        System.out.println(calendar.getTime());
     //结果:Tue May 28 09:58:53 CST 2019
  • 单个字段设置:
    // 或者6个字段分别进行设置,由于月份下标从0开始赋值月份要-1
        // 如果想设置为某个日期,可以一次设置年月日时分秒,由于月份下标从0开始赋值月份要-1
        // calendar.set(year, month, date, hourOfDay, minute, second);
        calendar.set(2019, 4, 28, 9, 58, 53);
        System.out.println(calendar.getTime());
        calendar.set(Calendar.YEAR, 2019);
        calendar.set(Calendar.MONTH, Calendar.MAY);
        calendar.set(Calendar.DAY_OF_MONTH, 28);
        calendar.set(Calendar.HOUR_OF_DAY, 9);
        calendar.set(Calendar.MINUTE, 58);
        calendar.set(Calendar.SECOND, 53);
        System.out.println(calendar.getTime());
2.3 add方法
        //当晚最后一秒  add 一秒 会自动加一天
        System.out.println(calendar.getTime());
        calendar.set(2019, 4, 28, 23, 59, 59);
        calendar.add(Calendar.SECOND, 1);
        System.out.println(calendar.getTime());
  • 结果
Tue May 28 09:58:53 CST 2019
Wed May 29 00:00:00 CST 2019
        //当月的最后一天 add 一天
        calendar.set(2019, 4, 30, 8, 0, 0);
        System.out.println(calendar.getTime());
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        System.out.println(calendar.getTime());
  • 结果:
Thu May 30 08:00:00 CST 2019
Fri May 31 08:00:00 CST 2019

注意:在使用add方法操作月份时,会将不存在的日期归为当月日历的最后一天。

2.4 after/before方法

after和before方法很类似,从名字我们就可以判断他们的意思,我们先看看源码到底如何使用的:

    public boolean after(Object when) {
        return when instanceof Calendar
            && compareTo((Calendar)when) > 0;
    }
    
    public boolean before(Object when) {
        return when instanceof Calendar
            && compareTo((Calendar)when) < 0;
    }

可以看出首先会判断当前传递的参数是不是Calendar类型,然后调用compareTo方法进行比较.
所以你如果传递的不是Calendar实例的话永远都为false.

        Calendar calendar = Calendar.getInstance();
        //获取当前时间
        System.out.println("当前时间:"+calendar.getTime());

        //判断是否在某个时间之后
        Calendar time = Calendar.getInstance();
        time.set(2019,3,29,8,0,0);
        System.out.println("自己设定的时间:"+time.getTime());
        //当前时间是否在设定的time之后
        System.out.println(calendar.after(time));
        //当前时间是否在设定的time之前
        System.out.println(calendar.before(time));
  • 结果
当前时间:Mon Apr 29 09:52:14 CST 2019
自己设定的时间:Mon Apr 29 08:00:00 CST 2019
true
false

3 常用场景

3.1 获取任意一个月的最后一天
    public static void lastDay() {
        Calendar calendar = Calendar.getInstance();
        // 假设求4月的最后一天
        int currentMonth = 4;
        // 先求出7月份的第一天,实际中这里6为外部传递进来的currentMonth变量
        // 1
        calendar.set(calendar.get(Calendar.YEAR), currentMonth, 1);

        calendar.add(Calendar.DATE, -1);

        // 获取日
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        System.out.println("4月份的最后一天为" + day + "号");
    }

//4月份的最后一天为30号
3.2 判断时间是否在某个范围
package cn.zhangyu.utils;

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

public class TimeFilterUtils {
    public static void main(String [] args) {
        //现在的时间
        Date now = null;
        //开始的时间
        Date beginTime = null;
        //结束的时间
        Date endTime = null;
   try {
            now = SimpleDateFormatUtils.getDataByFormatString(SimpleDateFormatUtils.HH_mm_ss,"00:00:00");
            beginTime = SimpleDateFormatUtils.getDataByFormatString(SimpleDateFormatUtils.HH_mm_ss,"8:21:00");
            endTime = SimpleDateFormatUtils.getDataByFormatString(SimpleDateFormatUtils.HH_mm_ss,"21:33:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Boolean flag = belongCalendar(now, beginTime, endTime);
        System.out.println(flag);
    }

    public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

}

  • SimpleDateFormatUtils 工具类
package cn.zhangyu.utils;

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

public class SimpleDateFormatUtils {

    /**yyyy-MM-dd HH:mm:ss 类型的日期 时间格式*/
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    /**yyyy-MM-dd类型的日期格式*/
    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    //HH:mm
    public static final String HH_mm_ss = "HH:mm:ss";

    /**
     * 根据输入的format格式,以及format字符串,返回对应的日期
     *
     * @param pattern,字符串的format格式,例如:yyyy-MM-dd HH:mm:ss
     * @param dateFormatStr,format后的日期字符串,例如:2015-02-10 22:00:00
     * @return java.util.Date对象
     * @throws ParseException
     */
    public static Date getDataByFormatString(String pattern, String dateFormatStr) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        Date date = simpleDateFormat.parse(dateFormatStr);
        return date;
    }

    /**
     *
     * @param pattern,字符串的format格式,例如:yyyy-MM-dd HH:mm:ss
     * @param date:Date类型,需要转换为指定格式的日期对象
     * @return
     */
    public static String getFormatStrByPatternAndDate(String pattern,Date date){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        String formatStr = simpleDateFormat.format(date);
        return formatStr;
    }

    /**
     *
     * @param pattern,字符串的format格式,例如:yyyy-MM-dd HH:mm:ss
     * @param time:13位long类型的时间戳,需要转换为指定格式的日期对象
     * @return
     */
    public static String getFormatStrByPatternAndLong(String pattern,Long time){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        String formatStr = simpleDateFormat.format(time);
        return formatStr;
    }

    public static void main(String[] args) throws ParseException {
        Date data = SimpleDateFormatUtils.getDataByFormatString(SimpleDateFormatUtils.YYYY_MM_DD_HH_MM_SS, "2019-04-26 09:33:09");
        System.out.println(data);

        String str = SimpleDateFormatUtils.getFormatStrByPatternAndDate(SimpleDateFormatUtils.YYYY_MM_DD_HH_MM_SS, new Date());
        System.out.println(str);

        String str1 = SimpleDateFormatUtils.getFormatStrByPatternAndLong(SimpleDateFormatUtils.YYYY_MM_DD_HH_MM_SS, new Date().getTime());
        System.out.println(str1);
    }
}

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值