All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.date.DateModifier Maven / Gradle / Ivy

There is a newer version: 5.8.33
Show newest version
package cn.hutool.core.date;

import cn.hutool.core.util.ArrayUtil;

import java.util.Calendar;

/**
 * 日期修改器
* 用于实现自定义某个日期字段的调整,包括: * *
 * 1. 获取指定字段的起始时间
 * 2. 获取指定字段的四舍五入时间
 * 3. 获取指定字段的结束时间
 * 
* * @author looly */ public class DateModifier { /** * 忽略的计算的字段 */ private static final int[] IGNORE_FIELDS = new int[]{ // Calendar.HOUR_OF_DAY, // 与HOUR同名 Calendar.AM_PM, // 此字段单独处理,不参与计算起始和结束 Calendar.DAY_OF_WEEK_IN_MONTH, // 不参与计算 Calendar.DAY_OF_YEAR, // DAY_OF_MONTH体现 Calendar.WEEK_OF_MONTH, // 特殊处理 Calendar.WEEK_OF_YEAR // WEEK_OF_MONTH体现 }; /** * 修改日期 * * @param calendar {@link Calendar} * @param dateField 日期字段,即保留到哪个日期字段 * @param modifyType 修改类型,包括舍去、四舍五入、进一等 * @return 修改后的{@link Calendar} */ public static Calendar modify(Calendar calendar, int dateField, ModifyType modifyType) { return modify(calendar, dateField, modifyType, false); } /** * 修改日期,取起始值或者结束值
* 可选是否归零毫秒。 * *

* 在{@link ModifyType#TRUNCATE}模式下,毫秒始终要归零, * 但是在{@link ModifyType#CEILING}和{@link ModifyType#ROUND}模式下, * 有时候由于毫秒部分必须为0(如MySQL数据库中),因此在此加上选项。 *

* * @param calendar {@link Calendar} * @param dateField 日期字段,即保留到哪个日期字段 * @param modifyType 修改类型,包括舍去、四舍五入、进一等 * @param truncateMillisecond 是否归零毫秒 * @return 修改后的{@link Calendar} * @since 5.7.5 */ public static Calendar modify(Calendar calendar, int dateField, ModifyType modifyType, boolean truncateMillisecond) { // AM_PM上下午特殊处理 if (Calendar.AM_PM == dateField) { boolean isAM = DateUtil.isAM(calendar); switch (modifyType) { case TRUNCATE: calendar.set(Calendar.HOUR_OF_DAY, isAM ? 0 : 12); break; case CEILING: calendar.set(Calendar.HOUR_OF_DAY, isAM ? 11 : 23); break; case ROUND: int min = isAM ? 0 : 12; int max = isAM ? 11 : 23; int href = (max - min) / 2 + 1; int value = calendar.get(Calendar.HOUR_OF_DAY); calendar.set(Calendar.HOUR_OF_DAY, (value < href) ? min : max); break; } // 处理下一级别字段 return modify(calendar, dateField + 1, modifyType); } final int endField = truncateMillisecond ? Calendar.SECOND : Calendar.MILLISECOND; // 循环处理各级字段,精确到毫秒字段 for (int i = dateField + 1; i <= endField; i++) { if (ArrayUtil.contains(IGNORE_FIELDS, i)) { // 忽略无关字段(WEEK_OF_MONTH)始终不做修改 continue; } // 在计算本周的起始和结束日时,月相关的字段忽略。 if (Calendar.WEEK_OF_MONTH == dateField || Calendar.WEEK_OF_YEAR == dateField) { if (Calendar.DAY_OF_MONTH == i) { continue; } } else { // 其它情况忽略周相关字段计算 if (Calendar.DAY_OF_WEEK == i) { continue; } } modifyField(calendar, i, modifyType); } if (truncateMillisecond) { calendar.set(Calendar.MILLISECOND, 0); } return calendar; } // -------------------------------------------------------------------------------------------------- Private method start /** * 修改日期字段值 * * @param calendar {@link Calendar} * @param field 字段,见{@link Calendar} * @param modifyType {@link ModifyType} */ private static void modifyField(Calendar calendar, int field, ModifyType modifyType) { if (Calendar.HOUR == field) { // 修正小时。HOUR为12小时制,上午的结束时间为12:00,此处改为HOUR_OF_DAY: 23:59 field = Calendar.HOUR_OF_DAY; } switch (modifyType) { case TRUNCATE: calendar.set(field, DateUtil.getBeginValue(calendar, field)); break; case CEILING: calendar.set(field, DateUtil.getEndValue(calendar, field)); break; case ROUND: int min = DateUtil.getBeginValue(calendar, field); int max = DateUtil.getEndValue(calendar, field); int href; if (Calendar.DAY_OF_WEEK == field) { // 星期特殊处理,假设周一是第一天,中间的为周四 href = (min + 3) % 7; } else { href = (max - min) / 2 + 1; } int value = calendar.get(field); calendar.set(field, (value < href) ? min : max); break; } // Console.log("# {} -> {}", DateField.of(field), calendar.get(field)); } // -------------------------------------------------------------------------------------------------- Private method end /** * 修改类型 * * @author looly */ public enum ModifyType { /** * 取指定日期短的起始值. */ TRUNCATE, /** * 指定日期属性按照四舍五入处理 */ ROUND, /** * 指定日期属性按照进一法处理 */ CEILING } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy