Adding datetime format decimal and no decimal (#936)
* revert change to xmlsoft link * remove link * Add DateFormat::Iso8601WithDecimals and DateFormat::Iso8601WithNoDecimals * changelog * add ToISO8601String with TimeFractionFormat * update the name and add extra test
This commit is contained in:
parent
038d02fd50
commit
4b4e8ba7ea
@ -13,6 +13,7 @@
|
||||
- Added `GetPort()` to `Url`.
|
||||
- Added `TransportPolicyOptions`.
|
||||
- Added `TelemetryPolicyOptions`.
|
||||
- Added `DateFormat::ToIso8601String(TimeFractionFormat)`.
|
||||
|
||||
### Other changes and Improvements
|
||||
|
||||
|
||||
@ -25,6 +25,23 @@ namespace Azure { namespace Core {
|
||||
static constexpr IntervalType WindowsToPosixOffsetSeconds = 11644473600LL;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Defines the format applied to the fraction part from any @DateFormat
|
||||
*
|
||||
*/
|
||||
enum class TimeFractionFormat
|
||||
{
|
||||
/// Decimals are not included when there are no decimals in the source Datetime and any zeros
|
||||
/// from the right are also removed.
|
||||
DropTrailingZeros,
|
||||
|
||||
/// Decimals are included for any Datetime.
|
||||
AllDigits,
|
||||
|
||||
/// Decimals are removed for any Datetime.
|
||||
Truncate
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the supported date and time string formats.
|
||||
*/
|
||||
@ -34,7 +51,7 @@ namespace Azure { namespace Core {
|
||||
Rfc1123,
|
||||
|
||||
/// ISO 8601.
|
||||
Iso8601
|
||||
Iso8601,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -76,6 +93,19 @@ namespace Azure { namespace Core {
|
||||
std::string const& timeString,
|
||||
DateFormat format = DateFormat::Rfc1123);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Get a string representation of the @DateTime.
|
||||
*
|
||||
* @param format The representation format to use.
|
||||
* @param fractionFormat The format for the fraction part of the Datetime. Only supported by
|
||||
* ISO8601
|
||||
*
|
||||
* @throw DateTimeException If year exceeds 9999, or if \p format is not recognized.
|
||||
*/
|
||||
std::string ToString(DateFormat format, TimeFractionFormat fractionFormat) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Get a string representation of the @DateTime.
|
||||
*
|
||||
@ -83,7 +113,22 @@ namespace Azure { namespace Core {
|
||||
*
|
||||
* @throw DateTimeException If year exceeds 9999, or if \p format is not recognized.
|
||||
*/
|
||||
std::string ToString(DateFormat format = DateFormat::Rfc1123) const;
|
||||
std::string ToString(DateFormat format = DateFormat::Rfc1123) const
|
||||
{
|
||||
return ToString(format, TimeFractionFormat::DropTrailingZeros);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get a string representation of the @DateTime formated with ISO8601.
|
||||
*
|
||||
* @param fractionFormat The format that is applied to the fraction part from the ISO8601 date.
|
||||
*
|
||||
* @throw DateTimeException If year exceeds 9999, or if \p fractionFormat is not recognized.
|
||||
*/
|
||||
std::string ToIso8601String(TimeFractionFormat fractionFormat) const
|
||||
{
|
||||
return ToString(DateFormat::Iso8601, fractionFormat);
|
||||
};
|
||||
|
||||
/// Get the integral time value.
|
||||
IntervalType ToInterval() const { return m_interval; }
|
||||
|
||||
@ -127,7 +127,7 @@ constexpr char const monthNames[] = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string DateTime::ToString(DateFormat format) const
|
||||
std::string DateTime::ToString(DateFormat format, TimeFractionFormat fractionFormat) const
|
||||
{
|
||||
if (m_interval > 2650467743999999999LL)
|
||||
{
|
||||
@ -209,7 +209,8 @@ std::string DateTime::ToString(DateFormat format) const
|
||||
leftover);
|
||||
|
||||
outCursor += 19;
|
||||
if (fracSec != 0)
|
||||
if ((fracSec != 0 && fractionFormat != TimeFractionFormat::Truncate)
|
||||
|| fractionFormat == TimeFractionFormat::AllDigits)
|
||||
{
|
||||
// Append fractional second, which is a 7-digit value with no trailing zeros
|
||||
// This way, '1200' becomes '00012'
|
||||
@ -226,11 +227,13 @@ std::string DateTime::ToString(DateFormat format) const
|
||||
".%07d",
|
||||
fracSec);
|
||||
|
||||
while (outCursor[appended - 1] == '0')
|
||||
if (fractionFormat != TimeFractionFormat::AllDigits)
|
||||
{
|
||||
--appended; // trim trailing zeros
|
||||
while (outCursor[appended - 1] == '0')
|
||||
{
|
||||
--appended; // trim trailing zeros
|
||||
}
|
||||
}
|
||||
|
||||
outCursor += appended;
|
||||
}
|
||||
|
||||
|
||||
@ -73,6 +73,59 @@ TEST(DateTime, ParseTimeRoundrip2)
|
||||
TestDateTimeRoundtrip("2013-11-19T14:30:59.1234567999Z", "2013-11-19T14:30:59.1234567Z");
|
||||
}
|
||||
|
||||
TEST(DateTime, decimals)
|
||||
{
|
||||
{
|
||||
std::string strExpected("2020-10-13T21:06:15.3300000Z");
|
||||
auto dt = DateTime::FromString("2020-10-13T21:06:15.33Z", DateTime::DateFormat::Iso8601);
|
||||
auto const str2 = dt.ToIso8601String(DateTime::TimeFractionFormat::AllDigits);
|
||||
EXPECT_EQ(str2, strExpected);
|
||||
}
|
||||
|
||||
{
|
||||
std::string strExpected("2020-10-13T21:06:15.0000000Z");
|
||||
auto dt = DateTime::FromString("2020-10-13T21:06:15Z", DateTime::DateFormat::Iso8601);
|
||||
auto const str2 = dt.ToIso8601String(DateTime::TimeFractionFormat::AllDigits);
|
||||
EXPECT_EQ(str2, strExpected);
|
||||
}
|
||||
|
||||
{
|
||||
std::string strExpected("2020-10-13T21:06:15.1234500Z");
|
||||
auto dt = DateTime::FromString("2020-10-13T21:06:15.12345Z", DateTime::DateFormat::Iso8601);
|
||||
auto const str2 = dt.ToIso8601String(DateTime::TimeFractionFormat::AllDigits);
|
||||
EXPECT_EQ(str2, strExpected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DateTime, noDecimals)
|
||||
{
|
||||
{
|
||||
std::string strExpected("2020-10-13T21:06:15Z");
|
||||
auto dt = DateTime::FromString("2020-10-13T21:06:15Z", DateTime::DateFormat::Iso8601);
|
||||
auto const str2 = dt.ToIso8601String(DateTime::TimeFractionFormat::Truncate);
|
||||
EXPECT_EQ(str2, strExpected);
|
||||
}
|
||||
|
||||
{
|
||||
std::string strExpected("2020-10-13T21:06:15Z");
|
||||
auto dt = DateTime::FromString("2020-10-13T21:06:15.99999Z", DateTime::DateFormat::Iso8601);
|
||||
auto const str2 = dt.ToIso8601String(DateTime::TimeFractionFormat::Truncate);
|
||||
EXPECT_EQ(str2, strExpected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DateTime, sameResultFromDefaultISO)
|
||||
{
|
||||
{
|
||||
auto dt = DateTime::FromString("2020-10-13T21:06:15.33000000Z", DateTime::DateFormat::Iso8601);
|
||||
auto dt2
|
||||
= DateTime::FromString("2020-10-13T21:06:15.330000000Z", DateTime::DateFormat::Iso8601);
|
||||
auto const str1 = dt.ToIso8601String(DateTime::TimeFractionFormat::DropTrailingZeros);
|
||||
auto const str2 = dt2.ToString(DateTime::DateFormat::Iso8601);
|
||||
EXPECT_EQ(str1, str2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DateTime, ParseTimeRoundrip3)
|
||||
{
|
||||
// leading 0-s after the comma, tricky to parse correctly
|
||||
|
||||
Loading…
Reference in New Issue
Block a user