gnc_mktime and gnc_timegm with GncDateTime.

This commit is contained in:
John Ralls 2015-04-28 15:23:26 -07:00
parent 2dde36d015
commit d2f80a9407
3 changed files with 93 additions and 37 deletions

View File

@ -155,20 +155,34 @@ gnc_tm_free (struct tm* time)
struct tm* struct tm*
gnc_localtime (const time64 *secs) gnc_localtime (const time64 *secs)
{ {
auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm))); try
if (gnc_localtime_r (secs, time) == NULL) {
auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
if (gnc_localtime_r (secs, time) == NULL)
{
gnc_tm_free (time);
return NULL;
}
return time;
}
catch(std::invalid_argument)
{ {
gnc_tm_free (time);
return NULL; return NULL;
} }
return time;
} }
struct tm* struct tm*
gnc_localtime_r (const time64 *secs, struct tm* time) gnc_localtime_r (const time64 *secs, struct tm* time)
{ {
*time = static_cast<struct tm>(GncDateTime(*secs)); try
return time; {
*time = static_cast<struct tm>(GncDateTime(*secs));
return time;
}
catch(std::invalid_argument)
{
return NULL;
}
} }
static void static void
@ -232,34 +246,48 @@ normalize_struct_tm (struct tm* time)
struct tm* struct tm*
gnc_gmtime (const time64 *secs) gnc_gmtime (const time64 *secs)
{ {
auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm))); try
GncDateTime gncdt(*secs); {
*time = static_cast<struct tm>(gncdt); auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
auto gmtoff = gncdt.offset(); GncDateTime gncdt(*secs);
time->tm_hour -= gmtoff / 3600; *time = gncdt.utc_tm();
time->tm_min -= (gmtoff % 3600 / 60); return time;
time->tm_sec -= gmtoff % 60; }
normalize_struct_tm(time); catch(std::invalid_argument)
return time; {
return NULL;
}
} }
time64 time64
gnc_mktime (struct tm* time) gnc_mktime (struct tm* time)
{ {
normalize_struct_tm (time); try
auto ldt = gnc_get_LDT (time->tm_year + 1900, time->tm_mon + 1, {
time->tm_mday, time->tm_hour, time->tm_min, normalize_struct_tm (time);
time->tm_sec); GncDateTime gncdt(*time);
return time64_from_date_time(ldt); return static_cast<time64>(gncdt) - gncdt.offset();
}
catch(std::invalid_argument)
{
return 0;
}
} }
time64 time64
gnc_timegm (struct tm* time) gnc_timegm (struct tm* time)
{ {
auto newtime = *time; try
normalize_struct_tm(time); {
auto pdt = boost::posix_time::ptime_from_tm(*time); normalize_struct_tm(time);
return time64_from_date_time(pdt); return static_cast<time64>(GncDateTime(*time));
}
catch(std::invalid_argument)
{
return 0;
}
} }
char* char*

View File

@ -81,21 +81,35 @@ GncDateImpl::ymd() const
static LDT static LDT
LDT_from_unix_local(const time64 time) LDT_from_unix_local(const time64 time)
{ {
PTime temp(unix_epoch.date(), try
boost::posix_time::hours(time / 3600) + {
boost::posix_time::seconds(time % 3600)); PTime temp(unix_epoch.date(),
auto tz = tzp.get(temp.date().year()); boost::posix_time::hours(time / 3600) +
return LDT(temp, tz); boost::posix_time::seconds(time % 3600));
auto tz = tzp.get(temp.date().year());
return LDT(temp, tz);
}
catch(boost::gregorian::bad_year)
{
throw(std::invalid_argument("Time value is outside the supported year range."));
}
} }
static LDT static LDT
LDT_from_struct_tm(const struct tm tm) LDT_from_struct_tm(const struct tm tm)
{ {
auto tdate = boost::gregorian::date_from_tm(tm); try
auto tdur = boost::posix_time::time_duration(tm.tm_hour, tm.tm_min, {
tm.tm_sec, 0); auto tdate = boost::gregorian::date_from_tm(tm);
auto tz = tzp.get(tdate.year()); auto tdur = boost::posix_time::time_duration(tm.tm_hour, tm.tm_min,
return LDT(PTime(tdate, tdur), tz); tm.tm_sec, 0);
auto tz = tzp.get(tdate.year());
return LDT(PTime(tdate, tdur), tz);
}
catch(boost::gregorian::bad_year)
{
throw(std::invalid_argument("Time value is outside the supported year range."));
}
} }
class GncDateTimeImpl class GncDateTimeImpl
@ -113,6 +127,7 @@ public:
void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); } void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); }
long offset() const; long offset() const;
long nsecs() const; long nsecs() const;
struct tm utc_tm() const { return to_tm(m_time.utc_time()); }
std::unique_ptr<GncDateImpl> date() const; std::unique_ptr<GncDateImpl> date() const;
std::string format(const char* format) const; std::string format(const char* format) const;
private: private:
@ -157,7 +172,11 @@ GncDateTimeImpl::operator time64() const
GncDateTimeImpl::operator struct tm() const GncDateTimeImpl::operator struct tm() const
{ {
return to_tm(m_time); struct tm time = to_tm(m_time);
#if HAVE_STRUCT_TM_GMTOFF
time.tm_gmtoff = offset();
#endif
return time;
} }
long long
@ -252,6 +271,12 @@ GncDateTime::nsecs() const
return m_impl->nsecs(); return m_impl->nsecs();
} }
struct tm
GncDateTime::utc_tm() const
{
return m_impl->utc_tm();
}
GncDate GncDate
GncDateTime::date() const GncDateTime::date() const
{ {

View File

@ -123,8 +123,7 @@ public:
void now(); void now();
/** Cast the GncDateTime to a time64, seconds from the POSIX epoch. */ /** Cast the GncDateTime to a time64, seconds from the POSIX epoch. */
explicit operator time64() const; explicit operator time64() const;
/** Cast the GncDateTime to a struct tm. Timezone and offset fields /** Cast the GncDateTime to a struct tm. Timezone field isn't filled.
* are not filled.
*/ */
explicit operator struct tm() const; explicit operator struct tm() const;
/** Obtain the UTC offset in seconds /** Obtain the UTC offset in seconds
@ -137,6 +136,10 @@ public:
* with the time. * with the time.
*/ */
long nsecs() const; long nsecs() const;
/** Obtain a struct tm representing the time in UTC.
* @return struct tm
*/
struct tm utc_tm() const;
/** Obtain the date from the time, as a GncDate, in the current timezone. /** Obtain the date from the time, as a GncDate, in the current timezone.
* @return GncDate represented by the GncDateTime. * @return GncDate represented by the GncDateTime.
*/ */