summaryrefslogtreecommitdiff
path: root/forms
diff options
context:
space:
mode:
authorLionel Elie Mamane <lionel@mamane.lu>2013-03-17 08:36:26 +0100
committerLionel Elie Mamane <lionel@mamane.lu>2013-04-18 21:34:46 +0200
commit9830fd36dbdb72c79703b0c61efc027fba793c5a (patch)
tree2e9d698e6ca109dc6627adb5c84aa2b635bcfe92 /forms
parent5aaaf0694b6e3213685563fc3bc90d19b10f5c75 (diff)
date/time IDL datatypes incompatible change
- nanosecond precision - signed (allowed negative) year Also: assorted improvements / bugfixes in date/time handling code. Some factorisation of copy/pasted code. Change-Id: I761a1b0b8731c82f19a0c37acbcf43d3c06d6cd6
Diffstat (limited to 'forms')
-rw-r--r--forms/qa/integration/forms/TimeValidator.java4
-rw-r--r--forms/source/component/Time.cxx13
-rw-r--r--forms/source/xforms/convert.cxx102
-rw-r--r--forms/source/xforms/datatypes.cxx13
4 files changed, 34 insertions, 98 deletions
diff --git a/forms/qa/integration/forms/TimeValidator.java b/forms/qa/integration/forms/TimeValidator.java
index ab9f036c2b67..36d1ae8f6e90 100644
--- a/forms/qa/integration/forms/TimeValidator.java
+++ b/forms/qa/integration/forms/TimeValidator.java
@@ -70,11 +70,11 @@ public class TimeValidator extends integration.forms.ControlValidator
private boolean isInvalidTime( com.sun.star.util.Time timeValue )
{
- return ( timeValue.Hours == -1 ) && ( timeValue.Minutes == -1 ) && ( timeValue.Seconds == -1 ) && ( timeValue.HundredthSeconds == -1 );
+ return ( timeValue.Hours == -1 ) && ( timeValue.Minutes == -1 ) && ( timeValue.Seconds == -1 ) && ( timeValue.NanoSeconds == -1 );
}
private boolean isFullHour( com.sun.star.util.Time timeValue )
{
- return ( timeValue.Minutes == 0 ) && ( timeValue.Seconds == 0 ) && ( timeValue.HundredthSeconds == 0 );
+ return ( timeValue.Minutes == 0 ) && ( timeValue.Seconds == 0 ) && ( timeValue.NanoSeconds == 0 );
}
}
diff --git a/forms/source/component/Time.cxx b/forms/source/component/Time.cxx
index 7b7b56c2821c..420a317fcefd 100644
--- a/forms/source/component/Time.cxx
+++ b/forms/source/component/Time.cxx
@@ -246,7 +246,7 @@ sal_Bool OTimeModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
util::Time aTime;
if ( !( aControlValue >>= aTime ) )
{
- sal_Int32 nAsInt(0);
+ sal_Int64 nAsInt(0);
aControlValue >>= nAsInt;
aTime = DBTypeConversion::toTime(nAsInt);
}
@@ -256,7 +256,7 @@ sal_Bool OTimeModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
else
{
util::DateTime aDateTime = m_xColumn->getTimestamp();
- aDateTime.HundredthSeconds = aTime.HundredthSeconds;
+ aDateTime.NanoSeconds = aTime.NanoSeconds;
aDateTime.Seconds = aTime.Seconds;
aDateTime.Minutes = aTime.Minutes;
aDateTime.Hours = aTime.Hours;
@@ -279,7 +279,7 @@ void OTimeModel::impl_translateControlValueToUNOTime( Any& _rUNOValue ) const
_rUNOValue = getControlValue();
if ( _rUNOValue.hasValue() )
{
- sal_Int32 nTime = 0;
+ sal_Int64 nTime = 0;
OSL_VERIFY( _rUNOValue >>= nTime );
if ( nTime == ::Time( 99, 99, 99 ).GetTime() )
// "invalid time" in VCL is different from "invalid time" in UNO
@@ -305,7 +305,7 @@ Any OTimeModel::translateExternalValueToControlValue( const Any& _rExternalValue
{
util::Time aTime;
OSL_VERIFY( _rExternalValue >>= aTime );
- aControlValue <<= DBTypeConversion::toINT32( aTime );
+ aControlValue <<= DBTypeConversion::toINT64( aTime );
}
return aControlValue;
}
@@ -325,8 +325,9 @@ Any OTimeModel::translateDbColumnToControlValue()
if ( m_xColumn->wasNull() )
m_aSaveValue.clear();
else
- // the aggregated set expects an Int32 as value ...
- m_aSaveValue <<= DBTypeConversion::toINT32( aTime );
+ // TODO FIXME: "the aggregated set expects an Int32 as value ..."
+ // need to fix it for int64
+ m_aSaveValue <<= DBTypeConversion::toINT64( aTime );
return m_aSaveValue;
}
diff --git a/forms/source/xforms/convert.cxx b/forms/source/xforms/convert.cxx
index b440f4b3705f..6dac9298aa6a 100644
--- a/forms/source/xforms/convert.cxx
+++ b/forms/source/xforms/convert.cxx
@@ -33,13 +33,14 @@
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/util/Time.hpp>
+#include <unotools/datetime.hxx>
using xforms::Convert;
using com::sun::star::uno::Any;
using com::sun::star::uno::makeAny;
-using com::sun::star::util::Time;
using namespace std;
using namespace o3tl;
+using namespace utl;
typedef com::sun::star::util::Date UNODate;
typedef com::sun::star::util::Time UNOTime;
@@ -279,30 +280,7 @@ namespace
UNODate aDate( 1, 1, 1900 );
- sal_Int32 nToken = 0;
- StringTokenizer aTokenizer( rString, '-' );
- while ( aTokenizer.hasNextToken() )
- {
- sal_Int32 nTokenValue = 0;
- if ( !aTokenizer.getNextToken().toInt32( nTokenValue ) )
- {
- bWellformed = false;
- break;
- }
-
- if ( nToken == 0 )
- aDate.Year = (sal_uInt16)nTokenValue;
- else if ( nToken == 1 )
- aDate.Month = (sal_uInt16)nTokenValue;
- else if ( nToken == 2 )
- aDate.Day = (sal_uInt16)nTokenValue;
- else
- {
- bWellformed = false;
- break;
- }
- ++nToken;
- }
+ bWellformed = ISO8601parseDate(rString, aDate);
// sanity checks
if ( ( aDate.Year > 9999 ) || ( aDate.Month < 1 ) || ( aDate.Month > 12 ) || ( aDate.Day < 1 ) || ( aDate.Day > 31 ) )
@@ -337,10 +315,15 @@ namespace
lcl_appendInt32ToBuffer( rTime.Minutes, sInfo, 2 );
sInfo.appendAscii( ":" );
lcl_appendInt32ToBuffer( rTime.Seconds, sInfo, 2 );
- if ( rTime.HundredthSeconds )
+ if ( rTime.NanoSeconds != 0 )
{
- sInfo.appendAscii( "." );
- lcl_appendInt32ToBuffer( rTime.HundredthSeconds, sInfo, 2 );
+ OSL_ENSURE(rTime.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999");
+ sInfo.append('.');
+ std::ostringstream ostr;
+ ostr.fill('0');
+ ostr.width(9);
+ ostr << rTime.NanoSeconds;
+ sInfo.append(OUString::createFromAscii(ostr.str().c_str()));
}
return sInfo.makeStringAndClear();
@@ -361,62 +344,7 @@ namespace
UNOTime aTime( 0, 0, 0, 0 );
- OUString sString( rString );
- // see if there's a decimal separator for the seconds,
- // and if so, handle it separately
- sal_Int32 nDecimalSepPos = rString.indexOf( '.' );
- if ( nDecimalSepPos == -1 )
- // ISO 8601 allows for both a comma and a dot
- nDecimalSepPos = rString.indexOf( ',' );
- if ( nDecimalSepPos != -1 )
- {
- // handle fractional seconds
- OUString sFractional = sString.copy( nDecimalSepPos + 1 );
- if ( sFractional.getLength() > 2 )
- // our precision is HundrethSeconds - it's all a css.util.Time can hold
- sFractional = sFractional.copy( 0, 2 );
- if ( !sFractional.isEmpty() )
- {
- sal_Int32 nFractional = 0;
- if ( StringTokenizer( sFractional, 0 ).getNextToken().toInt32( nFractional ) )
- {
- aTime.HundredthSeconds = (sal_uInt16)nFractional;
- if ( nFractional < 10 )
- aTime.HundredthSeconds *= 10;
- }
- else
- bWellformed = false;
- }
-
- // strip the fraction before further processing
- sString = sString.copy( 0, nDecimalSepPos );
- }
-
- // split into the tokens which are separated by colon
- sal_Int32 nToken = 0;
- StringTokenizer aTokenizer( sString, ':' );
- while ( aTokenizer.hasNextToken() )
- {
- sal_Int32 nTokenValue = 0;
- if ( !aTokenizer.getNextToken().toInt32( nTokenValue ) )
- {
- bWellformed = false;
- break;
- }
-
- if ( nToken == 0 )
- aTime.Hours = (sal_uInt16)nTokenValue;
- else if ( nToken == 1 )
- aTime.Minutes = (sal_uInt16)nTokenValue;
- else if ( nToken == 2 )
- aTime.Seconds = (sal_uInt16)nTokenValue;
- else
- {
- bWellformed = false;
- break;
- }
- ++nToken;
- }
+ bWellformed = ISO8601parseTime(rString, aTime);
// sanity checks
// note that Seconds == 60 denotes leap seconds. Normally, they're not allowed everywhere,
@@ -431,7 +359,7 @@ namespace
&& ( aTime.Hours == 24 )
&& ( ( aTime.Minutes != 0 )
|| ( aTime.Seconds != 0 )
- || ( aTime.HundredthSeconds != 0 )
+ || ( aTime.NanoSeconds != 0 )
)
)
bWellformed = false;
@@ -458,7 +386,7 @@ namespace
UNODate aDate( aDateTime.Day, aDateTime.Month, aDateTime.Year );
OUString sDate = lcl_toXSD_UNODate_typed( aDate );
- UNOTime aTime( aDateTime.HundredthSeconds, aDateTime.Seconds, aDateTime.Minutes, aDateTime.Hours );
+ UNOTime aTime( aDateTime.NanoSeconds, aDateTime.Seconds, aDateTime.Minutes, aDateTime.Hours );
OUString sTime = lcl_toXSD_UNOTime_typed( aTime );
OUStringBuffer sInfo;
@@ -489,7 +417,7 @@ namespace
aTime = lcl_toUNOTime( rString.copy( nDateTimeSep + 1 ) );
}
UNODateTime aDateTime(
- aTime.HundredthSeconds, aTime.Seconds, aTime.Minutes, aTime.Hours,
+ aTime.NanoSeconds, aTime.Seconds, aTime.Minutes, aTime.Hours,
aDate.Day, aDate.Month, aDate.Year
);
return makeAny( aDateTime );
diff --git a/forms/source/xforms/datatypes.cxx b/forms/source/xforms/datatypes.cxx
index e1fcdebecf24..66dbd907856a 100644
--- a/forms/source/xforms/datatypes.cxx
+++ b/forms/source/xforms/datatypes.cxx
@@ -829,7 +829,14 @@ namespace xforms
if ( !( aTypedValue >>= aValue ) )
return false;
- ::Time aToolsTime( aValue.Hours, aValue.Minutes, aValue.Seconds, aValue.HundredthSeconds );
+ ::Time aToolsTime( aValue.Hours, aValue.Minutes, aValue.Seconds, aValue.NanoSeconds );
+ // no loss/rounding; IEEE 754 double-precision floating-point
+ // has a mantissa of 53 bits; we need at the very most 50 bits:
+ // format of aToolsTime.GetTime() is (in decimal) hhmmssnnnnnnnnn
+ // and 999999999999999 = 0x38D7EA4C67FFF
+ // in reality I doubt we need (much) more than
+ // 240000000000000 = 0x0DA475ABF0000
+ // that is 48 bits
fValue = aToolsTime.GetTime();
return true;
}
@@ -846,7 +853,7 @@ namespace xforms
{
Time aValue;
OSL_VERIFY( _rValue >>= aValue );
- ::Time aToolsTime( aValue.Hours, aValue.Minutes, aValue.Seconds, aValue.HundredthSeconds );
+ ::Time aToolsTime( aValue.Hours, aValue.Minutes, aValue.Seconds, aValue.NanoSeconds );
_rDoubleValue = aToolsTime.GetTime();
}
@@ -869,7 +876,7 @@ namespace xforms
{
::DateTime aToolsValue(
::Date( _rValue.Day, _rValue.Month, _rValue.Year ),
- ::Time( _rValue.Hours, _rValue.Minutes, _rValue.Seconds, _rValue.HundredthSeconds )
+ ::Time( _rValue.Hours, _rValue.Minutes, _rValue.Seconds, _rValue.NanoSeconds )
);
double fValue = 0;