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

View File

@ -81,21 +81,35 @@ GncDateImpl::ymd() const
static LDT
LDT_from_unix_local(const time64 time)
{
try
{
PTime temp(unix_epoch.date(),
boost::posix_time::hours(time / 3600) +
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
LDT_from_struct_tm(const struct tm tm)
{
try
{
auto tdate = boost::gregorian::date_from_tm(tm);
auto tdur = boost::posix_time::time_duration(tm.tm_hour, tm.tm_min,
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
@ -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())); }
long offset() const;
long nsecs() const;
struct tm utc_tm() const { return to_tm(m_time.utc_time()); }
std::unique_ptr<GncDateImpl> date() const;
std::string format(const char* format) const;
private:
@ -157,7 +172,11 @@ GncDateTimeImpl::operator time64() 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
@ -252,6 +271,12 @@ GncDateTime::nsecs() const
return m_impl->nsecs();
}
struct tm
GncDateTime::utc_tm() const
{
return m_impl->utc_tm();
}
GncDate
GncDateTime::date() const
{

View File

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