获取Java中所有夜间的日期

时间:2018-12-08 19:13:42

标签: java date arraylist

我一直在尝试对犯罪列表进行排序,并将对象分为白天和夜间列表。因此,白天可以在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。对我来说,还有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

您唯一需要更改的是将&&替换为||。 这是新的if语句

if(data.getDate().getHours() < 6 || data.getDate().getHours() > 22)

答案 1 :(得分:2)

tl; dr

正如乔治·福克斯(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)=夜间值。

java.time

显然,您使用的是可怕的旧日期时间类,推论您对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/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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个对象的CrimeSet消除重复。如果您希望对犯罪进行分类,请使用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.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance 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中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore