mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'boost-date'
Some fixes plus GncDate::format().
This commit is contained in:
commit
42cca36445
@ -71,6 +71,8 @@ AC_GNU_SOURCE
|
||||
AC_PROG_INTLTOOL
|
||||
# Ensure the compiler supports C++ 11:
|
||||
AX_CXX_COMPILE_STDCXX_11(ext)
|
||||
# We require C99 for the C parts:
|
||||
AC_PROG_CC_C99
|
||||
|
||||
|
||||
AC_SUBST(GNUCASH_MAJOR_VERSION)
|
||||
@ -877,8 +879,9 @@ if test x$enable_google_test = xyes; then
|
||||
elif test "x$ac_cv_file__usr_src_gmock_gmock_all_cc" = xyes; then
|
||||
ac_cv_gmock_src_path="/usr/src/gmock"
|
||||
else
|
||||
ac_cv_gmock_root=""
|
||||
ac_cv_gmock_src_path=""
|
||||
fi
|
||||
ac_cv_gmock_root="$ac_cv_gmock_src_path"
|
||||
else
|
||||
ac_cv_gmock_root=""
|
||||
fi
|
||||
|
@ -479,44 +479,11 @@ int gnc_date_get_last_mday (int month, int year)
|
||||
return last_day_of_month[0][month];
|
||||
}
|
||||
|
||||
/* Safety function */
|
||||
static void
|
||||
gnc_gdate_range_check (GDate *gd)
|
||||
{
|
||||
int year;
|
||||
if (!g_date_valid (gd))
|
||||
{
|
||||
g_date_set_dmy (gd, 1, G_DATE_JANUARY, 1970);
|
||||
return;
|
||||
}
|
||||
year = g_date_get_year (gd);
|
||||
// Adjust the GDate to fit in the range of GDateTime.
|
||||
year = (year < 1 ? 1 : year > 9999 ? 9999 : year);
|
||||
g_date_set_year (gd, year);
|
||||
return;
|
||||
}
|
||||
/* Return the set dateFormat.
|
||||
|
||||
return QofDateFormat: enumeration indicating preferred format
|
||||
|
||||
Global: dateFormat
|
||||
*/
|
||||
QofDateFormat qof_date_format_get (void)
|
||||
{
|
||||
return dateFormat;
|
||||
}
|
||||
|
||||
/* set date format
|
||||
|
||||
set date format to one of US, UK, CE, ISO OR UTC
|
||||
checks to make sure it's a legal value
|
||||
|
||||
param QofDateFormat: enumeration indicating preferred format
|
||||
|
||||
return void
|
||||
|
||||
Globals: dateFormat
|
||||
*/
|
||||
void qof_date_format_set(QofDateFormat df)
|
||||
{
|
||||
if (df >= DATE_FORMAT_FIRST && df <= DATE_FORMAT_LAST)
|
||||
@ -589,11 +556,11 @@ const gchar *qof_date_format_get_string(QofDateFormat df)
|
||||
switch (df)
|
||||
{
|
||||
case QOF_DATE_FORMAT_US:
|
||||
return "%m/%d/%y";
|
||||
return "%m/%d/%Y";
|
||||
case QOF_DATE_FORMAT_UK:
|
||||
return "%d/%m/%y";
|
||||
return "%d/%m/%Y";
|
||||
case QOF_DATE_FORMAT_CE:
|
||||
return "%d.%m.%y";
|
||||
return "%d.%m.%Y";
|
||||
case QOF_DATE_FORMAT_UTC:
|
||||
return "%Y-%m-%dT%H:%M:%SZ";
|
||||
case QOF_DATE_FORMAT_ISO:
|
||||
@ -605,24 +572,15 @@ const gchar *qof_date_format_get_string(QofDateFormat df)
|
||||
return GNC_D_FMT;
|
||||
}
|
||||
|
||||
/* get the date format string for the current format
|
||||
|
||||
get the date format string for the current format
|
||||
|
||||
param df Required date format.
|
||||
return string
|
||||
|
||||
Globals: dateFormat
|
||||
*/
|
||||
const gchar *qof_date_text_format_get_string(QofDateFormat df)
|
||||
{
|
||||
switch (df)
|
||||
{
|
||||
case QOF_DATE_FORMAT_US:
|
||||
return "%b %d, %y";
|
||||
return "%b %d, %Y";
|
||||
case QOF_DATE_FORMAT_UK:
|
||||
case QOF_DATE_FORMAT_CE:
|
||||
return "%d %b, %y";
|
||||
return "%d %b %Y";
|
||||
case QOF_DATE_FORMAT_UTC:
|
||||
return "%Y-%m-%dT%H:%M:%SZ";
|
||||
case QOF_DATE_FORMAT_ISO:
|
||||
@ -634,89 +592,30 @@ const gchar *qof_date_text_format_get_string(QofDateFormat df)
|
||||
return GNC_D_FMT;
|
||||
}
|
||||
|
||||
/* Convert day, month and year values to a date string
|
||||
|
||||
Convert a date as day / month / year integers into a localized string
|
||||
representation
|
||||
|
||||
param buff - pointer to previously allocated character array; its size
|
||||
must be at lease MAX_DATE_LENTH bytes.
|
||||
param day - value to be set with the day of the month as 1 ... 31
|
||||
param month - value to be set with the month of the year as 1 ... 12
|
||||
param year - value to be set with the year (4-digit)
|
||||
|
||||
return length of string created in buff.
|
||||
|
||||
Globals: global dateFormat value
|
||||
*/
|
||||
size_t
|
||||
qof_print_date_dmy_buff (char * buff, size_t len, int day, int month, int year)
|
||||
{
|
||||
int flen;
|
||||
if (!buff) return 0;
|
||||
|
||||
/* Note that when printing year, we use %-4d in format string;
|
||||
* this causes a one, two or three-digit year to be left-adjusted
|
||||
* when printed (i.e. padded with blanks on the right). This is
|
||||
* important while the user is editing the year, since erasing a
|
||||
* digit can temporarily cause a three-digit year, and having the
|
||||
* blank on the left is a real pain for the user. So pad on the
|
||||
* right.
|
||||
*/
|
||||
switch (dateFormat)
|
||||
{
|
||||
case QOF_DATE_FORMAT_UK:
|
||||
flen = g_snprintf (buff, len, "%02d/%02d/%-4d", day, month, year);
|
||||
break;
|
||||
case QOF_DATE_FORMAT_CE:
|
||||
flen = g_snprintf (buff, len, "%02d.%02d.%-4d", day, month, year);
|
||||
break;
|
||||
case QOF_DATE_FORMAT_LOCALE:
|
||||
{
|
||||
struct tm tm_str;
|
||||
time64 t;
|
||||
|
||||
tm_str.tm_mday = day;
|
||||
tm_str.tm_mon = month - 1; /* tm_mon = 0 through 11 */
|
||||
tm_str.tm_year = year - 1900; /* this is what the standard
|
||||
says, it's not a Y2K thing */
|
||||
|
||||
gnc_tm_set_day_start (&tm_str);
|
||||
t = gnc_mktime (&tm_str);
|
||||
gnc_localtime_r (&t, &tm_str);
|
||||
flen = qof_strftime (buff, len, GNC_D_FMT, &tm_str);
|
||||
if (flen != 0)
|
||||
break;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
case QOF_DATE_FORMAT_ISO:
|
||||
case QOF_DATE_FORMAT_UTC:
|
||||
flen = g_snprintf (buff, len, "%04d-%02d-%02d", year, month, day);
|
||||
break;
|
||||
case QOF_DATE_FORMAT_US:
|
||||
default:
|
||||
flen = g_snprintf (buff, len, "%02d/%02d/%-4d", month, day, year);
|
||||
break;
|
||||
}
|
||||
|
||||
return flen;
|
||||
GncDate date(year, month, day);
|
||||
std::string str = date.format(qof_date_format_get_string(dateFormat));
|
||||
strncpy(buff, str.c_str(), len);
|
||||
if (str.length() >= len)
|
||||
buff[len - 1] = '\0';
|
||||
return strlen(buff);
|
||||
}
|
||||
|
||||
size_t
|
||||
qof_print_date_buff (char * buff, size_t len, time64 t)
|
||||
{
|
||||
struct tm theTime;
|
||||
time64 bt = t;
|
||||
size_t actual;
|
||||
if (!buff) return 0;
|
||||
if (!gnc_localtime_r(&bt, &theTime))
|
||||
return 0;
|
||||
|
||||
actual = qof_print_date_dmy_buff (buff, len,
|
||||
theTime.tm_mday,
|
||||
theTime.tm_mon + 1,
|
||||
theTime.tm_year + 1900);
|
||||
return actual;
|
||||
GncDateTime gncdt(t);
|
||||
std::string str = gncdt.format(qof_date_format_get_string(dateFormat));
|
||||
strncpy(buff, str.c_str(), len);
|
||||
if (str.length() >= len)
|
||||
buff[len - 1] = '\0';
|
||||
return strlen(buff);
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -725,7 +624,6 @@ qof_print_gdate( char *buf, size_t len, const GDate *gd )
|
||||
GDate date;
|
||||
g_date_clear (&date, 1);
|
||||
date = *gd;
|
||||
gnc_gdate_range_check (&date);
|
||||
return qof_print_date_dmy_buff( buf, len,
|
||||
g_date_get_day(&date),
|
||||
g_date_get_month(&date),
|
||||
@ -1332,33 +1230,6 @@ gnc_dmy2timespec_end (int day, int month, int year)
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
long int
|
||||
gnc_timezone (const struct tm *tm)
|
||||
{
|
||||
g_return_val_if_fail (tm != NULL, 0);
|
||||
|
||||
#ifdef HAVE_STRUCT_TM_GMTOFF
|
||||
/* tm_gmtoff is seconds *east* of UTC and is
|
||||
* already adjusted for daylight savings time. */
|
||||
return -(tm->tm_gmtoff);
|
||||
#else
|
||||
{
|
||||
long tz_seconds;
|
||||
/* timezone is seconds *west* of UTC and is
|
||||
* not adjusted for daylight savings time.
|
||||
* In Spring, we spring forward, wheee! */
|
||||
# if COMPILER(MSVC)
|
||||
_get_timezone(&tz_seconds);
|
||||
# else
|
||||
tz_seconds = timezone;
|
||||
# endif
|
||||
return (long int)(tz_seconds - (tm->tm_isdst > 0 ? 3600 : 0));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
timespecFromTime64 ( Timespec *ts, time64 t )
|
||||
{
|
||||
@ -1411,7 +1282,6 @@ GDate* gnc_g_date_new_today ()
|
||||
|
||||
Timespec gdate_to_timespec (GDate d)
|
||||
{
|
||||
gnc_gdate_range_check (&d);
|
||||
return gnc_dmy2timespec(g_date_get_day(&d),
|
||||
g_date_get_month(&d),
|
||||
g_date_get_year(&d));
|
||||
|
@ -385,19 +385,6 @@ gchar * gnc_timespec_to_iso8601_buff (Timespec ts, gchar * buff);
|
||||
*/
|
||||
void gnc_timespec2dmy (Timespec ts, gint *day, gint *month, gint *year);
|
||||
|
||||
/** The gnc_timezone function returns the number of seconds *west*
|
||||
* of UTC represented by the tm argument, adjusted for daylight
|
||||
* savings time.
|
||||
*
|
||||
* This function requires a tm argument returned by localtime or set
|
||||
* by mktime. This is a strange function! It requires that localtime
|
||||
* or mktime be called before use. Subsequent calls to localtime or
|
||||
* mktime *may* invalidate the result! The actual contents of tm *may*
|
||||
* be used for both timezone offset and daylight savings time, or only
|
||||
* daylight savings time! Timezone stuff under unix is not
|
||||
* standardized and is a big mess.
|
||||
*/
|
||||
glong gnc_timezone (const struct tm *tm);
|
||||
// @}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
|
||||
void today() { m_greg = boost::gregorian::day_clock::local_day(); }
|
||||
ymd year_month_day() const;
|
||||
std::string format(const char* format) const;
|
||||
private:
|
||||
Date m_greg;
|
||||
};
|
||||
@ -76,6 +77,18 @@ GncDateImpl::year_month_day() const
|
||||
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
|
||||
@ -211,6 +224,7 @@ GncDateTimeImpl::format(const char* format) const
|
||||
}
|
||||
|
||||
/* =================== 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)) {}
|
||||
@ -228,12 +242,20 @@ 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();
|
||||
}
|
||||
|
||||
/* GncDateTime */
|
||||
|
||||
GncDateTime::GncDateTime() : m_impl(new GncDateTimeImpl) {}
|
||||
GncDateTime::GncDateTime(const time64 time) :
|
||||
m_impl(new GncDateTimeImpl(time)) {}
|
||||
|
@ -69,6 +69,15 @@ public:/** Construct a GncDate representing the current day.
|
||||
@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; }
|
||||
|
||||
@ -83,7 +92,7 @@ private:
|
||||
* between 1400 and 9999 CE.
|
||||
*
|
||||
* Be careful when using times: A particular time is represented
|
||||
* differently depending on the timezone, which can shif the displayed
|
||||
* differently depending on the timezone, which can shift the displayed
|
||||
* date. Accounting is generally not sensitive to the time of day, but
|
||||
* is sensitive to the recorded day. Since GncDates are not timezone
|
||||
* dependent they should be preferred for accounting entries.
|
||||
@ -142,11 +151,12 @@ 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
|
||||
* 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. Consult the boost::date_time
|
||||
* documentation for format characters; while they mostly compy with
|
||||
* POSIX there are a few differences.
|
||||
* according to the format.
|
||||
*/
|
||||
std::string format(const char* format) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user