看看,如果目前的时间范围内一个具体的时间范围内在当天在Java
题
我确信,这样做是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");
}
我正在寻找是代码更好
- 在绩效
- 在看起来
- 在正确性
我不是在寻找
- 第三方图书馆
- 例外处理的辩论
- 变命名约定
- 方法的改性剂问题
解决方案
这是所有你应该需要这样做,这种方法是松散耦合的输入和高度协调一致。
boolean isNowBetweenDateTime(final Date s, final Date e)
{
final Date now = new Date();
return now.after(s) && now.before(e);
}
你怎么得到的日期的对象为开始和结束是不相关的比较。你做事情的方法复杂得多,需要与过往 String
表示周围。
这里是一个更好的方式得到开始和结束日期,再次松散耦合的和高度协调一致。
private Date dateFromHourMinSec(final String hhmmss)
{
if (hhmmss.matches("^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$"))
{
final String[] hms = hhmmss.split(":");
final GregorianCalendar gc = new GregorianCalendar();
gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hms[0]));
gc.set(Calendar.MINUTE, Integer.parseInt(hms[1]));
gc.set(Calendar.SECOND, Integer.parseInt(hms[2]));
gc.set(Calendar.MILLISECOND, 0);
return gc.getTime();
}
else
{
throw new IllegalArgumentException(hhmmss + " is not a valid time, expecting HH:MM:SS format");
}
}
现在你可以让两个好命名方法的呼吁,这将是相当记录。
其他提示
如指出的,凯文,模糊的棒棒糖的Regex不会挑时间14:00至19:00。
得到匹配的整整24小时时钟,可以使用这样的:
if (hhmmss.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
{
// Do stuff here
}
以下类的东西我刚创建了一些码从其他的答案。它囊括了行为的一个时期没有涉及的具体天。我们的系统是使用这类检查,如果目前的时间内我们的一个指定的维护窗。即05:00:00 - 07:00:00
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
/**
*
* @author Adam Yocum
*/
public class ExclusionTimePeriod {
private String timeStart;
private String timeEnd;
/**
* @return the timeStart
*/
public String getTimeStart() {
return timeStart;
}
/**
* @param timeStart the timeStart to set
*/
public void setTimeStart(String timeStart) {
if (timeStart.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
{
this.timeStart = timeStart;
}
else
{
throw new IllegalArgumentException(timeStart + " is not a valid time, expecting HH:MM:SS format");
}
}
/**
* @return the timeEnd
*/
public String getTimeEnd() {
return timeEnd;
}
/**
* @param timeEnd the timeEnd to set
*/
public void setTimeEnd(String timeEnd) {
if (timeEnd.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
{
this.timeEnd = timeEnd;
}
else
{
throw new IllegalArgumentException(timeEnd + " is not a valid time, expecting HH:MM:SS format");
}
}
private Date toDate(String hhmmss){
final String[] hms = hhmmss.split(":");
final GregorianCalendar gc = new GregorianCalendar();
gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hms[0]));
gc.set(Calendar.MINUTE, Integer.parseInt(hms[1]));
gc.set(Calendar.SECOND, Integer.parseInt(hms[2]));
gc.set(Calendar.MILLISECOND, 0);
Date date = gc.getTime();
return date;
}
public boolean isNowInPeriod()
{
final Date now = new Date();
return now.after(toDate(getTimeStart())) && now.before(toDate(getTimeEnd()));
}
public static void main(String[] args){
//Test All possible hours
for(int hour=0;hour<=23;hour++){
String hourStr = "";
if(hour<=9){
hourStr = "0"+hour;
}else{
hourStr = ""+hour;
}
for(int min=0;min<60;min++){
String minStr = "";
if(min<=9){
minStr = "0"+min;
}else{
minStr = ""+min;
}
for(int sec=0;sec<60;sec++){
String secStr = "";
if(sec<=9){
secStr = "0"+sec;
}else{
secStr = ""+sec;
}
String hhmmss = hourStr+":"+minStr+":"+secStr;
ExclusionTimePeriod period = new ExclusionTimePeriod();
period.setTimeStart(hhmmss);
period.setTimeEnd(hhmmss);
System.out.println(hhmmss+" Ok");
}
}
}
//Test isInPeriod functionality
ExclusionTimePeriod isInTest = new ExclusionTimePeriod();
isInTest.setTimeStart("10:00:00");
isInTest.setTimeEnd("10:43:00");
System.out.println((new Date())+" is between "+isInTest.getTimeStart()+" and "+isInTest.getTimeEnd()+" = "+isInTest.isNowInPeriod());
}
}
该dateFromHourMinSec方法是有缺陷的。它不会允许任何个小时,其中的松位数大于3,例如18:00:00.如果你改变它允许[0至2][0-9]它将允许时如29:00:00.有一个修复吗?
tl博士
LocalTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
.toLocalTime() ;
Boolean isBetween = ( ! now.isBefore( LocalTime.of( 18 , 0 ) ) // "not before" means "is equal to OR after".
&&
now.isBefore( LocalTime.of( 18 , 30 ) ) ; // Half-Open, beginning is *inclusive* while ending is *exclusive*.
使用java。时间
你正在使用的旧日时的课程已被证明是设计不当,造成混淆,并且麻烦。他们现在 遗产, 取代通过java。时间课程。
LocalTime
没有通过仅仅是串的代表每日时间值。我们现在有一种类型说, LocalTime
类。
LocalTime start = LocalTime.of( 18 , 0 );
LocalTime stop = LocalTime.of( 18 , 30 );
通过这些情况下给你的实用方法。这方法不应该做任何分析,因此不需要把分析例外。
public static boolean isCurrentTimeBetween( LocalTime start , LocalTime stop ) {
…
ZonedDateTime
一次区域至关重要的是在确定目前的日期和时间的一天。对于任何给定的时刻,日期不同世界各地的区域。例如,几分钟后在午夜 巴黎法国 是新的一天,同时仍然"昨天"在 蒙特利尔魁北克.
指定一个 适当时区名称 在格式 continent/region
, 如 America/Montreal
, Africa/Casablanca
, 或 Pacific/Auckland
.永远不会使用的3-4个字母的缩写如 EST
或 IST
因为他们是 不 真正的时区,未标准化,甚至不是唯一的(!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( z );
比较的时间的日的现在,我们可以简单地提取 LocalTime
从那 ZonedDateTime
.但是,我们有问题的异常现象,例如夏令时间(DST)和政治家重新定义时区。不能有任何下午6时在特定日期成行。解决这个难题,取决于业务方面和业务规则。你可以忽略的问题和坚持的字面要求,如果目前的时间为目标开始停止时间。或者你可以适用的时区到你开始停止时间的天天和我们 ZonedDateTime
类做出调整,因为它认为合适的。让我们看这两种方法。
忽略异常
第一,忽略任何异常情况。要求简单和从字面上,如果目前的时间是目标之间开始和结束时间的一天。
我们可以提取时的一天对象划日期间的对象。
LocalTime localTimeNow = zdt.toLocalTime(); // Extract a time-of-day from the zoned date-time object.
与此相比,我们的停止-开始时的一天。注意,我们在这里使用的半开放的方式来限定的时间跨度。在这种方法的开始是 包容 虽然结局 独家.这种方法是共同的日期非全时工作和一般是明智的路要走。
Boolean isNowOnOrAfterStart = ( ! localTimeNow.isBefore( start ) ) ; // A briefer way of asking "is equal to OR is after" is "is not before".
Boolean isNowBeforeStop = localTimeNow.isBefore( stop );
Boolean isNowInTargetZone = ( isNowOnOrAfterStart && isNowBeforeStop ); // Half-Open: beginning is inclusive while ending is exclusive.
考虑异常
接下来我们考虑的任何异常情况。我们应该开始和结束时间的日至目前的日期内相同的时区。我们中提取的日期只能从这划日期间的对象。
LocalDate localDateToday = zdt.toLocalDate();
ZonedDateTime zdtStart = ZonedDateTime.of( localDateToday , start , z );
ZonedDateTime zdtStop = ZonedDateTime.of( localDateToday , stop , z );
研究这类文件,以理解的行为 ZonedDateTime.of
在解决无效的时间的日的价值观。没有完美的方式来解决存在的时间价值的,所以你必须决定如果这类'的方式满足业务规则。
ZonedDateTime.的
public static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone)
取得的一个实例ZonedDateTime从一个地方的日期和时间。这将创建一个划日期间的匹配输入当地的日期和时间尽可能的。时间-区域规则,如夏令,意思是,不是每个地方的日期时间是有效的指定区,因此当地的日期,时间可能进行调整。
该局的日期和时间的第一个组合,以形成一个当地的日期的时间。地方一日期时间是那么解决的一个即时在时间上线。这是通过找到一个有效的偏离UTC/格林威治对当地的日期时间为限定的规则的区标识。
在大多数情况下,只有一个有效的偏用于当地的日期的时间。在这种情况下的一种重叠,当时钟设置回来,有两个有效的补偿。这种方法采用早先的偏通常应以"夏"。
在这种情况下的一个空隙,当时钟的跳跃式前进,没有任何有效抵消。相反,当地的日期时调整到以后的长度差距。对于一个典型的一个小时的夏令改变,当地的日期时将会被移一个小时后到偏通常应以"夏"。
适用相同的比较逻辑,因为我们看到了以上。
Boolean isNowOnOrAfterStart = ( ! zdt.isBefore( zdtStart ) ) ; // A briefer way of asking "is equal to OR is after" is "is not before".
Boolean isNowBeforeStop = zdt.isBefore( zdtStop );
Boolean isNowInTargetZone = ( isNowOnOrAfterStart && isNowBeforeStop ); // Half-Open: beginning is inclusive while ending is exclusive.
备选办法进行比较是以使用方便的 Interval
类从ThreeTen-额外的项目。这类需要的一个痛苦的 Instant
的对象,你可以从中提取你的 ZonedDateTime
对象。的 Instant
类表示一下时间线 UTC 与决议 毫微秒 (九(9)个数字的十进制分数)。
Interval interval = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );
Boolean isNowInTargetZone = interval.contains( zdt.toInstant() );
关于java。时间
的 java。时间 框架是建立成Java8和后。这些类别取代的麻烦老 遗产 日间课程,例如 java.util.Date
, Calendar
, & SimpleDateFormat
.
的 乔达时 项目,现在 维护模式, 建议迁移到 java。时间 课程。
若要了解更多信息,请参见的 Oracle教程.和搜索堆溢出许多实例和解释。说明书 JSR310.
在那里获得java。时间上课?
- Java SE8 和 SE9 和之后
- 内置。
- 标准的一部分API与捆绑的执行情况。
- Java9中增加了一些次要设和修复。
- Java SE6 和 SE7
- 许多java。时间功能回来了-移植到Java6&7 ThreeTen-移植.
- 安卓
- 的 ThreeTenABP 项目适应 ThreeTen-移植 (上面提到的)用于安卓具体的说明。
- 看看 如何使用ThreeTenABP....
的 ThreeTen-额外的 项目的延伸java。时与附加课程。这个项目是一个试验场于今后可能增加java。时间。你可以找一些有用的类在这里 Interval
, YearWeek
, YearQuarter
, , 更多.