Pentaho 每月发行日期

Pentaho 每月发行日期,pentaho,kettle,Pentaho,Kettle,我需要在R编程语言中重现cattle Datedif函数。我需要'datedif month'选项。我以为复制会很容易,但我在pentaho有一些“奇怪的行为”。例如: ID日期\u 1日期\u 2月\u差异\u壶日差异\u mysql 15943 2013年12月31日2014年7月28日7209 15943 31/12/2011 27/07/2012 6 209 所以在pentaho釜中,我使用了公式步骤和函数DATEDIF(date2,date1,“m”)。正如您所见,当我在mysql中计

我需要在R编程语言中重现cattle Datedif函数。我需要'datedif month'选项。我以为复制会很容易,但我在pentaho有一些“奇怪的行为”。例如:

ID日期\u 1日期\u 2月\u差异\u壶日差异\u mysql

15943 2013年12月31日2014年7月28日7209

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

所以在pentaho釜中,我使用了公式步骤和函数DATEDIF(date2,date1,“m”)。正如您所见,当我在mysql中计算每日差异时,我得到的两条记录的差异天数相同(209),但是,当通过pentaho釜中的公式步骤计算每月差异时,我在数月内得到的结果不同(分别为7和6)。我不明白这是怎么计算出来的

有人能在pentaho中生成“DATEDIF months”函数的源代码吗?我想在R中复制它,所以我得到了完全相同的结果

提前感谢,,
致以最诚挚的问候,

我不太清楚mysql,但我认为它是一样的。在PostgreSQL中,日期差给出整数值(以天为单位)。这意味着两行在天内完全匹配

计算月差非常重要。什么是月份(28、30、31天)?如果这个月还没满,我们算一下好吗

文档状态如果两个日期之间没有完整的月份,则返回0

但根据源代码很容易理解如何计算datedif:

源代码可通过github获得


在开始日期后加上1个月,直到它比结束日期更大

不确定mysql,但我认为它是一样的。在PostgreSQL中,日期差给出整数值(以天为单位)。这意味着两行在天内完全匹配

计算月差非常重要。什么是月份(28、30、31天)?如果这个月还没满,我们算一下好吗

文档状态如果两个日期之间没有完整的月份,则返回0

但根据源代码很容易理解如何计算datedif:

源代码可通过github获得


在开始日期后加上1个月,直到开始日期大于结束日期

为什么您的样本行中有不同的日期?第二行包括29天的二月,因为2012年是闰年,而2014年不是。这很可能是闰年处理中的一个错误。为什么在您的样本行中有不同的日期?第二行包括29天的二月,因为2012年是闰年,而2014年不是。这很可能是闰年处理中的一个错误,值得一提的是gregoriacalendar.add()方法对月份的处理方式。在2013年12月31日之前加上1个月,您将获得2014年1月31日。然后是2014年2月28日,然后是2012年3月28日,依此类推。这样,在第7次迭代中,您将精确到达2014年7月28日,并且您将需要再进行一次迭代以超过目标日期。从2011年12月31日开始,经过同样的7次迭代后,您将到达2014年7月29日,因此超过了目标日期。addFieldLoop返回的值是迭代编号-1。感谢您的澄清,这非常有帮助。所以,当“通过”二月时,它实际上做了一些奇怪的事情,不是一直持续到下个月底,而是只持续到二月的天数?在以下情况下,情况是否相同:假设我需要从2015年3月31日到2016年9月30日:开始:2015年3月31日+1个月2015年4月30日+1个月2015年5月30日-->而不是通常的2015年5月31日+1个月2015年6月30日+1个月2015年7月30日-->而不是通常的2015年7月31日,那么规则将采用最低的“天数”来进一步循环?提前谢谢是的,看起来是这样。这是这个循环打印的行,将print放在c.add()之后,从205年3月31日到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谢谢,这对我帮助很大。是我还是这种行为相当奇怪?我不得不用R写几行代码来复制这个函数。。。如果你愿意,你可以创建一个答案,我会将其作为“答案”进行营销。这就是我需要的。。。非常感谢。值得一提的是gregoriacalendar.add()方法在月份方面的工作方式。在2013年12月31日之前加上1个月,您将获得2014年1月31日。然后是2014年2月28日,然后是2012年3月28日,依此类推。这样,在第7次迭代中,您将精确到达2014年7月28日,并且您将需要再进行一次迭代以超过目标日期。从2011年12月31日开始,经过同样的7次迭代后,您将到达2014年7月29日,因此超过了目标日期。addFieldLoop返回的值是迭代编号-1。感谢您的澄清,这非常有帮助。所以,当“通过”二月时,它实际上做了一些奇怪的事情,不是一直持续到下个月底,而是只持续到二月的天数?在以下情况下,情况是否相同:假设我需要从2015年3月31日到2016年9月30日:开始:2015年3月31日+1个月2015年4月30日+1个月2015年5月30日-->而不是通常的2015年5月31日+1个月2015年6月30日+1个月2015年7月30日-->而不是通常的2015年7月31日,那么规则将采用最低的“天数”来进一步循环?提前谢谢是的,看起来是这样。这是这个循环打印的行,将print放在c.add()之后,从205年3月31日到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/2
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;
 }
}