我确信这在1000个不同的地方已经做了1000次。问题是我想知道是否有更好/标准/更快的方法来检查当前的"时间"是否在两个以hh:mm:ss
给出的时间值之间。例如,我的大业务逻辑不应该在18:00:00 and 18:30:00
之间运行。所以下面是我的想法:
public static boolean isCurrentTimeBetween(String starthhmmss, String endhhmmss) throws ParseException{
DateFormat hhmmssFormat = new SimpleDateFormat("yyyyMMddhh:mm:ss");
Date now = new Date();
String yyyMMdd = hhmmssFormat.format(now).substring(0, 8);
return(hhmmssFormat.parse(yyyMMdd+starthhmmss).before(now) &&
hhmmssFormat.parse(yyyMMdd+endhhmmss).after(now));
}
示例测试用例:
String doNotRunBetween="18:00:00,18:30:00";//read from props file
String[] hhmmss = downTime.split(",");
if(isCurrentTimeBetween(hhmmss[0], hhmmss[1])){
System.out.println("NOT OK TO RUN");
}else{
System.out.println("OK TO RUN");
}
我所寻找的是更好的代码
- 演出中
- 外貌
- 不正确
我不想看到的是
- 第三方库
- 异常处理争论
- 变量命名约定
- 方法修饰符问题
6条答案
按热度按时间iqih9akk1#
dateFromHourMinSec方法在编写时存在缺陷。它不允许第二位数字大于3的任何小时数,例如18:00:00。如果您将其更改为允许[0-2][0-9],它将允许29:00:00这样的时间。是否有修复程序?
jv4diomz2#
这就是你所需要做的,这个方法与输入是松散耦合的,并且是高度一致的。
如何获取Start和End的Date对象与比较它们无关。传递
String
表示会使事情变得比需要的更复杂。这里有一个更好的方法来获取开始和结束日期,同样是松散耦合和高度一致的。
现在,您可以进行两个命名良好的方法调用,它们将是非常自文档化的。
6yt4nkrj3#
TL;医生
使用java. time
您使用的旧的日期-时间类已经被证明是设计糟糕、混乱和麻烦的,它们现在是legacy,被java.time类所取代。
一个月一个月
不要只传递表示时间值的字符串,我们现在有了一个类型,
LocalTime
类。把这些示例传递给你的实用方法,这个方法不需要做任何解析,所以不需要抛出解析异常。
ZonedDateTime
时区对于确定当前日期和时间至关重要。对于任何给定时刻,全球各地的日期都会因时区而异。例如,在Paris France中,午夜后几分钟是新的一天,而在Montréal Québec中,这几分钟仍然是"昨天"。
以
continent/region
的格式指定proper time zone name,例如America/Montreal
、Africa/Casablanca
或Pacific/Auckland
。切勿使用3 - 4个字母的缩写,例如EST
或IST
,因为它们 * 不是 * 真正的时区,没有标准化,甚至不唯一(!)。为了比较现在的时间,我们可以简单地从
ZonedDateTime
中提取一个LocalTime
。但是我们有异常的问题,如夏令时(夏令时)和政治家重新定义时区。在特定日期可能没有任何下午6点。这个难题的解决方案取决于您的业务环境和业务规则。您可以忽略这个难题,直接询问当前时间是否在目标起止时间之间,或者将时区应用于起止时间,让ZonedDateTime
类根据需要进行调整,让我们来看看这两种方法。忽略异常
首先,忽略任何异常情况,简单而直接地询问当前时间是否在目标开始时间和目标停止时间之间。
我们可以从zoned date-time对象中提取一个time-of-day对象。
将其与我们的停止-开始时间进行比较。注意,我们在这里使用半开方法来定义时间跨度。在这种方法中,开始是 * 包含 *,而结束是 * 排除 *。这种方法在日期-时间工作中很常见,通常是明智的做法。
考虑异常
接下来,我们考虑任何异常情况。我们将一天中的开始时间和结束时间应用于同一时区内的当前日期。我们从zoned date-time对象中只提取日期。
研究类文档以了解
ZonedDateTime.of
在解析无效时间值时的行为。没有完美的方法来解析不存在的时间值,因此您必须确定此类的方法是否符合您的业务规则。public static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone)
从本地日期和时间获取ZonedDateTime的示例。这将创建与输入的本地日期和时间尽可能匹配的分区日期-时间。时区规则(如夏令时)意味着并非每个本地日期-时间都对指定的区域有效,因此可以调整本地日期-时间。
本地日期时间和第一个组合以形成本地日期时间。然后,本地日期时间被解析为时间线上的单个时刻。这是通过查找区域ID规则定义的本地日期时间相对于UTC/Greenwich的有效偏移量来实现的。
在大多数情况下,本地日期时间只有一个有效偏移量。在重叠的情况下,当时钟向后设置时,有两个有效偏移量。此方法使用通常对应于"summer"的较早偏移量。
在间隔的情况下,当时钟向前跳转时,没有有效的偏移量。相反,本地日期-时间被调整为晚间隔的长度。对于典型的一小时夏令时更改,本地日期-时间将被移动到通常对应于"summer"的偏移量的一小时后。
应用与我们上面看到的相同的比较逻辑。
另一种比较的方法是使用ThreeTen-Extra项目中的
Interval
类。该类需要Instant
对象,可以从ZonedDateTime
对象中提取。Instant
类表示UTC中时间轴上的某个时刻,分辨率为nanoseconds(最多九(9)位小数)。关于java.时间
java.time框架内置于Java 8及更高版本中,这些类取代了麻烦的旧legacy日期-时间类,如
java.util.Date
、Calendar
和SimpleDateFormat
。Joda-Time项目(现在在maintenance mode中)建议迁移到java.time类。
要了解更多信息,请参阅Oracle Tutorial。并搜索堆栈溢出以获取许多示例和解释。规范是JSR 310。
从哪里获得java. time类?
ThreeTen-Extra项目用额外的类扩展了java.time。这个项目是将来可能添加到java.time的一个试验场。您可以在这里找到一些有用的类,如
Interval
、YearWeek
、YearQuarter
和more。sg2wtvxw4#
正如Kevin所指出的,Fuzzy Lollipop的Regex不会在14:00到19:00之间拾取时间。
要匹配完整的24小时时钟,您可以使用以下命令:
nsc4cvqm5#
下面的类是我刚刚从其他答案的一些代码中创建的。它封装了一个“时间段”的行为,而不与特定日期相关。我们的系统正在使用这个类来检查当前时间是否在我们指定的维护窗口之一内。即05:00:00 - 07:00:00
pjngdqdw6#
午夜的问题
其他答案没有提到它-OP也没有问-但你真的应该考虑间隔跨越午夜的时间。
时间很紧,我特意留下了代码的“长”版本,没有缩写逻辑条件,以使它尽可能清楚地说明是什么和为什么。
冗长并不总是错的。这个方法将被隐藏在一个实用类中,两年后你会感谢自己理解了它的作用!