最近遇到的一个需求

2023-02-11 11:25:04 +08:00
 jvee

判断两个日期是否在同一个半年: 比如:2023-01-03 和 2023-06-30 true 2023-06-30 和 2023-07-01 false 各位彦祖们有没有比较优雅的算法

1908 次点击
所在节点    问与答
14 条回复
jmc891205
2023-02-11 11:41:02 +08:00
return (Y1 == Y2) && ((M1<=6 && M2<=6) || (M1>=7 && M2 >=7))
这样就可以吧
dethan
2023-02-11 11:43:38 +08:00
不太优雅的:a 和 b 为月份,上半年 Math.max(a, b)<=6 ,下半年 Math.min(a, b)>6
bojackhorseman
2023-02-11 11:44:28 +08:00
先判断是不是同一年,再判断是否同时小于等于 6.30 或同时大于 6.30
qeqv
2023-02-11 11:45:45 +08:00
这还需要算法吗,按照你的描述,只要年份一样,月份分为两个区间不就算出来了?
christin
2023-02-11 11:47:43 +08:00
想减看月份是不是大于 6 不就行了……
mk3s
2023-02-11 11:50:27 +08:00
@christin 嗨呀,给你点个赞,好思路,再补充一下,大于等于且同一年
zhaoxin
2023-02-11 12:03:48 +08:00
@mk3s 你俩在搞笑吧。到底有没有看原博啊。这个半年指的是上半年和下半年。不是你俩以为的时长小于六个月。

算法应该是先比较年,如果年不同,则否。否则看月份,如果两个都在 1-6 月或两个都在 7-12 月,则是;否则则否。所以 1 楼的就是正确答案。
ETiV
2023-02-11 12:08:10 +08:00
转成数字处理,(年度相同)且 [(月份数字-1 )/6] 的整数部分相同

let sameSemiYear = (ymd1, ymd2) => {
let ym1 = parseInt(ymd1.replace(/-\d+$/, '').replace('-','')), ym2 = parseInt(ymd2.replace(/-\d+$/, '').replace('-',''))
return Math.floor(ym1/100) === Math.floor(ym2/100) && Math.floor((ym1-1)%100/6) === Math.floor((ym2-1)%100/6)
}

sameSemiYear('2023-01-03', '2023-06-30') // true
sameSemiYear('2023-06-30', '2023-07-01') // false
ershierdu
2023-02-11 12:54:31 +08:00
优雅的没有,但我有一个足够不优雅的 ( doge
P.S.,纯属开玩笑,代码没有经过测试

return ((y1 * 16 + m1 + 1) ^ (y2 * 16 + m2 + 1)) // 8 == 0
IvanLi127
2023-02-11 13:43:29 +08:00
我没有优雅的算法,但我有优雅的写法。

把楼上的答案封到库里,调用的时候就优雅了
gaobing
2023-02-11 14:26:59 +08:00
精简下问题,发现只和月份有关。
所以,你只需要把 月份 除以 6 ,判断值是否相同即可:
return m1 / 6 == m2 / 6 。
gaobing
2023-02-11 14:28:45 +08:00
@gaobing 不好意思,和年份月份有关, (y1 == y2) && (m1 / 6 == m2 / 6 )
gaobing
2023-02-11 15:10:38 +08:00
@gaobing 半睡半醒的时候尽量不要发帖......,再修正一下:(y1 == y2) && (m1 / 7 == m2 / 7 )
Jtyczc
2023-02-12 02:21:23 +08:00
应该是转化为时间戳来计算。

https://apidoc.gitee.com/dromara/hutool/

betweenMonth
public long betweenMonth(boolean isReset)
计算两个日期相差月数
在非重置情况下,如果起始日期的天大于结束日期的天,月数要少算 1 (不足 1 个月)
Parameters:
isReset - 是否重置时间为起始时间(重置天时分秒)
Returns:
相差月数
Since:
3.0.8


```java
public DateBetween(Date begin, Date end, boolean isAbs) {
Assert.notNull(begin, "Begin date is null !", new Object[0]);
Assert.notNull(end, "End date is null !", new Object[0]);
if (isAbs && begin.after(end)) {
this.begin = end;
this.end = begin;
} else {
this.begin = begin;
this.end = end;
}

}



public long betweenMonth(boolean isReset) {
Calendar beginCal = DateUtil.calendar(this.begin);
Calendar endCal = DateUtil.calendar(this.end);
int betweenYear = endCal.get(1) - beginCal.get(1);
int betweenMonthOfYear = endCal.get(2) - beginCal.get(2);
int result = betweenYear * 12 + betweenMonthOfYear;
if (!isReset) {
endCal.set(1, beginCal.get(1));
endCal.set(2, beginCal.get(2));
long between = endCal.getTimeInMillis() - beginCal.getTimeInMillis();
if (between < 0L) {
return (long)(result - 1);
}
}

return (long)result;
}
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/915110

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX