Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 3 additions & 81 deletions include/boost/chrono/io/time_point_io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <boost/chrono/io/duration_io.hpp>
#include <boost/chrono/io/ios_base_state.hpp>
#include <boost/chrono/io/utility/manip_base.hpp>
#include <boost/chrono/io/utility/timegm.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/clock_string.hpp>
#include <boost/chrono/round.hpp>
Expand All @@ -34,15 +35,6 @@
#include <locale>
#include <ctime>

#if ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) ) \
|| (defined(sun) || defined(__sun)) \
|| (defined __IBMCPP__) \
|| defined __ANDROID__ \
|| defined __QNXNTO__ \
|| (defined(_AIX) && defined __GNUC__)
#define BOOST_CHRONO_INTERNAL_TIMEGM
#endif

#if (defined BOOST_WINDOWS && ! defined(__CYGWIN__)) \
|| ( (defined(sun) || defined(__sun)) && defined __GNUC__) \
|| (defined __IBMCPP__) \
Expand Down Expand Up @@ -748,66 +740,6 @@ namespace boost
namespace detail
{

//#if defined BOOST_CHRONO_INTERNAL_TIMEGM

inline int32_t is_leap(int32_t year)
{
if(year % 400 == 0)
return 1;
if(year % 100 == 0)
return 0;
if(year % 4 == 0)
return 1;
return 0;
}
inline int32_t days_from_0(int32_t year)
{
year--;
return 365 * year + (year / 400) - (year/100) + (year / 4);
}
inline int32_t days_from_1970(int32_t year)
{
static const int32_t days_from_0_to_1970 = days_from_0(1970);
return days_from_0(year) - days_from_0_to_1970;
}
inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
{
static const int32_t days[2][12] =
{
{ 0,31,59,90,120,151,181,212,243,273,304,334},
{ 0,31,60,91,121,152,182,213,244,274,305,335}
};

return days[is_leap(year)][month-1] + day - 1;
}

inline time_t internal_timegm(std::tm const *t)
{
int year = t->tm_year + 1900;
int month = t->tm_mon;
if(month > 11)
{
year += month/12;
month %= 12;
}
else if(month < 0)
{
int years_diff = (-month + 11)/12;
year -= years_diff;
month+=12 * years_diff;
}
month++;
int day = t->tm_mday;
int day_of_year = days_from_1jan(year,month,day);
int days_since_epoch = days_from_1970(year) + day_of_year ;

time_t seconds_in_day = 3600 * 24;
time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;

return result;
}
//#endif

/**
* from_ymd could be made more efficient by using a table
* day_count_table indexed by the y%400.
Expand Down Expand Up @@ -1161,13 +1093,7 @@ namespace boost
minutes min = detail::extract_z(i, eof, err, ct);

if (err & std::ios_base::failbit) goto exit;
time_t t;

#if defined BOOST_CHRONO_INTERNAL_TIMEGM
t = detail::internal_timegm(&tm);
#else
t = timegm(&tm);
#endif
time_t t = timegm_s(&tm);
tp = time_point_cast<Duration>(
system_clock::from_time_t(t) - min + round<system_clock::duration> (duration<fractional_seconds> (sec))
);
Expand Down Expand Up @@ -1215,11 +1141,7 @@ namespace boost
time_t t;
if (tz == timezone::utc || fz != pe)
{
#if defined BOOST_CHRONO_INTERNAL_TIMEGM
t = detail::internal_timegm(&tm);
#else
t = timegm(&tm);
#endif
t = timegm_s(&tm);
}
else
{
Expand Down
110 changes: 110 additions & 0 deletions include/boost/chrono/io/utility/timegm.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// boost/chrono/utility/timegm.hpp
//
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).

#ifndef BOOST_CHRONO_UTILITY_TIMEGM_HPP
#define BOOST_CHRONO_UTILITY_TIMEGM_HPP

#include <ctime>
#include <locale>

#if ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) ) \
|| (defined(sun) || defined(__sun)) \
|| (defined __IBMCPP__) \
|| defined __ANDROID__ \
|| defined __QNXNTO__ \
|| (defined(_AIX) && defined __GNUC__)
#define BOOST_CHRONO_INTERNAL_TIMEGM
#endif

namespace boost {
namespace chrono {

namespace detail {

inline int32_t is_leap(int32_t year) {
if (year % 400 == 0) {
return 1;
}
if (year % 100 == 0) {
return 0;
}
if (year % 4 == 0) {
return 1;
}
return 0;
}

#if defined BOOST_CHRONO_INTERNAL_TIMEGM

inline int32_t days_from_0(int32_t year) {
--year;
return 365 * year + (year / 400) - (year/100) + (year / 4);
}
inline int32_t days_from_1970(int32_t year) {
static const int32_t days_from_0_to_1970 = days_from_0(1970);
return days_from_0(year) - days_from_0_to_1970;
}
inline int32_t days_from_1jan(int32_t year, int32_t month, int32_t day) {
static const int32_t days[2][12] = {
{ 0,31,59,90,120,151,181,212,243,273,304,334},
{ 0,31,60,91,121,152,182,213,244,274,305,335}
};

return days[is_leap(year)][month-1] + day - 1;
}
inline std::time_t internal_timegm(const std::tm* t) {
int year = t->tm_year + 1900;
int month = t->tm_mon;
if (month > 11) {
year += month/12;
month %= 12;
} else if (month < 0) {
int years_diff = (-month + 11)/12;
year -= years_diff;
month += 12 * years_diff;
}
month++;
int day = t->tm_mday;
int day_of_year = days_from_1jan(year,month,day);
int days_since_epoch = days_from_1970(year) + day_of_year ;

std::time_t seconds_in_day = 3600 * 24;
std::time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;

return result;
}

#endif

} // detail

/**
* This function translates tm time as if it were utc in time_t.
* This function is inverse to gmtime from POSIX.
*/
inline std::time_t timegm_s(const std::tm* t) {
#if defined BOOST_CHRONO_INTERNAL_TIMEGM
#if defined BOOST_WINDOWS && ! defined(__CYGWIN__)
#if BOOST_MSVC < 1900
return detail::internal_timegm(t);
#else
std::tm temp_t = *t;
return _mkgmtime(&temp_t);
#endif
#else
return detail::internal_timegm(t);
#endif
#else
std::tm temp_t = *t;
return timegm(&temp_t);
#endif
}


} // chrono
} // boost

#endif // BOOST_CHRONO_UTILITY_TIMEGM_HPP