susumu.yata
null+****@clear*****
Thu Feb 28 11:02:53 JST 2013
susumu.yata 2013-02-28 11:02:53 +0900 (Thu, 28 Feb 2013) New Revision: edcbaf42c06e457b6bcebce12f1b5ec578297dca https://github.com/groonga/grnxx/commit/edcbaf42c06e457b6bcebce12f1b5ec578297dca Log: Implement grnxx::Time::universal/local_time(). Modified files: lib/broken_down_time.hpp lib/features.hpp lib/time.cpp lib/time.hpp Modified: lib/broken_down_time.hpp (+4 -0) =================================================================== --- lib/broken_down_time.hpp 2013-02-28 10:31:24 +0900 (43c7295) +++ lib/broken_down_time.hpp 2013-02-28 11:02:53 +0900 (34dd118) @@ -35,6 +35,10 @@ struct BrokenDownTime { int yday; // Day in the year. int isdst; // Daylight saving time. + static constexpr BrokenDownTime invalid_value() { + return BrokenDownTime{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + } + StringBuilder &write_to(StringBuilder &builder) const; }; Modified: lib/features.hpp (+1 -0) =================================================================== --- lib/features.hpp 2013-02-28 10:31:24 +0900 (87f579c) +++ lib/features.hpp 2013-02-28 11:02:53 +0900 (f6414f8) @@ -174,6 +174,7 @@ #if (GRNXX_POSIX_C_SOURCE >= 1) || GRNXX_XOPEN_SOURCE || GRNXX_BSD_SOURCE ||\ GRNXX_SVID_SOURCE || GRNXX_POSIX_SOURCE +# define GRNXX_HAS_GMTIME_R # define GRNXX_HAS_LOCALTIME_R #endif // (GRNXX_POSIX_C_SOURCE >= 1) || ... Modified: lib/time.cpp (+70 -0) =================================================================== --- lib/time.cpp 2013-02-28 10:31:24 +0900 (1ac00f2) +++ lib/time.cpp 2013-02-28 11:02:53 +0900 (3678f5c) @@ -33,9 +33,79 @@ #include "error.hpp" #include "intrinsic.hpp" #include "logger.hpp" +#include "lock.hpp" #include "string_format.hpp" namespace grnxx { +namespace { + +// Note: std::tm does not support usec (microseconds). +BrokenDownTime create_broken_down_time(const std::tm &tm, std::int64_t count) { + BrokenDownTime time; + time.usec = static_cast<int>(count % 1000000); + time.sec = tm.tm_sec; + time.min = tm.tm_min; + time.hour = tm.tm_hour; + time.mday = tm.tm_mday; + time.mon = tm.tm_mon; + time.year = tm.tm_year; + time.wday = tm.tm_wday; + time.yday = tm.tm_yday; + time.isdst = tm.tm_isdst; + return time; +} + +} // namespace + +BrokenDownTime Time::universal_time() const { + const std::time_t posix_time = static_cast<std::time_t>(count_ / 1000000); + std::tm tm; +#ifdef GRNXX_MSC + if (::gmtime_s(&posix_time, &tm) != 0) { + return BrokenDownTime::invalid_value(); + } +#elif defined(GRNXX_HAS_GMTIME_R) + if (::gmtime_r(&posix_time, &tm) == nullptr) { + return BrokenDownTime::invalid_value(); + } +#else // defined(GRNXX_HAS_GMTIME_R) + // Lock is used for exclusive access, but it is still not thread-safe + // because other threads may call std::gmtime(). + static Mutex mutex(MUTEX_UNLOCKED); + Lock lock(&mutex); + std::tm * const shared_tm = std::gmtime(&posix_time); + if (!shared_tm) { + return BrokenDownTime::invalid_value(); + } + tm = *shared_tm; +#endif // defined(GRNXX_HAS_GMTIME_R) + return create_broken_down_time(tm, count_); +} + +BrokenDownTime Time::local_time() const { + const std::time_t posix_time = static_cast<std::time_t>(count_ / 1000000); + std::tm tm; +#ifdef GRNXX_MSC + if (::localtime_s(&posix_time, &tm) != 0) { + return BrokenDownTime::invalid_value(); + } +#elif defined(GRNXX_HAS_LOCALTIME_R) + if (::localtime_r(&posix_time, &tm) == nullptr) { + return BrokenDownTime::invalid_value(); + } +#else // defined(GRNXX_HAS_LOCALTIME_R) + // Lock is used for exclusive access, but it is still not thread-safe + // because other threads may call std::localtime(). + static Mutex mutex(MUTEX_UNLOCKED); + Lock lock(&mutex); + std::tm * const shared_tm = std::localtime(&posix_time); + if (!shared_tm) { + return BrokenDownTime::invalid_value(); + } + tm = *shared_tm; +#endif // defined(GRNXX_HAS_LOCALTIME_R) + return create_broken_down_time(tm, count_); +} StringBuilder &Time::write_to(StringBuilder &builder) const { if (!builder) { Modified: lib/time.hpp (+0 -1) =================================================================== --- lib/time.hpp 2013-02-28 10:31:24 +0900 (849bf12) +++ lib/time.hpp 2013-02-28 11:02:53 +0900 (f5feaa7) @@ -42,7 +42,6 @@ class Time { return Time(std::numeric_limits<int64_t>::max()); } - // TODO: To be implemented. // Transform tick count to broken-down time (UTC). BrokenDownTime universal_time() const; // Transform tick count to broken-down time (local). -------------- next part -------------- HTML����������������������������...Download