mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Extract function tz_from_string.
Also changes from calculating the Bug 767824 offset to using boost::date_time::local_time_in() and provides unit tests.
This commit is contained in:
parent
e798df07d7
commit
fcf88262ca
@ -262,48 +262,31 @@ GncDateTimeImpl::GncDateTimeImpl(const GncDateImpl& date, DayPart part) :
|
||||
}
|
||||
}
|
||||
|
||||
using PTZ = boost::local_time::posix_time_zone;
|
||||
|
||||
static TZ_Ptr
|
||||
tz_from_string(std::string str)
|
||||
{
|
||||
if (str.empty()) return utc_zone;
|
||||
std::string tzstr = "XXX" + str;
|
||||
if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
|
||||
tzstr.insert(6, ":");
|
||||
if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
|
||||
{
|
||||
tzstr.insert(9, ":");
|
||||
}
|
||||
return TZ_Ptr(new PTZ(tzstr));
|
||||
}
|
||||
|
||||
GncDateTimeImpl::GncDateTimeImpl(const std::string str) :
|
||||
m_time(unix_epoch, utc_zone)
|
||||
{
|
||||
if (str.empty()) return;
|
||||
|
||||
using std::string;
|
||||
using PTZ = boost::local_time::posix_time_zone;
|
||||
TZ_Ptr tzptr;
|
||||
auto tzpos = str.find_first_of("+-", str.find(":"));
|
||||
int offset = 0L;
|
||||
if (tzpos != str.npos)
|
||||
{
|
||||
string tzstr = "XXX" + str.substr(tzpos);
|
||||
if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
|
||||
tzstr.insert(6, ":");
|
||||
if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
|
||||
{
|
||||
tzstr.insert(9, ":");
|
||||
/* Bug 767824: A GLib bug in parsing the UTC timezone on
|
||||
* Windows may have created a bogus timezone of a random
|
||||
* number of minutes. Since there are no fractional-hour
|
||||
* timezones around the prime meridian we can safely check for
|
||||
* this in files by looking for minutes-only offsets and
|
||||
* making the appropriate correction.
|
||||
*/
|
||||
if (tzstr.compare(7,8, "00") &&
|
||||
(tzstr.length() > 10 ? tzstr[10] != '0' :
|
||||
!tzstr.compare(10, 11, "00")))
|
||||
{
|
||||
offset = atoi(tzstr.substr(10,11).c_str());
|
||||
if (offset && tzpos == '-')
|
||||
offset = -offset;
|
||||
tzstr.replace(10, 11, "00");
|
||||
}
|
||||
}
|
||||
tzptr.reset(new PTZ(tzstr));
|
||||
if (str[tzpos - 1] == ' ') --tzpos;
|
||||
}
|
||||
else
|
||||
{
|
||||
tzptr = utc_zone;
|
||||
}
|
||||
auto tzptr = tz_from_string(tzpos != str.npos ? str.substr(tzpos) : "");
|
||||
if (tzpos != str.npos && str[tzpos - 1] == ' ') --tzpos;
|
||||
|
||||
try
|
||||
{
|
||||
using Facet = boost::posix_time::time_input_facet;
|
||||
@ -328,8 +311,15 @@ GncDateTimeImpl::GncDateTimeImpl(const std::string str) :
|
||||
{
|
||||
throw(std::invalid_argument("The date string was outside of the supported year range."));
|
||||
}
|
||||
if (offset)
|
||||
m_time -= boost::posix_time::minutes(offset);
|
||||
/* Bug 767824: A GLib bug in parsing the UTC timezone on Windows may have
|
||||
* created a bogus timezone of a random number of minutes. Since there are
|
||||
* no fractional-hour timezones around the prime meridian we can safely
|
||||
* check for this in files by resetting to UTC if there's a
|
||||
* less-than-an-hour offset.
|
||||
*/
|
||||
auto offset = tzptr->base_utc_offset().seconds();
|
||||
if (offset != 0 && std::abs(offset) < 3600)
|
||||
m_time = m_time.local_time_in(utc_zone);
|
||||
}
|
||||
|
||||
GncDateTimeImpl::operator time64() const
|
||||
@ -460,7 +450,7 @@ GncDateTime::GncDateTime(const time64 time) :
|
||||
m_impl(new GncDateTimeImpl(time)) {}
|
||||
GncDateTime::GncDateTime(const struct tm tm) :
|
||||
m_impl(new GncDateTimeImpl(tm)) {}
|
||||
GncDateTime::GncDateTime(const std::string str) :
|
||||
GncDateTime::GncDateTime(const std::string str, std::string fmt) :
|
||||
m_impl(new GncDateTimeImpl(str)) {}
|
||||
GncDateTime::~GncDateTime() = default;
|
||||
|
||||
|
@ -261,15 +261,38 @@ TEST(gnc_datetime_constructors, test_time64_constructor)
|
||||
|
||||
TEST(gnc_datetime_constructors, test_string_constructor)
|
||||
{
|
||||
std::string timestr("2015-12-05 00:01:00");
|
||||
GncDateTime time(timestr);
|
||||
auto tm = time.utc_tm();
|
||||
/* Plain UTC date-time */
|
||||
std::string timestr("2015-12-05 11:57:03");
|
||||
GncDateTime time1(timestr);
|
||||
auto tm = time1.utc_tm();
|
||||
EXPECT_EQ(tm.tm_year, 115);
|
||||
EXPECT_EQ(tm.tm_mon, 11);
|
||||
EXPECT_EQ(tm.tm_mday, 5);
|
||||
EXPECT_EQ(tm.tm_hour, 0);
|
||||
EXPECT_EQ(tm.tm_min, 1);
|
||||
EXPECT_EQ(tm.tm_sec, 0);
|
||||
EXPECT_EQ(tm.tm_hour,11);
|
||||
EXPECT_EQ(tm.tm_min, 57);
|
||||
EXPECT_EQ(tm.tm_sec, 3);
|
||||
|
||||
/* Datetime with an offset */
|
||||
timestr = "1993-07-22 15:21:19 +0300";
|
||||
GncDateTime time2(timestr);
|
||||
tm = time2.utc_tm();
|
||||
EXPECT_EQ(tm.tm_year, 93);
|
||||
EXPECT_EQ(tm.tm_mon, 6);
|
||||
EXPECT_EQ(tm.tm_mday, 22);
|
||||
EXPECT_EQ(tm.tm_hour, 12);
|
||||
EXPECT_EQ(tm.tm_min, 21);
|
||||
EXPECT_EQ(tm.tm_sec, 19);
|
||||
|
||||
/* Bug 767824 date-time */
|
||||
timestr = "1993-07-22 15:21:19 +0013";
|
||||
GncDateTime time3(timestr);
|
||||
tm = time3.utc_tm();
|
||||
EXPECT_EQ(tm.tm_year, 93);
|
||||
EXPECT_EQ(tm.tm_mon, 6);
|
||||
EXPECT_EQ(tm.tm_mday, 22);
|
||||
EXPECT_EQ(tm.tm_hour, 15);
|
||||
EXPECT_EQ(tm.tm_min, 8);
|
||||
EXPECT_EQ(tm.tm_sec, 19);
|
||||
}
|
||||
|
||||
TEST(gnc_datetime_constructors, test_struct_tm_constructor)
|
||||
|
Loading…
Reference in New Issue
Block a user