簡體   English   中英

獲取Java中所有夜間的日期

[英]Get all night time dates in Java

我一直在嘗試對犯罪列表進行排序,並將對象分為白天和夜間列表。 因此,白天可以在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。是否有更好的方法讓我解決?

您唯一需要更改的是將&&替換為||。 這是新的if語句

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

tl; dr

正如喬治·福克斯(George Fox)的正確答案所說,對您問題的直接答案是使用邏輯或而不是與。

但是您的代碼還有其他問題:

  • 忽略時區的關鍵問題
  • 使用流血的可怕日期時間類 ,現在已經過時了。

程式碼片段:

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的格式指定正確的時區名稱 ,例如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 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.time框架內置於Java 8及更高版本中。 這些類取代了麻煩的舊的舊式日期時間類,例如java.util.DateCalendarSimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time類。

要了解更多信息,請參見Oracle教程 並在Stack Overflow中搜索許多示例和說明。 規格為JSR 310

您可以直接與數據庫交換java.time對象。 使用與JDBC 4.2或更高版本兼容的JDBC驅動程序 不需要字符串,不需要java.sql.*類。

在哪里獲取java.time類?

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目為將來可能在java.time中添加內容提供了一個試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM