关于日期单双日,星期判断

本文详细介绍了如何在Java中进行日期的获取、判断与调整,包括获取前天日期、判断单双号及周几,以及在原有日期基础上加一天的算法实现。通过具体的代码示例,展示了日期逻辑处理的细节,如单双号逻辑、休息日处理和星期收货判断等。

1,获取前天日期

Date d = new Date(System.currentTimeMillis() - 2 * 1000 * 60 * 60 * 24);
SimpleDateFormat sp = new SimpleDateFormat("yyyyMMdd");
pbProductMapper.deleteProduct(sp.format(d));

2,判断单双号,周几,在原来日期基础上加一天

/**
 * 判断星期是否可收货
 *
 * @param data
 * @param planDeliveryDate
 */
private String checkWeek(LocationDeliveryCycle data, String planDeliveryDate) {
   String newDay = planDeliveryDate;
   // 原来到货日期是星期几
   Date date = DateUtils.strToDate(planDeliveryDate, DateUtils.yyyyMMdd);
   int weekDate = getWeekOfDate(date);
   if (StringUtils.isEmpty(data.getOrderingCycleW())) {
      return newDay;
   } else {
      if (!BizConstant.DELIVERY_WEEK.equals(data.getOrderingCycleW().substring(weekDate, weekDate + 1))) {
         newDay = addOneDay(planDeliveryDate);
         //场景到货日期是周日,不作业, 周一三五收食品 周二四六收用品,当前是用品,这时推一天,周一,但是用品二四六收,要再推一天
         //先判断当前是不是周日,再判断周,是否符合规则;不用管是不是周日,再判断一次
         Date sunDate = DateUtils.strToDate(newDay, DateUtils.yyyyMMdd);
         int sunday = getWeekOfDate(sunDate);
         if (!BizConstant.DELIVERY_WEEK.equals(data.getOrderingCycleW().substring(sunday, sunday + 1))) {
            newDay = addOneDay(newDay);
         }
      }
   }
   return newDay;
}


/**
 * 单双号逻辑处理
 * @param cycle
 * @param planDeliveryDate
 * @return
 */
private String checkDate(LocationDeliveryCycle cycle, String planDeliveryDate) {
   String newDay = planDeliveryDate;
   String orderingCycleT = cycle.getOrderingCycleT();
   // 未维护或每天
   if (StringUtils.isEmpty(orderingCycleT) || orderingCycleT.equals(OrderingCycleEnum.DURING_FLAG_T_E.getValue())) {
      return newDay;
   }

   //单号/双号
   newDay = dealDoubleAndSingle(orderingCycleT, planDeliveryDate);
   return newDay;
}

/**
 * 休息日
 * @param cycle
 * @param planDeliveryDate
 */
private String checkHolidayDate(LocationDeliveryCycle cycle, String planDeliveryDate) {
   String newDay = planDeliveryDate;
   String orderingCycleH = cycle.getOrderingCycleH();
   // 未维护
   if (StringUtils.isEmpty(orderingCycleH)) {
      return newDay;
   }

   List<String> list = Arrays.asList(orderingCycleH.split(","));
   String day = planDeliveryDate.substring(6, planDeliveryDate.length());
   if (list.get(0).equals(day)) {
      newDay = addOneDay(planDeliveryDate);
   }
   return newDay;
}

/**
 * 在原来日期基础上加一天
 *
 * @param day
 */
public String addOneDay(String day) {
   Date date = DateUtils.strToDate(day, DateUtils.yyyyMMdd);
   day = DateUtils.dateToStr(DateUtil.calculateDate(date, Calendar.DATE, 1), DateUtils.yyyyMMdd);
   return day;
}

/**
 * 处理日期单双号配置
 *
 * @param cycleType
 * @param day
 */
private String dealDoubleAndSingle(String cycleType, String day) {
   String planDeliveryDate = day;
   if (StringUtil.isEmpty(day)) {
      return day;
   }
   //双号
   if (cycleType.equals(OrderingCycleEnum.DURING_FLAG_T_S.getValue())) {
      if (Integer.valueOf(day) % 2 == 0) {
         return day;
      } else {
         //获取当天第二天日期
         planDeliveryDate = addOneDay(day);
         //特殊场景:当前是31号,食品/食品双号收,推一天,1号,还是不收,解决:如果双号收,且是31号,直接推两天
         if (BizConstant.IS_31.equals(day.substring(6, day.length()))) {
            Date date = DateUtils.strToDate(day, DateUtils.yyyyMMdd);
            planDeliveryDate = DateUtils.dateToStr(DateUtil.calculateDate(date, Calendar.DATE, 2), DateUtils.yyyyMMdd);
         }
         return planDeliveryDate;
      }
   }
   //单号
   if (cycleType.equals(OrderingCycleEnum.DURING_FLAG_T_D.getValue())) {
      if (Integer.valueOf(day) % 2 != 0) {
         return day;
      } else {
         //获取当天第二天日期
         planDeliveryDate = addOneDay(day);
         return planDeliveryDate;
      }
   }
   return day;
}

/**
 * 获取当前日期是星期几<br>
 *
 * @param date
 * @return 当前日期是星期几
 */
public static int getWeekOfDate(Date date) {
   int[] weekDays = {6, 0, 1, 2, 3, 4, 5};
   Calendar cal = Calendar.getInstance();
   cal.setTime(date);
   int day = cal.get(Calendar.DAY_OF_WEEK) - 1;
   if (day < 0) {
      day = 0;
   }
   return weekDays[day];
}
<think>嗯,用户现在问的是用Java的位运算来判断单双数。我需要先回想一下位运算的基本知识。记得位运算符有与、或、异或、取反,还有移位操作。判断单双数的话,通常单数的二进制最后一位是1,双数是0。所以应该可以用按位与运算符来检查最后一位是否为1。 比如,n & 1的结果如果是1,说明是单数,否则是双数。这个方法应该比取模运算更快,因为位运算更底层,效率更高。不过需要确认n是否是负数的情况会不会有问题,因为Java中的位运算是用补码表示的。不过负数的话,比如-1的二进制最后一位也是1,所以-1 & 1的结果是1,会被认为是单数。但单双数的定义通常针对非负整数,所以可能需要先取绝对值或者确保输入是非负的。 然后用户可能想知道具体的代码示例,比如如何写一个函数来判断。可能还要解释为什么位运算可以这样做,以及可能的注意事项。比如,如果输入是0的话,0 & 1的结果是0,所以会被认为是双数,这没问题。另外,还要比较与n % 2 == 0的方法有什么不同,或者为什么用位运算更好。 用户可能是在学习Java的基础,或者在准备面试题,因为这类问题常出现在编程面试中。他们可能想了解更高效的写法,或者理解位运算的应用场景。也有可能用户对位运算不太熟悉,需要简单的例子来理解。 另外,可能要考虑代码的可读性。虽然位运算更高效,但有些人可能觉得n % 2更直观,特别是对新手来说。所以在实际开发中需要权衡效率和可读性,但在这个问题中,用户可能更关注技术实现。 需要给出具体的代码示例,并解释每个步骤。例如: public static boolean isEven(int n) { return (n & 1) == 0; } 然后说明当n是奇数时返回false,偶数返回true。同时指出这个方法对负数同样有效,因为补码的最低位如果是1的话,说明是奇数。比如-3的补码是...11111101,&1结果是1,所以会被正确判断为奇数。 可能还需要提到其他位运算的应用,比如快速判断某个数是否是2的幂,或者交换两个数不用临时变量,但当前问题可能不需要这些,不过相关问题可以建议用户进一步学习。 最后,要确保回答符合用户的要求,比如给出示例代码,解释原理,并可能提出相关问题,如其他位运算技巧,或者性能比较等。</think>在 Java 中,可以通过 **位运算** 快速判断一个整数是奇数(单数)还是偶数(双数)。其核心原理是:**二进制表示中,偶数的最低位一定是 0,奇数的最低位一定是 1**。 --- ### **实现原理** - 使用位运算符 `&`(按位与)判断最低位是否为 1: - 如果 `n & 1 == 0`,说明最低位为 0 → **偶数** - 如果 `n & 1 == 1`,说明最低位为 1 → **奇数** Java 中整数使用 **补码表示**,因此该方法对正数、负数和 0 均适用: - 例如:`-3` 的二进制补码为 `...11111101`,`-3 & 1 == 1` → 奇数 - `0` 的二进制为 `00000000`,`0 & 1 == 0` → 偶数 --- ### **代码示例** ```java public class EvenOddCheck { public static boolean isEven(int n) { return (n & 1) == 0; } public static void main(String[] args) { int[] numbers = {0, 1, 2, -3, 100, -100}; for (int num : numbers) { System.out.println(num + " 是 " + (isEven(num) ? "偶数" : "奇数")); } } } ``` **输出结果:** ``` 0 是 偶数 1 是 奇数 2 是 偶数 -3 是 奇数 100 是 偶数 -100 是 偶数 ``` --- ### **与取模运算的对比** - **位运算 `n & 1`**: - 更高效,直接操作二进制位。 - 适用于所有整数(包括负数)。 - **取模运算 `n % 2`**: - 可读性更高,但效率略低。 - 需注意负数取模的结果符号与除数一致(如 `-3 % 2 == -1`),需额外处理符号: ```java public static boolean isEven(int n) { return n % 2 == 0 || n % 2 == -0; // 处理负数情况 } ``` --- ### **性能优化场景** - 在需要高频判断奇偶的场景(如算法竞赛、底层系统开发),使用位运算能显著提升效率。 - 对于普通业务逻辑,可优先使用 `n % 2` 以提高代码可读性。 --- ### **扩展应用** - **快速判断 2 的幂**:`n > 0 && (n & (n - 1)) == 0` - **交换两个数**(不使用临时变量): ```java a ^= b; b ^= a; a ^= b; ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值