2017-05-12 208 views
0

問題:你是如何處理這些用例的?LocalDate:缺少方法isEqualOrBefore isEqualOrAfter

  • 你使用靜態輔助方法嗎?
  • 你使用verbose equals後跟isAfter/isBefore嗎?
  • 你使用否定相反的條件嗎?
  • 你使用第三方庫助手嗎?

在日常業務中,我經常需要檢查日期a < =日期b或日期a> =日期b。

互聯網通常建議使用isBefore/isAfter方法的否定版本。

在實踐中我發現,我

  • 幾乎從來沒有得到這些否定比較正確的第一次嘗試(他們應該是直觀和容易)。
  • 也很難讀碼

我想我的一部分仍然希望,我只是忽略了API中的相應方法(請!)當理解業務邏輯。

/** 
    * @return true if candidate >= reference </br> 
    *   or in other words: <code>candidate.equals(reference) || candidate.isAfter(reference)</code> </br> 
    *   or in other words: <code>!candidate.isBefore(reference) </br> 
    *   or in other words: <code>candidate.compareTo(reference) >= 0 
    */ 
    public static boolean isEqualOrAfter(LocalDate candidate, LocalDate reference) 
    { 
    return !candidate.isBefore(reference); 
    } 

    /** 
    * @return true if candidate <= reference </br> 
    *   or in other words: <code>candidate.equals(reference) || candidate.isBefore(reference)</code> </br> 
    *   or in other words: <code>!candidate.isAfter(reference) </br> 
    *   or in other words: <code>candidate.compareTo(reference) <= 0 
    */ 
    public static boolean isEqualOrBefore(LocalDate candidate, LocalDate reference) 
    { 
    return !candidate.isAfter(reference); 
    } 

編輯:由於由Andreas建議,我加入了版本compareTo方法,我希望我得到了他們的權利(未經測試)。

編輯2:例:

// Manager says: "Show me everything from 3 days ago or later" or "show me everything that's at most 3 days old" 
for(Item item : items) { 
    // negation idiom 
    if(!item.getDate().isBefore(LocalDate.now().minusDays(3))) { 
    // show 
    } 

    // compareTo idiom 
    if(item.getDate().compareTo(LocalDate.now().minusDays(3)) >= 0) { 
    // show 
    } 

    // desired 
    if(item.getDate().isEqualOrAfter(LocalDate.now().minusDays(3))) { 
    // show 
    } 
} 
+0

你不需要equals方法,前後都足夠了。要使用equals()來測試相等性。 –

+0

@StimpsonCat @StimpsonCat @StimpsonCat在技術上你當然是對的,但這個問題的關鍵在於抱怨它根本不方便(而且對我和其他人來說非常容易出錯) – Zalumon

+2

投票結束爲「主要基於意見的」,因爲對「你如何處理這些用例?」的回答完全是基於觀點的。 ---但是,你忘記列出'compareTo()'。請注意,a.isAfter(b),a.isBefore(b)和a.isEqual(b)與a.compareTo(b)> 0完全相同,a.compareTo( b)<0'和'a.compareTo(b)== 0',所以你的'a.isEqualOrAfter(b)'和'a.isEqualOrBefore(b)'與'a.compareTo(b) )> = 0'和'a.compareTo(b)<= 0'。 – Andreas

回答

3

的compareTo是對於這些類型的(當然它們實現可比)是否一致? 記得聯文檔暗示「成語」:

(a.compareTo(b) <operator> 0), so 

for isEqualOrBefore: (a.compareTo(b) <= 0) 
for isEqualOrAfter: (a.compareTo(b) >= 0) 
+0

是的,我認爲他們是,正如安德烈亞斯已經指出的那樣。我將這些選項包含在我的問題代碼中。然而,除了可讀性問題之外,就我看來,只有問你自己這個方法是否一致纔會使得這個方法不如isEqualOrAfter。 – Zalumon

+0

好的,直到發佈後纔看到更新。我經常得到compareTo錯誤 - ,直到我在類文件中讀取該行爲止! – nsandersen

+3

自從Java 1.0以來,它是'BigDecimal'中常見的成語。查看['BigDecimal.compareTo()']的javadoc(https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#compareTo-java.math.BigDecimal-):*該方法優先於六個布爾比較運算符('<', '==', '>','> =','!=','<=')中的每一個的單獨方法。進行這些比較的建議習慣用法是:'(x.compareTo(y)''0)',其中是六個比較運算符之一* – Andreas

3

的方法你尋求的unnecesary。你就是這麼做的:

isEqualOrBefore == !isAfter 
isEqualOrAfter == !isBefore 
+0

看到這正是我強烈反對的地方(以及爲什麼Andreas將這個問題標記爲主要基於意見的原因)。我覺得這個建議的解決方案不方便,不太可讀,並且很容易出錯(以我的經驗)。 – Zalumon

+0

另外我會爭辯說,我尋求這些方法的事實使他們有必要。 – Zalumon

+1

沒有必要的問題,他們沒有必要。你可能認爲它們方便可讀,但我不同意你的看法。我所提出的只是對於不注意最重要的'!'的粗心大意或新手程序員而言「容易出錯」。沒有注意到這個錯誤只會發生一次。至於你的建議,我不喜歡它。像「isEqualOrBefore」這樣的長方法名稱的可讀性要差得多,主要是因爲它們由許多單詞組成,並且一看不到它們。其次,如果我不得不,我會把它命名爲isBeforeOrEqual,以區分2更好。 – Dariusz