gnucash master: Multiple changes pushed
Geert Janssens
gjanssens at code.gnucash.org
Thu Apr 20 17:20:24 EDT 2017
Updated via https://github.com/Gnucash/gnucash/commit/39195597 (commit)
via https://github.com/Gnucash/gnucash/commit/d1ff1613 (commit)
via https://github.com/Gnucash/gnucash/commit/724f8aa7 (commit)
from https://github.com/Gnucash/gnucash/commit/b2b32e29 (commit)
commit 391955975bac2be7a86b7f4418d7c28d23ad6622
Author: Geert Janssens <geert at kobaltwit.be>
Date: Thu Apr 20 23:01:54 2017 +0200
Fix static code checker warnings about parameter definition in doxygen comments
Apparently these shouldn't suffixed with a colon (:)
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 305d24d..74a3bad 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -71,13 +71,13 @@ public:
GncDateTime();
/** Construct a GncDateTime in the current timezone representing the
* timestamp as seconds from the POSIX epoch (1970-01-01T00:00:00UTC).
- * @param time: Seconds from the POSIX epoch.
+ * @param time Seconds from the POSIX epoch.
* @exception std::invalid_argument if the year is outside the constraints.
*/
GncDateTime(const time64 time);
/** Construct a GncDateTime in the current timezone representing the
* standard struct tm provided.
- * @param tm: A C-standard struct tm representing the date and
+ * @param tm A C-standard struct tm representing the date and
* time. Note that the timezone and offset are ignored on those
* systems which include them in struct tm.
* @exception std::invalid_argument if the year is outside the constraints.
@@ -86,8 +86,8 @@ public:
/** Construct a GncDateTime from a GncDate. As a GncDate doesn't contain time
* information, the time will be set depending on the second parameter
* to start of day, neutral or end of day.
- * @param date: A GncDate representing a date.
- * @param part: An optinoal DayPart indicating which time to use in the conversion.
+ * @param date A GncDate representing a date.
+ * @param part An optinoal DayPart indicating which time to use in the conversion.
* This can be "DayPart::start" for start of day (00:00 local time),
* "DayPart::neutral" for a neutral time (10:59 UTC, chosen to have the
* least chance of date changes when crossing timezone borders),
@@ -99,7 +99,7 @@ public:
*/
GncDateTime(const GncDate& date, DayPart part = DayPart::neutral);
/** Construct a GncDateTime
- * @param str: A string representing the date and time in some
+ * @param str A string representing the date and time in some
* recognizable format. Note that if a timezone is not specified the
* default is UTC, not the local one.
* @exception std::invalid_argument if the year is outside the constraints.
@@ -130,7 +130,7 @@ public:
/** Test if the GncDateTime has a member pointer. Testing only. */
bool isnull (void) { return m_impl == nullptr; }
/** Format the GncDateTime into a std::string
- * @param format: A cstr describing the way the date and time are
+ * @param format A cstr describing the way the date and time are
* presented. Code letters preceded with % stand in for arguments;
* most are the same as described in strftime(3), but there are a few
* differences. Consult the boost::date_time documentation.
@@ -139,7 +139,7 @@ public:
*/
std::string format(const char* format) const;
/** Format the GncDateTime into a std::string in GMT
- * @param format: A cstr describing the way the date and time are
+ * @param format A cstr describing the way the date and time are
* presented. Code letters preceded with % stand in for arguments;
* most are the same as described in strftime(3), but there are a few
* differences. Consult the boost::date_time documentation.
@@ -164,9 +164,9 @@ class GncDate
* will be normalized if the day or month values are outside of the
* normal ranges. e.g. 1994, -3, 47 will be normalized to 1993-10-17.
*
- * @param year: The year in the Common Era.
- * @param month: The month, where 1 is January and 12 is December.
- * @param day: The day of the month, beginning with 1.
+ * @param year The year in the Common Era.
+ * @param month The month, where 1 is January and 12 is December.
+ * @param day The day of the month, beginning with 1.
* @exception std::invalid_argument if the calculated year is outside
* of the constrained range.
*/
@@ -182,7 +182,7 @@ class GncDate
*/
ymd year_month_day() const;
/** Format the GncDate into a std::string
- * @param format: A cstr describing the way the date and time are
+ * @param format A cstr describing the way the date and time are
* presented. Code letters preceded with % stand in for arguments;
* most are the same as described in strftime(3), but there are a few
* differences. Consult the boost::date_time documentation.
commit d1ff16138eec2dc388cb90c5d9da51af2d2fd44f
Author: Geert Janssens <geert at kobaltwit.be>
Date: Thu Apr 20 22:58:35 2017 +0200
Add GncDateTime constructor taking a GncDate as parameter
As a GncDate doesn't have any time information, this has to be made up.
GnuCash uses 3 times-of-day quite a lot:
- start-of-day (00:00 local time)
- end-of-day (23:59 local time)
- neutral time (10:59 utc, chosen to minimize
day offsetting when converting to/from localtime)
A second parameter to the new constructor will tell it to use one of these presets.
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 5bc9f5b..f367d45 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -100,6 +100,7 @@ public:
GncDateTimeImpl() : m_time(boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year()))) {}
GncDateTimeImpl(const time64 time) : m_time(LDT_from_unix_local(time)) {}
GncDateTimeImpl(const struct tm tm) : m_time(LDT_from_struct_tm(tm)) {}
+ GncDateTimeImpl(const GncDateImpl& date, DayPart part = DayPart::neutral);
GncDateTimeImpl(const std::string str);
GncDateTimeImpl(PTime&& pt) : m_time(pt, tzp.get(pt.date().year())) {}
GncDateTimeImpl(LDT&& ldt) : m_time(ldt) {}
@@ -132,10 +133,46 @@ public:
std::string format_zulu(const char* format) const;
private:
Date m_greg;
+
+ friend GncDateTimeImpl::GncDateTimeImpl(const GncDateImpl&, DayPart);
};
/* Member function definitions for GncDateTimeImpl.
*/
+GncDateTimeImpl::GncDateTimeImpl(const GncDateImpl& date, DayPart part) :
+ m_time(unix_epoch, utc_zone)
+{
+ using TD = boost::posix_time::time_duration;
+ static const TD start(0, 0, 0);
+ static const TD neutral(10, 59, 0);
+ static const TD end(23,59, 0);
+ TD time_of_day;
+ switch (part)
+ {
+ case DayPart::start:
+ time_of_day = start;
+ break;
+ case DayPart::neutral:
+ time_of_day = neutral;
+ break;
+ case DayPart::end:
+ time_of_day = end;
+ break;
+ }
+
+ try
+ {
+ auto tz = utc_zone;
+ if (part != DayPart::neutral)
+ tz = tzp.get(date.m_greg.year());
+ m_time = LDT(date.m_greg, time_of_day, tz, LDT::EXCEPTION_ON_ERROR);
+ }
+ catch(boost::gregorian::bad_year)
+ {
+ throw(std::invalid_argument("Time value is outside the supported year range."));
+ }
+}
+
GncDateTimeImpl::GncDateTimeImpl(const std::string str) :
m_time(unix_epoch, utc_zone)
{
@@ -286,6 +323,9 @@ GncDateTime::GncDateTime(const std::string str) :
m_impl(new GncDateTimeImpl(str)) {}
GncDateTime::~GncDateTime() = default;
+GncDateTime::GncDateTime(const GncDate& date, DayPart part) :
+ m_impl(new GncDateTimeImpl(*(date.m_impl), part)) {}
+
void
GncDateTime::now()
{
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 6e9e723..305d24d 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -36,6 +36,12 @@ typedef struct
int day; //1-31
} ymd;
+enum class DayPart {
+ start, // 00:00
+ neutral, // 10:59
+ end, // 23:59
+};
+
class GncDateTimeImpl;
class GncDateImpl;
class GncDate;
@@ -77,6 +83,21 @@ public:
* @exception std::invalid_argument if the year is outside the constraints.
*/
GncDateTime(const struct tm tm);
+/** Construct a GncDateTime from a GncDate. As a GncDate doesn't contain time
+ * information, the time will be set depending on the second parameter
+ * to start of day, neutral or end of day.
+ * @param date: A GncDate representing a date.
+ * @param part: An optinoal DayPart indicating which time to use in the conversion.
+ * This can be "DayPart::start" for start of day (00:00 local time),
+ * "DayPart::neutral" for a neutral time (10:59 UTC, chosen to have the
+ * least chance of date changes when crossing timezone borders),
+ * "DayPart::end" for end of day (23:59 local time).
+ * If omitted part defaults to DayPart::neutral.
+ * Note the different timezone used for DayPart::neutral compared to the other
+ * two options!
+ * @exception std::invalid_argument if the year is outside the constraints.
+ */
+ GncDateTime(const GncDate& date, DayPart part = DayPart::neutral);
/** Construct a GncDateTime
* @param str: A string representing the date and time in some
* recognizable format. Note that if a timezone is not specified the
@@ -174,6 +195,8 @@ class GncDate
private:
std::unique_ptr<GncDateImpl> m_impl;
+
+ friend GncDateTime::GncDateTime(const GncDate&, DayPart);
};
#endif // __GNC_DATETIME_HPP__
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index f76f375..59b19e4 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -71,6 +71,35 @@ TEST(gnc_datetime_constructors, test_struct_tm_constructor)
EXPECT_EQ(tm1.tm_min, tm.tm_min);
}
+/* Note: the following tests for the constructor taking a GncDate as input parameter
+ * use GncDateTime's format() member function to simplify the result checking.
+ * If there's a bug in this member function, these tests may fail in addition
+ * to the format test later in the test suite. Be sure to check that later
+ * test as well in case any of the below constructor tests fails. */
+
+TEST(gnc_datetime_constructors, test_gncdate_start_constructor)
+{
+ const ymd aymd = { 2017, 04, 20 };
+ GncDateTime atime(GncDate(aymd.year, aymd.month, aymd.day), DayPart::start);
+ //Skipping timezone information as this can't be controlled.
+ EXPECT_EQ(atime.format("%d-%m-%Y %H:%M:%S"), "20-04-2017 00:00:00");
+}
+
+TEST(gnc_datetime_constructors, test_gncdate_end_constructor)
+{
+ const ymd aymd = { 2046, 11, 06 };
+ GncDateTime atime(GncDate(aymd.year, aymd.month, aymd.day), DayPart::end);
+ //Skipping timezone information as this can't be controlled.
+ EXPECT_EQ(atime.format("%d-%m-%Y %H:%M:%S"), "06-11-2046 23:59:00");
+}
+
+TEST(gnc_datetime_constructors, test_gncdate_neutral_constructor)
+{
+ const ymd aymd = { 2017, 04, 20 };
+ GncDateTime atime(GncDate(aymd.year, aymd.month, aymd.day), DayPart::neutral);
+ EXPECT_EQ(atime.format("%d-%m-%Y %H:%M:%S %z"), "20-04-2017 10:59:00 UTC");
+}
+
TEST(gnc_datetime_functions, test_format)
{
GncDateTime atime(2394187200); //2045-11-13 12:00:00 Z
commit 724f8aa7847c4b8f1ddea1aff1fbf839c9b69f07
Author: Geert Janssens <geert at kobaltwit.be>
Date: Thu Apr 20 21:42:24 2017 +0200
Swap GncDate and GncDateTime in preparation of a future commit
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 25d16a9..5bc9f5b 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -58,43 +58,6 @@ static constexpr auto ticks_per_second = INT64_C(1000000);
static constexpr auto ticks_per_second = INT64_C(1000000000);
#endif
-/** Private implementation of GncDate. See the documentation for that class.
- */
-class GncDateImpl
-{
-public:
- GncDateImpl(): m_greg(boost::gregorian::day_clock::local_day()) {}
- GncDateImpl(const int year, const int month, const int day) :
- m_greg(year, static_cast<Month>(month), day) {}
- GncDateImpl(Date d) : m_greg(d) {}
-
- void today() { m_greg = boost::gregorian::day_clock::local_day(); }
- ymd year_month_day() const;
- std::string format(const char* format) const;
- std::string format_zulu(const char* format) const;
-private:
- Date m_greg;
-};
-
-ymd
-GncDateImpl::year_month_day() const
-{
- auto boost_ymd = m_greg.year_month_day();
- return {boost_ymd.year, boost_ymd.month.as_number(), boost_ymd.day};
-}
-
-std::string
-GncDateImpl::format(const char* format) const
-{
- using Facet = boost::gregorian::date_facet;
- std::stringstream ss;
- //The stream destructor frees the facet, so it must be heap-allocated.
- auto output_facet(new Facet(format));
- ss.imbue(std::locale(std::locale(), output_facet));
- ss << m_greg;
- return ss.str();
-}
-
/** Private implementation of GncDateTime. See the documentation for that class.
*/
static LDT
@@ -153,6 +116,26 @@ private:
LDT m_time;
};
+/** Private implementation of GncDate. See the documentation for that class.
+ */
+class GncDateImpl
+{
+public:
+ GncDateImpl(): m_greg(boost::gregorian::day_clock::local_day()) {}
+ GncDateImpl(const int year, const int month, const int day) :
+ m_greg(year, static_cast<Month>(month), day) {}
+ GncDateImpl(Date d) : m_greg(d) {}
+
+ void today() { m_greg = boost::gregorian::day_clock::local_day(); }
+ ymd year_month_day() const;
+ std::string format(const char* format) const;
+ std::string format_zulu(const char* format) const;
+private:
+ Date m_greg;
+};
+
+/* Member function definitions for GncDateTimeImpl.
+ */
GncDateTimeImpl::GncDateTimeImpl(const std::string str) :
m_time(unix_epoch, utc_zone)
{
@@ -270,37 +253,28 @@ GncDateTimeImpl::format_zulu(const char* format) const
return ss.str();
}
-/* =================== Presentation-class Implementations ====================*/
-/* GncDate */
-GncDate::GncDate() : m_impl{new GncDateImpl} {}
-GncDate::GncDate(int year, int month, int day) :
- m_impl(new GncDateImpl(year, month, day)) {}
-GncDate::GncDate(std::unique_ptr<GncDateImpl> impl) :
- m_impl(std::move(impl)) {}
-GncDate::GncDate(GncDate&&) = default;
-GncDate::~GncDate() = default;
-
-GncDate&
-GncDate::operator=(GncDate&&) = default;
-
-void
-GncDate::today()
+/* Member function definitions for GncDateTimeImpl.
+ */
+ymd
+GncDateImpl::year_month_day() const
{
- m_impl->today();
+ auto boost_ymd = m_greg.year_month_day();
+ return {boost_ymd.year, boost_ymd.month.as_number(), boost_ymd.day};
}
std::string
-GncDate::format(const char* format)
-{
- return m_impl->format(format);
-}
-
-ymd
-GncDate::year_month_day() const
+GncDateImpl::format(const char* format) const
{
- return m_impl->year_month_day();
+ using Facet = boost::gregorian::date_facet;
+ std::stringstream ss;
+ //The stream destructor frees the facet, so it must be heap-allocated.
+ auto output_facet(new Facet(format));
+ ss.imbue(std::locale(std::locale(), output_facet));
+ ss << m_greg;
+ return ss.str();
}
+/* =================== Presentation-class Implementations ====================*/
/* GncDateTime */
GncDateTime::GncDateTime() : m_impl(new GncDateTimeImpl) {}
@@ -357,3 +331,33 @@ GncDateTime::format_zulu(const char* format) const
{
return m_impl->format_zulu(format);
}
+
+/* GncDate */
+GncDate::GncDate() : m_impl{new GncDateImpl} {}
+GncDate::GncDate(int year, int month, int day) :
+m_impl(new GncDateImpl(year, month, day)) {}
+GncDate::GncDate(std::unique_ptr<GncDateImpl> impl) :
+m_impl(std::move(impl)) {}
+GncDate::GncDate(GncDate&&) = default;
+GncDate::~GncDate() = default;
+
+GncDate&
+GncDate::operator=(GncDate&&) = default;
+
+void
+GncDate::today()
+{
+ m_impl->today();
+}
+
+std::string
+GncDate::format(const char* format)
+{
+ return m_impl->format(format);
+}
+
+ymd
+GncDate::year_month_day() const
+{
+ return m_impl->year_month_day();
+}
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 3942c4b..6e9e723 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -36,57 +36,13 @@ typedef struct
int day; //1-31
} ymd;
-class GncDateImpl;
class GncDateTimeImpl;
+class GncDateImpl;
+class GncDate;
using time64 = int64_t;
constexpr const time64 MINTIME = -17987443200;
constexpr const time64 MAXTIME = 253402214400;
-class GncDate
-{
-public:/** Construct a GncDate representing the current day.
- */
- GncDate();;
-/** Construct a GncDate representing the given year, month, and day in
- * the proleptic Gregorian calendar.
- *
- * Years are constrained to be from 1400 - 9999 CE inclusive. Dates
- * will be normalized if the day or month values are outside of the
- * normal ranges. e.g. 1994, -3, 47 will be normalized to 1993-10-17.
- *
- * @param year: The year in the Common Era.
- * @param month: The month, where 1 is January and 12 is December.
- * @param day: The day of the month, beginning with 1.
- * @exception std::invalid_argument if the calculated year is outside
- * of the constrained range.
- */
- GncDate(int year, int month, int day);
- GncDate(std::unique_ptr<GncDateImpl> impl);
- GncDate(GncDate&&);
- ~GncDate();
- GncDate& operator=(GncDate&&);
-/** Set the date object to the computer clock's current day. */
- void today();
-/** Get the year, month, and day from the date as a ymd.
- @return ymd struct
- */
- ymd year_month_day() const;
-/** Format the GncDate into a std::string
- * @param format: A cstr describing the way the date and time are
- * presented. Code letters preceded with % stand in for arguments;
- * most are the same as described in strftime(3), but there are a few
- * differences. Consult the boost::date_time documentation.
- * @return a std::string containing a representation of the date
- * according to the format.
- */
- std::string format(const char* format);
-/** Test that the Date has an implementation. */
- bool isnull (void) { return m_impl == nullptr; }
-
-private:
- std::unique_ptr<GncDateImpl> m_impl;
-};
-
/** GnuCash DateTime class
*
* Represents local time in the current timezone.
@@ -175,4 +131,49 @@ private:
std::unique_ptr<GncDateTimeImpl> m_impl;
};
+class GncDate
+{
+ public:/** Construct a GncDate representing the current day.
+ */
+ GncDate();;
+ /** Construct a GncDate representing the given year, month, and day in
+ * the proleptic Gregorian calendar.
+ *
+ * Years are constrained to be from 1400 - 9999 CE inclusive. Dates
+ * will be normalized if the day or month values are outside of the
+ * normal ranges. e.g. 1994, -3, 47 will be normalized to 1993-10-17.
+ *
+ * @param year: The year in the Common Era.
+ * @param month: The month, where 1 is January and 12 is December.
+ * @param day: The day of the month, beginning with 1.
+ * @exception std::invalid_argument if the calculated year is outside
+ * of the constrained range.
+ */
+ GncDate(int year, int month, int day);
+ GncDate(std::unique_ptr<GncDateImpl> impl);
+ GncDate(GncDate&&);
+ ~GncDate();
+ GncDate& operator=(GncDate&&);
+ /** Set the date object to the computer clock's current day. */
+ void today();
+ /** Get the year, month, and day from the date as a ymd.
+ * @return ymd struct
+ */
+ ymd year_month_day() const;
+ /** Format the GncDate into a std::string
+ * @param format: A cstr describing the way the date and time are
+ * presented. Code letters preceded with % stand in for arguments;
+ * most are the same as described in strftime(3), but there are a few
+ * differences. Consult the boost::date_time documentation.
+ * @return a std::string containing a representation of the date
+ * according to the format.
+ */
+ std::string format(const char* format);
+ /** Test that the Date has an implementation. */
+ bool isnull (void) { return m_impl == nullptr; }
+
+private:
+ std::unique_ptr<GncDateImpl> m_impl;
+};
+
#endif // __GNC_DATETIME_HPP__
Summary of changes:
src/libqof/qof/gnc-datetime.cpp | 166 ++++++++++++++++++-----------
src/libqof/qof/gnc-datetime.hpp | 126 +++++++++++++---------
src/libqof/qof/test/gtest-gnc-datetime.cpp | 29 +++++
3 files changed, 209 insertions(+), 112 deletions(-)
More information about the gnucash-changes
mailing list