背景:一句话需求“我需要判断当前是否在一段时间内”
目前网上提供了很多方法,但是都是考虑了一种情况,这种情况就是先假定这个时间段是发生在同一天,比如“00:00-
23:59” ,“00:00-18:00”,
代码很简单,copy一段网上代码
但是如果考虑到跨天呢?比如 “18:00-06:00”,
“07:00-06:59”就没法很直接的判断了。
如果按上述代码 当前时间为00:46,那么我们大脑一想肯定是符号当前时间段的,但是代码却会判断不在当前时间范围内
为了满足上面案例,我的解决方案是,先判断结束时间是否小于开始时间,如果true,则认为是跨天,将开始时间减一天,结束时间按当前时间算。
尝试改下代码
main方法跑一下试试:
成功了。
似乎解决了问题。但是尝试想一下如果当前时间是”2019-05-25 19:00“呢,理论上说也是符合设定时间段的(测试的时间段”18:00-06:00“)
main跑一下试试:
代码返回了false
说明我们的逻辑有问题,原因就是我们无法确定这个时间段的开始日期和结束日期,只能通过传入的日期作为比较。上述逻辑如果DEBUG或者仔细想一下就会发现,一旦确定跨天,开始时间就变成了
传入时间减一天,即2019-05-25 18:00~2019-05-26 06:00,那么传入的时间是 2019-05-26 19:00,自然不在时间段内了。
那么我把当前结束时间+1天不就解决了这个问题么,是的,我当时也是这么想的,但是如果传入时间是00:46会发现他返回了false,就像打地鼠一般,这边打下去了,那边又上来了
所以单纯的开始时间-1,结束时间+1都是解决不了这个问题,仔细想想之后,我又想出了一个问题,如果当前时间超过12点就 把结束时间+1,没超过就把开始时间+1不就完了么?
尝试修改如下:
在跑跑上面的两个案例 即当前时间为“2019-05-26 00:46:00”和 “2019-05-26 19:46:00”
这两个都应该返回true,才对。
似乎解决了问题,就在我写这个总结之前我以为都是没毛病的,但是我忽然将时间段改为“20:00-17:59”时,好像又不好使了,如下
我的当前时间是16:46分,按照我设置的时间段想法应该只有18:00-19:59分是返回false,其他都应该在该时间段范围内,然后结果是返回了false!
看来这些方法都是行不通的,直接用时间比较是否可以?尝试修改代码如下:
把当前时间的日期也去掉,都放在同一天比较,如果当前时间大于等于开始时间或者小于等于结束时间测试上面案例都得到理论结果。
最后放出带时区校验的方法:
/**
* 比较当前时间 是否在timeArray 范围内
* @param timezone 时区
* @param timeArray 开始时间,结束时间
* @return
*/
public static boolean isInDate(Date now,String[] timeArray,String pattern,String timezone){
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
TimeZone timeZone = TimeZone.getTimeZone(timezone);
sdf.setTimeZone(timeZone);
//转换为对应时区时间
Date date = DateUtils.stringToDate(sdf.format(now),pattern);
Date start = DateUtils.stringToDate(timeArray[0],pattern);
Date end = DateUtils.stringToDate(timeArray[1],pattern);
if (start.after(end) || start.equals(end)) {
/**
* 直接用时间判断
*/
if (date.getTime() >= start.getTime() || date.getTime() <= end.getTime()) {
return true;
}
}else {
if (date.getTime() >= start.getTime() && date.getTime() <= end.getTime()) {
return true;
}
}
return false;
}
总结:遇事不能钻牛角尖,当一个方法想不通尝试换个思路试试。之前我一直在和当前日期上纠结不能自已。,导致一直无法完美的解决这么简单的问题!