2017-05-02 50 views
0

我需要在R編程語言中重現水壺Dateif函數。我需要'過期月份'選項。我認爲複製會很容易,但是我在pentaho中有一些'奇怪的行爲'。作爲一個例子:水壺Dateif月份問題

ID DATE_1日期2 monthly_difference_kettle daydiff_mysql

15943 31/12/2013 28/07/2014 7 209

15943 31/12/2011 27/07/2012 6 209

因此,在pentaho壺中,我使用公式步驟和函數DATEDIF(date2,date1,「m」)。正如你可以看到當我計算每日差異在MySQL中,我得到的兩個記錄的差異天數相同(209),但是,當通過pentaho壺中的公式步長計算每月差異時,我會在幾個月內得到不同的結果(分別爲7和6)。我不明白這是如何計算的...

任何人都可以在pentaho中生成'DATEDIF months'函數的源代碼嗎?我想在R中重現它,所以我得到完全相同的結果。

由於提前, 最好的問候,

+0

爲什麼你的樣本行中有不同的日期?第二行包括2月29日,因爲2012年是閏年,而2014年不是。這可能是一方或另一方閏年處理中的一個錯誤。 – Cyrus

回答

2

不知道有關MySQL,但我認爲這是一樣的。在PostgreSQL中,日期差異給出整數值(以天爲單位)。這意味着兩行都有幾天完全匹配。

計算月份差異不重要。什麼是月份(28,30,31天)?如果月份不滿,我們可以算一下嗎?

文檔狀態如果沒有日期之間的整月,0將根據源代碼,簡單易懂返回

但如何計算DATEDIF:

的源代碼可以通過github上https://github.com/pentaho/pentaho-reporting/blob/f7defbcfc0e8f48ad2b139fe9820445f052e0e78/libraries/libformula/src/main/java/org/pentaho/reporting/libraries/formula/function/datetime/DateDifFunction.java

private int addFieldLoop(final GregorianCalendar c, final GregorianCalendar target, final int field) { 
c.set(Calendar.MILLISECOND, 0); 
c.set(Calendar.SECOND, 0); 
c.set(Calendar.MINUTE, 0); 
c.set(Calendar.HOUR_OF_DAY, 0); 

target.set(Calendar.MILLISECOND, 0); 
target.set(Calendar.SECOND, 0); 
target.set(Calendar.MINUTE, 0); 
target.set(Calendar.HOUR_OF_DAY, 0); 

if (c.getTimeInMillis() == target.getTimeInMillis()) { 
    return 0; 
} 

int count = 0; 
while (true) { 
    c.add(field, 1); 
    if (c.getTimeInMillis() > target.getTimeInMillis()) { 
    return count; 
    } 
    count += 1; 
} 
} 

追加1個月開始日期,直到它會變大然後結束日期

+2

值得一提的是GregorianCalendar.add()方法在數月內的工作方式。一旦您在2013年12月31日之前添加1個月,您將獲得31/01/2014。然後你會得到28/02/2014然後28/03/2012,等等。這樣,在第7次迭代中,您將準確到達2014年7月28日,並且您需要再次迭代超過目標日期。從2011年12月31日開始經過7次迭代後,您將到達2014年7月29日,因此超出了目標日期。 addFieldLoop返回的值是迭代數字-1。 – user4637357

+0

感謝您的澄清,這有很大幫助。所以當2月份「傳遞」時,它實際上會有一些奇怪的現象,而不是直到下個月結束纔會進入2月份的天數? 這將是在以下情況下,同樣的情況: 說,我需要從31/03/2015去30/09/2016: 開始:31/03/2015 + 1個月 30/04/2015 + 1個月 2015年5月30日 - >代替正常31/05/2015 + 1個月 30/06/2015 + 1個月 2015年7月30日 - >而不是正常31/07/2015 因此,規則將採取最低的'日數'在循環中進一步? 在此先感謝 – tibo

+1

是的,它似乎是如此。這是由循環打印的行,在c.add()之後打印後,從31/03/205開始到2016年9月30日(我已將月份增加1,以便它不會從0):2015/4/30 - > 2015/5/30 - > 2015/6/30 - > 2015/7/30 - > 2015/8/30 - > 2015/9/30 - > 2015/10/30 - > 2015/11/30 - > 2015/12/30 - > 2016/1/30 - > 2016/2/29 - > 2016/3/29 - > 2016/4/29 - > 2016/5/29 - > 2016/6/29 - > 2016/7/29 - > 2016/8/29 - > 2016/9/29 - > 2016/10/29 – user4637357