Java Calendar 使用说明

468 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

Java Calendar 使用说明

Java Calendar 是时间操作类,Calendar 抽象类定义了足够的方法,在某一特定的瞬间或日历上,提供年、月、日、小时之间的转换提供方法。

格式

这个格式表基于 jdk1.8,如果是其他版本出现问题请查阅官方文档.

Letter日期或时间组件演示Examples
G时代Text公元
yYear2022
Y当天所在的周属于的年份 ,只要本周跨年,那么这周就算入下一年Year2022
M月份MonthJuly; Jul; 07
LMonth in year (standalone form)MonthJuly; Jul; 07
w当年第几周Number27
W当月第几周Number2
D当年第几天Number189
d当月第几天Number10
F每月的星期几Number2
E星期几Text星期三
u星期的编号 (1 = Monday, ..., 7 = Sunday)Number1
aAm/pm 上午下午TextPM 下午
H时 (24 小时)(0-23)Number0
k时 (24 小时)(1-24)Number24
K时 (12 小时)(0-11)Number0
h时 (12 小时)(1-12)Number12
mNumber30
sNumber55
S毫秒 MillisecondNumber978
z一般时区一般时区Pacific Standard Time; PST; GMT-08:00
ZRFC 822 时区RFC 822 时区-0800
XISO 8601 时区ISO 8601 时区-08; -0800; -08:00

示例

public static void format(){
    SimpleDateFormat format = new SimpleDateFormat("G y 年,M 月 d 日 E,a H 时 m 分 s 秒 S 毫秒");
    System.out.println(format.format(new Date()));
    // 公元 2022 年,10 月 18 日 星期二,下午 19 时 57 分 11 秒 652 毫秒
    SimpleDateFormat format2 = new SimpleDateFormat("G yyyy 年,M 月 d 日 ");
    System.out.println(format2.format(new Date()));
    // 公元 2022 年,10 月 18 日
}

Calendar类常量

常量含义注释
Calendar.YEAR
Calendar.MONTHmonth 从 0 开始,也就是全年 12 个月由 0 ~ 11 进行表示。
Calendar.DAY_OF_MONTH
Calendar.HOUR_OF_DAY24小时制
Calendar.HOUR12小时制
Calendar.MINUTE
Calendar.SECOND
Calendar.MILLISECOND毫秒

特别注意 Calendar.DAY_OF_WEEK

  • 开始时间 Calendar.SUNDAY,如需自定义需要手动设置
  • 常量为 1-7 和月份有区别
常量含义注释
Calendar.SUNDAY = 1周日
Calendar.MONDAY = 2周一
Calendar.TUESDAY = 3周二
Calendar.WEDNESDAY = 4周三
Calendar.THURSDAY = 5周四
Calendar.FRIDAY = 6周五
Calendar.SATURDAY = 7周六

自定义每周第一天

setFirstDayOfWeek

Calendar ca = Calendar.getInstance();
// 设置哪天为本周第一天
ca.setFirstDayOfWeek(Calendar.MONDAY);

常量测试

public static void stand(){
    Calendar ca = Calendar.getInstance();

    System.out.println(ca.get(Calendar.YEAR));
    System.out.println(ca.get(Calendar.MONTH)); // 0-11
    System.out.println(ca.get(Calendar.DAY_OF_MONTH));
    System.out.println(ca.get(Calendar.HOUR_OF_DAY)); // 24 h
    System.out.println(ca.get(Calendar.HOUR)); // 12 h
    System.out.println(ca.get(Calendar.MINUTE));
    System.out.println(ca.get(Calendar.SECOND));
    System.out.println(ca.get(Calendar.MILLISECOND));
}

2022
9
19
1
13
34
56
528

Calendar 常用操作

获取 Calendar 实例

public static void instance(){
    Calendar ca = Calendar.getInstance();
    System.out.println(ca.getTime());

    Calendar ca2 = Calendar.getInstance(TimeZone.getDefault());
    System.out.println(ca2.getTime());

    Calendar ca3 = Calendar.getInstance(Locale.getDefault(Locale.Category.FORMAT));
    System.out.println(ca3.getTime());
}

设置当前 Calendar 时间

// 创建 Calendar 对象,默认当前时间
Calendar calendar = Calendar.getInstance();
// 初始化 Calendar 对象,但并不必要,除非需要重置时间
calendar.setTime(new Date());

计算一天的开始时间和结束时间

public static void getThisToday(){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY,0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND,0);
    String start = sdf.format(cal.getTime());

    cal.set(Calendar.HOUR_OF_DAY,23);
    cal.set(Calendar.MINUTE, 59);
    cal.set(Calendar.SECOND,59);
    String end = sdf.format(cal.getTime());

    System.out.println(start+"|"+end);
}

计算一周的开始时间和结束时间

public static void getThisWeekDate(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar ca = Calendar.getInstance();
        // 设置哪天为本周第一天
        ca.setFirstDayOfWeek(Calendar.MONDAY);
        // 设置日期为 本周的 周日
        ca.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
        // 设置年月日,H m s
//        ca.set(ca.get(Calendar.YEAR), ca.get(Calendar.MONTH),ca.get(Calendar.DATE),23,59,59);
        // 也可这样写
        ca.set(Calendar.HOUR_OF_DAY,23);
        ca.set(Calendar.MINUTE,59);
        ca.set(Calendar.SECOND,59);
        String end = sdf.format(ca.getTime());

        ca.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        ca.set(Calendar.HOUR_OF_DAY,0);
        ca.set(Calendar.MINUTE, 0);
        ca.set(Calendar.SECOND,0);
        String start = sdf.format(ca.getTime());

        System.out.println(start+"|"+end);
    }

计算本月的开始时间和结束时间

public static void getThisMonthDate(){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Calendar cc2 = Calendar.getInstance();
    // 指定日历字段可以具有的最大值 DAY_OF_MONTH 的最大值就是当月最后一天
    int maxMonthDay = cc2.getActualMaximum(Calendar.DAY_OF_MONTH);
    cc2.set(cc2.get(Calendar.YEAR), cc2.get(Calendar.MONTH),maxMonthDay,23,59,59);
    String end = sdf.format(cc2.getTime());

    cc2.set(cc2.get(Calendar.YEAR), cc2.get(Calendar.MONTH),1,0,0,0);
    String start = sdf.format(cc2.getTime());

    System.out.println(start+"|"+end);
}

计算两日期相隔天数

public static int getDaysBetween (Calendar d1, Calendar d2){
    if (d1.after(d2)){  // 保证 d1 开始 d2 结束
        Calendar swap = d1;
        d1 = d2;
        d2 = swap;
    }
    // d2.get(Calendar.DAY_OF_YEAR) 当年第几天
    // d1.get(Calendar.DAY_OF_YEAR) 当年第几天
    System.out.println(d2.get(Calendar.DAY_OF_YEAR));
    System.out.println(d1.get(Calendar.DAY_OF_YEAR));
    int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);

    int y2 = d2.get(Calendar.YEAR);
    // 是否是同一年
    if (d1.get(Calendar.YEAR) != y2){
        d1 = (Calendar) d1.clone();
        do{
            days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);//得到当年的实际天数
            d1.add(Calendar.YEAR, 1);
        } while (d1.get(Calendar.YEAR) != y2);
    }
    System.out.println(days);
    return days;
}

public static void main(String[] args) throws ParseException {
    Calendar instance1 = Calendar.getInstance();
    Calendar instance2 = Calendar.getInstance();
    instance1.setTime(new SimpleDateFormat("yyyy MM dd HH:mm:ss").parse("2022 10 18 00:00:00"));
    instance2.setTime(new SimpleDateFormat("yyyy MM dd HH:mm:ss").parse("2021 10 18 00:00:00"));
    getDaysBetween(instance1,instance2);
}

计算某月份的最大天数

计算某一月份的最大天数
Calendar time=Calendar.getInstance(); 
time.clear(); 
time.set(Calendar.YEAR,year); 
time.set(Calendar.MONTH,i-1);//注意,Calendar对象默认一月为0             
int day=time.getActualMaximum(Calendar.DAY_OF_MONTH);//本月份的天数
注:在使用set方法之前,必须先clear一下,否则很多信息会继承自系统当前时间

其他计算

public static void test() throws ParseException {
    // 字符串转换日期格式
    DateFormat fmtDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // 得到日期格式对象
    Date date = fmtDateTime.parse("2022-10-18 00:00:00");
    System.out.println(date);

    // 完整显示日期时间
    String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());
    System.out.println(format);

    // 创建 Calendar 对象,默认当前时间
    Calendar calendar = Calendar.getInstance();
    System.out.println(calendar.getTime());
    // 初始化 Calendar 对象,但并不必要,除非需要重置时间
    calendar.setTime(date);
    System.out.println(calendar.getTime());

    // 显示年份
    int year = calendar.get(Calendar.YEAR);
    System.out.println(year);

    // 显示月份 (从0开始, 实际显示要加一)
    int month = calendar.get(Calendar.MONTH);
    System.out.println(month+1);

    // 今年的第 N 天
    int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
    System.out.println(dayOfYear);

    // 本月第 N 天 (几号)
    int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(dayOfMonth);

    // 3小时以后
    // Calendar.HOUR;           12 小时
    // Calendar.HOUR_OF_DAY     24 小时
    calendar.add(Calendar.HOUR_OF_DAY,3);
    int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY);
    System.out.println(hourOfDay);

    // 当前分钟数
    int minute = calendar.get(Calendar.MINUTE);
    System.out.println(minute);

    // 15 分钟以后
    calendar.add(Calendar.MINUTE,15);
    int minute15 = calendar.get(Calendar.MINUTE);
    System.out.println(minute15);

    // 30分钟前
    calendar.add(Calendar.MINUTE,-30);
    int minute_30 = calendar.get(Calendar.MINUTE);
    System.out.println(minute_30);

    // 日期比较
    // 创建一个 Calendar 用于比较时间
    calendar.setTime(date);
    Calendar calendarNew = Calendar.getInstance();
    calendarNew.setTime(date);

    // 新日期设定为 5 小时以前,后者大,显示 -1
    calendarNew.add(Calendar.HOUR, -5);
    System.out.println("时间比较:" + calendarNew.compareTo(calendar));

    // 设定7小时以后,前者大,显示 1
    calendarNew.add(Calendar.HOUR, +7);
    System.out.println("时间比较:" + calendarNew.compareTo(calendar));

    // 退回 2 小时,时间相同,显示 0
    calendarNew.setTime(date);
    System.out.println("时间比较:" + calendarNew.compareTo(calendar));
}

设置时区

TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));  
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));  
c.setTime(date);

Calendar API 文档

Calendar API 文档

时区转换

// 太平洋时间是美国用的时间PST=UTC-8h太平洋标准时。
// 北京时间=UTC+8h=PST+8+8=PST+16h。

太平洋时间 UTC

UTC是现在用的时间标准,根据原子钟来计算时间,UTC更加精确。

格林尼治标准时间 GMT

GMT是老的时间计量标准,根据地球的自转和公转来计算时间。就是英国格林威治时间,也就是世界标准时间,是本初子午线上的地方时,是0时区的区时,与我国的标准时间北京时间(东八区)相差8小时,即晚8小时。

北京时间

北京时间=GMT时间+8小时。

美国时间 PST

PST=UTC-8小时。

示例

public static void timezone() throws ParseException {
    // 1. 设置默认时区
    TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
    System.out.println(TimeZone.getDefault());

    // 2. 获取可用时区列表
    for (int i = 0; i < TimeZone.getAvailableIDs().length; i++) {
        System.out.println(TimeZone.getAvailableIDs()[i]);
    }

    SimpleDateFormat foo = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    System.out.println("foo:" + foo.format(new Date()));

    Calendar gc = GregorianCalendar.getInstance();
    System.out.println("gc.getTime():" + gc.getTime());
    System.out.println("gc.getTimeInMillis():" + new Date(gc.getTimeInMillis()));

    // 当前系统默认时区的时间:
    Calendar calendar = new GregorianCalendar();
    System.out.print("时区:" + calendar.getTimeZone().getID() + "  ");
    System.out.println("时间:" + calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE));
    // 美国洛杉矶时区
    TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
    // 时区转换
    calendar.setTimeZone(tz);
    System.out.print("时区:" + calendar.getTimeZone().getID() + "  ");
    System.out.println("时间:" + calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE));
    Date time = new Date();

    // 1、取得本地时间:
    java.util.Calendar cal = java.util.Calendar.getInstance();

    // 2、取得时间偏移量:
    int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET);

    // 3、取得夏令时差:
    int dstOffset = cal.get(java.util.Calendar.DST_OFFSET);

    // 4、从本地时间里扣除这些差量,即可以取得UTC时间:
    cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));

    // 太平洋时间是美国用的时间PST=UTC-8h太平洋标准时。
    // 北京时间=UTC+8h=PST+8+8=PST+16h。
    // 之后调用cal.get(int x)或cal.getTimeInMillis()方法所取得的时间即是UTC标准时间。
    System.out.println("UTC:" + new Date(cal.getTimeInMillis()));

    Calendar calendar1 = Calendar.getInstance();
    TimeZone tztz = TimeZone.getTimeZone("GMT");
    calendar1.setTimeZone(tztz);
    System.out.println(calendar.getTime());
    System.out.println(calendar.getTimeInMillis());


    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    Date t = new Date();
    System.out.println(df1.format(t));
    System.out.println(df1.format(df1.parse("2014-08-27T18:02:59.676Z")) + "***********");
    df1.setTimeZone(TimeZone.getTimeZone("UTC"));
    System.out.println(df1.format(t));
    System.out.println("-----------");
    System.out.println(df1.format(df1.parse("2014-08-27T18:02:59.676Z")) + "***********");
    System.out.println("2014-08-27T18:02:59.676Z");

}