Created
July 8, 2014 07:31
-
-
Save notcome/526b1fbca6cb359c1152 to your computer and use it in GitHub Desktop.
Convert std::chrono::system_clock::time_point to std::tm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <ratio> | |
#include <chrono> | |
#include <string> | |
template <typename value_type> | |
struct timed { | |
std::chrono::time_point<std::chrono::steady_clock> timestamp; | |
value_type value; | |
timed (const value_type &value): | |
value(value), timestamp(std::chrono::steady_clock::now()) | |
{} | |
timed (value_type &&rvalue): | |
value(std::move(rvalue)), timestamp(std::chrono::steady_clock::now()) | |
{} | |
}; | |
typedef timed<std::string> commitMessage; | |
constexpr int getWeekdayFromDays (int days) { | |
if (days >= -4) | |
return (days + 4) % 7; | |
else | |
return (days + 5) % 7 + 6; | |
} | |
//From 1970-01-01 -> 0000-03-01 | |
constexpr int shiftEpoch (int days) { | |
const int EpochShiftDays = 719468; | |
return days + EpochShiftDays; | |
} | |
constexpr int getEraFromDays (int days) { | |
const int dEra = 365 * 400 + 97; | |
return (days >= 0 ? days : days - (dEra - 1)) / dEra; | |
} | |
constexpr int getDayOfEra (int days, int era) { | |
const int dEra = 365 * 400 + 97; | |
return days - era * dEra; | |
} | |
constexpr int getYearOfEra (int dayOfEra) { | |
const int d4Years = 365 * 4 + 1; | |
const int d100Years = 365 * 100 + 24; | |
const int d400Years = 365 * 400 + 97; | |
const int adjustedDays = dayOfEra - dayOfEra / (d4Years - 1) | |
+ dayOfEra / d100Years | |
- dayOfEra / (d400Years - 1); | |
return adjustedDays / 365; | |
} | |
constexpr int getYDay (int dayOfEra, int yearOfEra) { | |
return dayOfEra - (365 * yearOfEra + yearOfEra / 4 - yearOfEra / 100); | |
} | |
constexpr std::tuple<int, int, int, int> getYMDFromDays (int days) { | |
days = shiftEpoch(days); | |
const int era = getEraFromDays(days); | |
const int dayOfEra = getDayOfEra(days, era); | |
const int yearOfEra = getYearOfEra(dayOfEra); | |
const int shiftedYear = yearOfEra + era * 400; | |
const int yday = getYDay(dayOfEra, yearOfEra); | |
//dMarch + dApril + dMay + dJune + dJuly | |
const int dToAugust = 31 + 30 + 31 + 30 + 31; | |
const int shiftedMonth = (5 * yday + 2) / dToAugust; | |
const int mday = yday - (dToAugust * shiftedMonth + 2) / 5 + 1; | |
const int month = shiftedMonth + (shiftedMonth < 10 ? 3 : -9); | |
const int year = shiftedYear + (month <= 2 ? 1 : 0); | |
return std::tuple<int, int, int, int>(year, month, mday, yday); | |
} | |
std::tm toUTCTime (const std::chrono::system_clock::time_point &tp) { | |
using namespace std; | |
using namespace chrono; | |
typedef duration<int, ratio_multiply<hours::period, ratio<24>>> days; | |
auto t = tp.time_since_epoch(); | |
days d = duration_cast<days>(t); | |
t -= d; | |
int year, month, mday, yday; | |
std::tie(year, month, mday, yday) = getYMDFromDays(d.count()); | |
std::tm tm = {0}; | |
tm.tm_year = year - 1900; | |
tm.tm_mon = month - 1; | |
tm.tm_yday = yday; | |
tm.tm_mday = mday; | |
tm.tm_wday = getWeekdayFromDays(d.count()); | |
tm.tm_hour = static_cast<int>(duration_cast<hours>(t).count()); | |
t -= hours(tm.tm_hour); | |
tm.tm_min = static_cast<int>(duration_cast<minutes>(t).count()); | |
t -= minutes(tm.tm_min); | |
tm.tm_sec = static_cast<int>(duration_cast<seconds>(t).count()); | |
t -= seconds(tm.tm_sec); | |
return tm; | |
} | |
int main () { | |
using namespace std; | |
using namespace chrono; | |
auto t = system_clock::now(); | |
auto tm = toUTCTime(t); | |
cout << asctime(&tm); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment