使用Calendar遇到的坑

Calendar.HOUR和Calendar.HOUR_OF_DAY

  • 背景:需要判断某个时间段(该时间段不会跨天)是否在当天,于是用到Calender获取当天的开始和结束时间。
    错误使用如下:
Calendar todayStart = Calendar.getInstance();
todayStart.set(Calendar.HOUR, 0); // 此处错误
todayStart.set(Calendar.MINUTE, 0);
todayStart.set(Calendar.SECOND, 0);
todayStart.set(Calendar.MILLISECOND, 0);
Long todayStart = todayStart.getTimeInMillis();
Calendar todayEnd = Calendar.getInstance();
todayEnd.set(Calendar.HOUR, 23); // 此处错误
todayEnd.set(Calendar.MINUTE, 59);
todayEnd.set(Calendar.SECOND, 59);
todayEnd.set(Calendar.MILLISECOND, 999);
Long todayEnd = todayEnd.getTimeInMillis();

在当天0-12点获取到的时间戳和转出得时间如下,可以看到没有问题。

使用Calendar遇到的坑_第1张图片

而从12点到24点之间使用上述代码获取到的时间戳和转出得到的时间如下,可以看到下午运行得到的是当天12点到隔天12点的时间。

使用Calendar遇到的坑_第2张图片

也就是说,这种使用方法在上午是没有问题的,只有到下午才会触发bug,由于测试是在上午测试的(需求很简单,测的时间比较短),没有排查到问题,于是在上线之后的下午发现数据异常,导致了线上bug,第一次遇到线上bug,可紧张了呢T_T

看Calendar对HOUR和HOUR_OF_DAY的注释:

/**
     * Field number for get and set indicating the
     * hour of the morning or afternoon. HOUR is used for the
     * 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12.
     * E.g., at 10:04:15.250 PM the HOUR is 10.
     *
     * @see #AM_PM
     * @see #HOUR_OF_DAY
     */
    public final static int HOUR = 10;

    /**
     * Field number for get and set indicating the
     * hour of the day. HOUR_OF_DAY is used for the 24-hour clock.
     * E.g., at 10:04:15.250 PM the HOUR_OF_DAY is 22.
     *
     * @see #HOUR
     */
    public final static int HOUR_OF_DAY = 11;

也就是HOUR是12小时制的,HOUR_OF_DAY是24小时制的,使用HOUR_OF_DAY才是正确的使用方式。

以下是正确使用姿势:

Calendar todayStart = Calendar.getInstance();
todayStart.set(Calendar.HOUR_OF_DAY, 0); // 此处正确
todayStart.set(Calendar.MINUTE, 0);
todayStart.set(Calendar.SECOND, 0);
todayStart.set(Calendar.MILLISECOND, 0);
Long todayStart = todayStart.getTimeInMillis();
Calendar todayEnd = Calendar.getInstance();
todayEnd.set(Calendar.HOUR_OF_DAY, 23); // 此处正确
todayEnd.set(Calendar.MINUTE, 59);
todayEnd.set(Calendar.SECOND, 59);
todayEnd.set(Calendar.MILLISECOND, 999);
Long todayEnd = todayEnd.getTimeInMillis();

你可能感兴趣的:(java)