我一直在尝试对犯罪列表进行排序,并将对象分为白天和夜间列表。因此,白天可以在6am到10pm之间,而夜间可以在10pm到6am之间。 我写了一个if语句来尝试填充夜间犯罪列表。
if(data.getDate().getHours() < 6 && data.getDate().getHours() > 22) {
System.out.println(data.getDate().toLocaleString());
nightCrimes.add(data);
}
尽管没有任何输出,并且列表仍然为空。我注意到逻辑上显然是错误的,因为特定的整数(小时)不能大于22且小于6。对我来说,还有更好的方法吗?
答案 0 :(得分:4)
您唯一需要更改的是将&&替换为||。 这是新的if语句
if(data.getDate().getHours() < 6 || data.getDate().getHours() > 22)
答案 1 :(得分:2)
正如乔治·福克斯(George Fox)的correct Answer所说,对您问题的直接答案是使用逻辑或而不是与。
但是您的代码还有其他问题:
代码段:
data
.getDate() // Using terrible old `java.time.Date` class.
.toInstant() // Convert from legacy class to modern class.
.atZone( // Adjust from UTC to your own local time zone.
ZoneId.of( "Africa/Tunis" ) // Use proper time zone name in `Continent/Region` format.
) // Returns a `ZonedDateTime` object, a moment as seen through the wall-clock time used by the people of a particular region (a time zone).
.getHour() // Returns an `int` for hour-of-day.
…(等于或大于22)或(小于6)=夜间值。
显然,您使用的是可怕的旧日期时间类,推论您对getHours
的呼叫是java.util.Date::getHours
。
这些遗留类在几年前被行业领先的 java.time 类所取代。
顺便提一下,Date::getHours
也已被弃用。
如果您使用的是java.util.Date
,那么您将忽略时区这一关键问题。 Date
代表UTC时刻,根据定义始终为UTC。
因此,除非您居住在冰岛,否则要以UTC询问一天中的小时不是 与您当地的白天和黑夜时间匹配。
首先将您的Date
转换为现代的java.time.Instant
。为此,您可以使用添加到旧类中的新方法。
Instant instant = myJavaUtilDate.toInstant() ; // Convert from legacy class to modern class.
然后为您所在的地区应用时区,以获取ZonedDateTime
。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
比较您的问题中看到的一天中的小时。
static final int MORNING_HOUR = 6 ;
static final int EVENING_HOUR = 22 ;
…
int hour = zdt.getHour() ;
boolean isNighttime =
( hour >= EVENING_HOUR ) // Include this hour.
||
( hour < MORNING_HOUR ) // Exclude this hour.
;
您可以将它们收集到Map
中,其中键是字符串“ nighttime”或“ daytime”,值是Set
个对象的Crime
。 Set
消除重复。如果您希望对犯罪进行分类,请使用SortedSet
。
Map < String, SortedSet < Crime > > dayOrNight = new HashMap <>( 2 );
dayOrNight.put( "daytime" , new TreeSet <>() );
dayOrNight.put( "nighttime" , new TreeSet <>() );
收集。
if( isNighttime ) {
dayOrNight.get( "nighttime" ).add( crime ) ;
} else { // Else, must be daytime.
dayOrNight.get( "daytime" ).add( crime ) ;
}
如果您的业务规则重新定义为部分小时数,那么让我们接下来旋转该代码以使用每日时间而不是小时数。
通常最好使用半开式方法定义时间跨度。开头是包含,结尾是包含。因此,夜晚时间从晚上10点的第一刻开始,一直到但不包括早上6点的第一刻。
提示:询问“是否等于或晚于10 PM”的较短方法是“如果不早于
LocalTime morning = LocalTime.of( 6 , 0 ) ;
LocalTime evening = LocalTime.of( 22 , 0 ) ;
LocalTime lt = zdt.toLocalTime() ;
boolean isNighttime = ( ! lt.isBefore( evening ) ) || lt.isBefore( morning ) ;
if( isNighttime ) {
dayOrNight.get( "nighttime" ).add( crime ) ;
} else { // Else, must be daytime.
dayOrNight.get( "daytime" ).add( crime ) ;
}
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。