summaryrefslogtreecommitdiff
path: root/sc/source/core/tool/interpr2.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/tool/interpr2.cxx')
-rw-r--r--sc/source/core/tool/interpr2.cxx91
1 files changed, 91 insertions, 0 deletions
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index f022e9c10a7e..4f159a043f02 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -412,6 +412,97 @@ void ScInterpreter::ScGetDiffDate360()
}
}
+//fdo#44456 function DATEDIF as defined in ODF1.2 (Par. 6.10.3)
+void ScInterpreter::ScGetDateDif()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDateDif" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ String aFormat = GetString();
+ double nDate2 = GetDouble();
+ double nDate1 = GetDouble();
+ int dd = nDate2 - nDate1;
+
+ //split dates in day, month, year for use with formats other than "d"
+ int d1, m1, y1, d2, m2, y2;
+ Date aDate = *( pFormatter->GetNullDate() );
+ aDate += (long) ::rtl::math::approxFloor( nDate1 );
+ y1 = aDate.GetYear();
+ m1 = aDate.GetMonth();
+ d1 = aDate.GetDay();
+ aDate = *( pFormatter->GetNullDate() );
+ aDate += (long) ::rtl::math::approxFloor( nDate2 );
+ y2 = aDate.GetYear();
+ m2 = aDate.GetMonth();
+ d2 = aDate.GetDay();
+
+ if ( dd == 0 )
+ PushInt( 0 ); // nothing to do...
+
+ if ( aFormat.EqualsIgnoreCaseAscii( "d" ) ) // return number of days
+ PushInt( dd );
+ else if ( aFormat.EqualsIgnoreCaseAscii( "m" ) ) // return number of months
+ {
+ int md = m2 - m1 + 12 * (y2 - y1);
+ if ( nDate2 > nDate1 )
+ {
+ if ( d2 < d1 )
+ md -= 1;
+ }
+ else
+ {
+ if ( d2 > d1 )
+ md += 1;
+ }
+ PushInt( md );
+ }
+ else if ( aFormat.EqualsIgnoreCaseAscii( "y" ) ) // return number of years
+ {
+ int yd = y2 - y1;
+ if ( y2 > y1 )
+ {
+ if ( ( m2 == m1 and d2 >= d1 ) || ( m2 > m1 ) )
+ yd = y2 - y1 - 1;
+ }
+ else
+ {
+ if ( ( m2 == m1 and d2 <= d1 ) || ( m2 < m1 ) )
+ yd = y2 - y1 + 1;
+ }
+ PushInt( yd );
+ }
+ else if ( aFormat.EqualsIgnoreCaseAscii( "md" ) ) // return number of days, ignoring months and years
+ {
+ aDate = Date( d2, m1, y1 );
+ double nd2 = double( aDate - *( pFormatter->GetNullDate() ) );
+ PushInt( nd2 - nDate1 );
+ }
+ else if ( aFormat.EqualsIgnoreCaseAscii( "ym" ) ) // return number of months, ignoring years
+ {
+ int md = m2 - m1;
+ if ( m2 > m1 )
+ {
+ if ( d2 < d1 )
+ md -= 1;
+ }
+ else
+ {
+ if ( m2 < m1 && d2 > d1 )
+ md += 1;
+ }
+ PushInt( md );
+ }
+ else if ( aFormat.EqualsIgnoreCaseAscii( "yd" ) ) // return number of days, ignoring years
+ {
+ aDate = Date( d2, m2, y1 );
+ double nd2 = double( aDate - *( pFormatter->GetNullDate() ) );
+ PushInt( nd2 - nDate1 );
+ }
+ else
+ PushIllegalArgument(); // unsupported format
+ }
+}
+
void ScInterpreter::ScGetTimeValue()
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetTimeValue" );