25#include <tools/datetime.hxx>
26#include <rtl/ustrbuf.hxx>
27#include <rtl/math.hxx>
28#include <osl/diagnose.h>
36 bool checkAllNumber(std::u16string_view rString)
39 sal_Int32 nLen = rString.size();
42 while( nPos < nLen &&
' ' == rString[nPos] )
45 if( nPos < nLen &&
'-' == rString[nPos] )
50 '0' <= rString[nPos] &&
51 '9' >= rString[nPos] )
60 bool convertNumber32(sal_Int32& rValue,
61 std::u16string_view rString,
62 sal_Int32 = -1, sal_Int32 = -1)
64 if (!checkAllNumber(rString))
74 bool convertNumber64(sal_Int64& rValue,
75 std::u16string_view rString,
76 sal_Int64 = -1, sal_Int64 = -1)
78 if (!checkAllNumber(rString))
104 bool impl_getISO8601TimeToken(std::u16string_view i_str, std::size_t &nPos, OUString &resInt,
bool &bFraction, OUString &resFrac)
108 const std::size_t nEndPos =
nPos + 2;
117 if (c < c0 || c > c9)
119 resInt += OUStringChar(c);
123 if (nPos == i_str.size() || i_str[nPos] == sep)
125 if (i_str[nPos] ==
',' || i_str[nPos] ==
'.')
132 if (c ==
'Z' || c ==
'+' || c ==
'-')
140 if (c < c0 || c > c9)
142 resFrac += OUStringChar(c);
144 OSL_ENSURE(nPos == i_str.size(),
"impl_getISO8601TimeToken internal error; expected to be at end of string");
147 if (i_str[nPos] ==
'Z' || i_str[nPos] ==
'+' || i_str[nPos] ==
'-')
155 bool getISO8601TimeToken(std::u16string_view i_str, std::size_t &io_index, OUString &o_strInt,
bool &o_bFraction, OUString &o_strFrac)
159 bool bFraction =
false;
160 std::size_t
index = io_index;
161 if(!impl_getISO8601TimeToken(i_str, index, resInt, bFraction, resFrac))
168 o_bFraction = bFraction;
172 bool getISO8601TimeZoneToken(std::u16string_view i_str, std::size_t &io_index, OUString &o_strInt)
177 if (i_str[io_index] ==
'Z')
183 else if (i_str[io_index] ==
'+' || i_str[io_index] ==
'-')
187 for (; io_index < i_str.size(); ++io_index)
190 if ((c < c0 || c > c9) && c != sep)
192 o_strInt += OUStringChar(c);
236 _rOut.Day = _rDate.
GetDay();
243 _rOut =
Date(_rDate.Day, _rDate.Month, _rDate.Year);
248 _rOut.Year = _rDateTime.
GetYear();
249 _rOut.Month = _rDateTime.
GetMonth();
250 _rOut.Day = _rDateTime.
GetDay();
251 _rOut.Hours = _rDateTime.
GetHour();
252 _rOut.Minutes = _rDateTime.
GetMin();
253 _rOut.Seconds = _rDateTime.
GetSec();
259 Date aDate(_rDateTime.Day, _rDateTime.Month, _rDateTime.Year);
260 tools::Time aTime(_rDateTime.Hours, _rDateTime.Minutes, _rDateTime.Seconds, _rDateTime.NanoSeconds);
266 OUStringBuffer rBuffer(32);
267 rBuffer.append(OUString::number(
static_cast<sal_Int32
>(rDateTime.Year)) +
"-");
268 if( rDateTime.Month < 10 )
270 rBuffer.append(OUString::number(
static_cast<sal_Int32
>(rDateTime.Month)) +
"-");
271 if( rDateTime.Day < 10 )
273 rBuffer.append(
static_cast<sal_Int32
>(rDateTime.Day));
275 if( rDateTime.NanoSeconds != 0 ||
276 rDateTime.Seconds != 0 ||
277 rDateTime.Minutes != 0 ||
278 rDateTime.Hours != 0 )
281 if( rDateTime.Hours < 10 )
283 rBuffer.append(OUString::number(
static_cast<sal_Int32
>(rDateTime.Hours)) +
":");
284 if( rDateTime.Minutes < 10 )
286 rBuffer.append(OUString::number(
static_cast<sal_Int32
>(rDateTime.Minutes)) +
":");
287 if( rDateTime.Seconds < 10 )
289 rBuffer.append(
static_cast<sal_Int32
>(rDateTime.Seconds));
290 if ( rDateTime.NanoSeconds > 0)
292 OSL_ENSURE(rDateTime.NanoSeconds < 1000000000,
"NanoSeconds cannot be more than 999 999 999");
294 std::ostringstream ostr;
297 ostr << rDateTime.NanoSeconds;
298 rBuffer.appendAscii(ostr.str().c_str());
301 return rBuffer.makeStringAndClear();
307 bool bSuccess =
true;
309 std::u16string_view aDateStr, aTimeStr;
310 css::util::Date aDate;
311 css::util::Time aTime;
312 size_t nPos = rString.find(
'T' );
313 if (
nPos != std::u16string_view::npos )
315 aDateStr = rString.substr( 0,
nPos );
316 aTimeStr = rString.substr(
nPos + 1 );
323 if ( bSuccess && !aTimeStr.empty() )
330 rDateTime = css::util::DateTime(aTime.NanoSeconds, aTime.Seconds, aTime.Minutes, aTime.Hours,
331 aDate.Day, aDate.Month, aDate.Year,
false);
345 if (nDateTokens<1 || nDateTokens>3)
348 sal_Int32 nYear = 1899;
349 sal_Int32 nMonth = 12;
354 if ( !convertNumber32( nYear, strCurrentToken, 0, 9999 ) )
356 if ( nDateTokens >= 2 )
359 if (strCurrentToken.size() > 2)
361 if ( !convertNumber32( nMonth, strCurrentToken, 0, 12 ) )
364 if ( nDateTokens >= 3 )
367 if (strCurrentToken.size() > 2)
369 if ( !convertNumber32( nDay, strCurrentToken, 0, 31 ) )
373 rDate.Year =
static_cast<sal_uInt16
>(nYear);
374 rDate.Month =
static_cast<sal_uInt16
>(nMonth);
375 rDate.Day =
static_cast<sal_uInt16
>(nDay);
386 sal_Int32 nNanoSec = 0;
394 bool bSuccess = getISO8601TimeToken(aTimeStr,
n, tokInt, bFrac, tokFrac);
398 if ( bFrac &&
n < aTimeStr.size())
401 bSuccess = getISO8601TimeZoneToken(aTimeStr,
n, tokTz);
405 bSuccess = convertNumber32( nHour, tokInt, 0, 23 );
411 sal_Int64 fracNumerator;
412 bSuccess = convertNumber64(fracNumerator, tokFrac);
415 double frac =
static_cast<double>(fracNumerator) / pow(
static_cast<double>(10),
static_cast<double>(tokFrac.getLength()));
417 OSL_ENSURE(frac < 1 && frac >= 0,
"ISO8601parse internal error frac hours (of hours) not between 0 and 1");
422 OSL_ENSURE(frac < 1 && frac >= 0,
"ISO8601parse internal error frac minutes (of hours) not between 0 and 1");
427 OSL_ENSURE(frac < 1 && frac >= 0,
"ISO8601parse internal error frac seconds (of hours) not between 0 and 1");
429 nNanoSec = ::rtl::math::round(frac);
433 if(
n >= aTimeStr.size())
437 bSuccess = getISO8601TimeToken(aTimeStr,
n, tokInt, bFrac, tokFrac);
440 if ( bFrac &&
n < aTimeStr.size())
443 bSuccess = getISO8601TimeZoneToken(aTimeStr,
n, tokTz);
447 bSuccess = convertNumber32( nMin, tokInt, 0, 59 );
452 sal_Int64 fracNumerator;
453 bSuccess = convertNumber64(fracNumerator, tokFrac);
456 double frac =
static_cast<double>(fracNumerator) / pow(
static_cast<double>(10),
static_cast<double>(tokFrac.getLength()));
458 OSL_ENSURE(frac < 1 && frac >= 0,
"ISO8601parse internal error frac minutes (of minutes) not between 0 and 1");
463 OSL_ENSURE(frac < 1 && frac >= 0,
"ISO8601parse internal error frac seconds (of minutes) not between 0 and 1");
465 nNanoSec = ::rtl::math::round(frac);
469 if(
n >= aTimeStr.size())
473 bSuccess = getISO8601TimeToken(aTimeStr,
n, tokInt, bFrac, tokFrac);
476 if (
n < aTimeStr.size())
479 bSuccess = getISO8601TimeZoneToken(aTimeStr,
n, tokTz);
484 bSuccess = convertNumber32( nSec, tokInt, 0, 60 );
489 sal_Int64 fracNumerator;
490 bSuccess = convertNumber64(fracNumerator, tokFrac);
493 double frac =
static_cast<double>(fracNumerator) / pow(
static_cast<double>(10),
static_cast<double>(tokFrac.getLength()));
495 OSL_ENSURE(frac < 1 && frac >= 0,
"ISO8601parse internal error frac seconds (of seconds) not between 0 and 1");
497 nNanoSec = ::rtl::math::round(frac);
506 const int secondsOverflow = (nSec == 60) ? 61 : 60;
507 if (nNanoSec == 1000000000)
512 if(nSec == secondsOverflow)
523 rTime.IsUTC = (tokTz ==
"Z");
525 rTime.Hours =
static_cast<sal_uInt16
>(nHour);
526 rTime.Minutes =
static_cast<sal_uInt16
>(nMin);
527 rTime.Seconds =
static_cast<sal_uInt16
>(nSec);
528 rTime.NanoSeconds = nNanoSec;
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
This class can be accessed without locking because we load all of the data in the constructor.
OUString getDate(const Date &rDate) const
only numerical values of Gregorian calendar
OUString getTime(const tools::Time &rTime, bool bSec=true, bool b100Sec=false) const
SvtSysLocale provides a refcounted single instance of an application wide LocaleDataWrapper and <type...
const LocaleDataWrapper & GetLocaleData() const
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
sal_Int64 toInt64(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OUString toISO8601(const css::util::DateTime &rDateTime)
void typeConvert(const Date &_rDate, css::util::Date &_rOut)
bool ISO8601parseDate(std::u16string_view aDateStr, css::util::Date &rDate)
convert ISO8601 Date String to util::Date
DateTime GetDateTime(const css::util::DateTime &_rDT)
OUString GetDateTimeString(const css::util::DateTime &_rDT)
const LocaleDataWrapper & GetLocaleData()
OUString GetDateString(const css::util::DateTime &_rDT)
bool ISO8601parseDateTime(std::u16string_view rString, css::util::DateTime &rDateTime)
convert ISO8601 DateTime String to util::DateTime
bool ISO8601parseTime(std::u16string_view aTimeStr, css::util::Time &rTime)
convert ISO8601 Time String to util::Time