2013-01-25 18:21:14 +00:00
|
|
|
#include <fc/time.hpp>
|
2013-06-05 19:19:00 +00:00
|
|
|
#include <fc/variant.hpp>
|
2012-09-08 02:50:37 +00:00
|
|
|
#include <boost/chrono/system_clocks.hpp>
|
2012-11-18 06:07:10 +00:00
|
|
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
2012-10-18 02:44:21 +00:00
|
|
|
#include <sstream>
|
2014-03-31 20:10:52 +00:00
|
|
|
#include <fc/string.hpp>
|
|
|
|
|
#include <fc/io/sstream.hpp>
|
2014-05-27 14:05:58 +00:00
|
|
|
#include <fc/exception/exception.hpp>
|
2012-09-08 02:50:37 +00:00
|
|
|
|
|
|
|
|
namespace fc {
|
|
|
|
|
namespace bch = boost::chrono;
|
|
|
|
|
time_point time_point::now() {
|
|
|
|
|
return time_point(microseconds(bch::duration_cast<bch::microseconds>(bch::system_clock::now().time_since_epoch()).count()));
|
|
|
|
|
}
|
2012-10-18 02:44:21 +00:00
|
|
|
time_point::operator fc::string()const {
|
|
|
|
|
bch::system_clock::time_point tp;
|
|
|
|
|
tp += bch::microseconds( elapsed._count);
|
|
|
|
|
time_t tt = bch::system_clock::to_time_t(tp);
|
2013-01-25 18:21:14 +00:00
|
|
|
|
|
|
|
|
return boost::posix_time::to_iso_string( boost::posix_time::from_time_t(tt) + boost::posix_time::microseconds( elapsed._count % 1000000 ) );
|
2012-10-18 02:44:21 +00:00
|
|
|
}
|
2014-05-27 14:05:58 +00:00
|
|
|
time_point time_point::from_iso_string( const fc::string& s )
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
auto pt = boost::posix_time::from_iso_string(s);
|
|
|
|
|
//return fc::time_point(fc::seconds( (pt - boost::posix_time::from_time_t(0)).total_seconds() ));
|
|
|
|
|
return fc::time_point(fc::microseconds( (pt - boost::posix_time::from_time_t(0)).total_microseconds() ));
|
|
|
|
|
}
|
|
|
|
|
FC_RETHROW_EXCEPTIONS(warn, "unable to convert ISO-formatted string to fc::time_point")
|
2013-01-20 20:44:16 +00:00
|
|
|
}
|
2014-07-27 01:05:11 +00:00
|
|
|
|
|
|
|
|
fc::string time_point_sec::to_iso_string()const
|
|
|
|
|
{
|
|
|
|
|
const auto ptime = boost::posix_time::from_time_t( time_t ( sec_since_epoch() ) );
|
|
|
|
|
return boost::posix_time::to_iso_string( ptime );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fc::string time_point_sec::to_iso_extended_string()const
|
|
|
|
|
{
|
|
|
|
|
const auto ptime = boost::posix_time::from_time_t( time_t ( sec_since_epoch() ) );
|
|
|
|
|
return boost::posix_time::to_iso_extended_string( ptime );
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-05 19:19:00 +00:00
|
|
|
void to_variant( const fc::time_point& t, variant& v ) {
|
2013-01-20 20:44:16 +00:00
|
|
|
v = fc::string(t);
|
|
|
|
|
}
|
2013-06-05 19:19:00 +00:00
|
|
|
void from_variant( const fc::variant& v, fc::time_point& t ) {
|
|
|
|
|
t = fc::time_point::from_iso_string(v.as_string());
|
2013-01-20 20:44:16 +00:00
|
|
|
}
|
2013-07-22 18:03:34 +00:00
|
|
|
void to_variant( const fc::time_point_sec& t, variant& v ) {
|
|
|
|
|
v = fc::string(fc::time_point(t));
|
|
|
|
|
}
|
|
|
|
|
void from_variant( const fc::variant& v, fc::time_point_sec& t ) {
|
|
|
|
|
t = fc::time_point::from_iso_string(v.as_string());
|
|
|
|
|
}
|
2014-03-31 20:10:52 +00:00
|
|
|
|
|
|
|
|
// inspired by show_date_relative() in git's date.c
|
2014-06-15 18:16:00 +00:00
|
|
|
string get_approximate_relative_time_string(const time_point_sec& event_time,
|
|
|
|
|
const time_point_sec& relative_to_time /* = fc::time_point::now() */,
|
2014-06-17 15:12:15 +00:00
|
|
|
const std::string& default_ago /* = " ago" */) {
|
2014-06-15 18:16:00 +00:00
|
|
|
|
2014-06-17 15:12:15 +00:00
|
|
|
|
|
|
|
|
string ago = default_ago;
|
2014-06-17 19:45:16 +00:00
|
|
|
int32_t seconds_ago = relative_to_time.sec_since_epoch() - event_time.sec_since_epoch();
|
|
|
|
|
if (seconds_ago < 0)
|
|
|
|
|
{
|
2014-06-17 15:12:15 +00:00
|
|
|
ago = " in the future";
|
2014-06-17 19:45:16 +00:00
|
|
|
seconds_ago = -seconds_ago;
|
|
|
|
|
}
|
2014-03-31 20:10:52 +00:00
|
|
|
stringstream result;
|
|
|
|
|
if (seconds_ago < 90)
|
|
|
|
|
{
|
2014-06-15 18:16:00 +00:00
|
|
|
result << seconds_ago << " second" << (seconds_ago > 1 ? "s" : "") << ago;
|
2014-03-31 20:10:52 +00:00
|
|
|
return result.str();
|
|
|
|
|
}
|
|
|
|
|
uint32_t minutes_ago = (seconds_ago + 30) / 60;
|
|
|
|
|
if (minutes_ago < 90)
|
|
|
|
|
{
|
2014-06-15 18:16:00 +00:00
|
|
|
result << minutes_ago << " minute" << (minutes_ago > 1 ? "s" : "") << ago;
|
2014-03-31 20:10:52 +00:00
|
|
|
return result.str();
|
|
|
|
|
}
|
|
|
|
|
uint32_t hours_ago = (minutes_ago + 30) / 60;
|
|
|
|
|
if (hours_ago < 90)
|
|
|
|
|
{
|
2014-06-15 18:16:00 +00:00
|
|
|
result << hours_ago << " hour" << (hours_ago > 1 ? "s" : "") << ago;
|
2014-03-31 20:10:52 +00:00
|
|
|
return result.str();
|
|
|
|
|
}
|
|
|
|
|
uint32_t days_ago = (hours_ago + 12) / 24;
|
|
|
|
|
if (days_ago < 90)
|
|
|
|
|
{
|
2014-06-15 18:16:00 +00:00
|
|
|
result << days_ago << " day" << (days_ago > 1 ? "s" : "") << ago;
|
2014-03-31 20:10:52 +00:00
|
|
|
return result.str();
|
|
|
|
|
}
|
|
|
|
|
uint32_t weeks_ago = (days_ago + 3) / 7;
|
|
|
|
|
if (weeks_ago < 70)
|
|
|
|
|
{
|
2014-06-15 18:16:00 +00:00
|
|
|
result << weeks_ago << " week" << (weeks_ago > 1 ? "s" : "") << ago;
|
2014-03-31 20:10:52 +00:00
|
|
|
return result.str();
|
|
|
|
|
}
|
|
|
|
|
uint32_t months_ago = (days_ago + 15) / 30;
|
|
|
|
|
if (months_ago < 12)
|
|
|
|
|
{
|
2014-06-15 18:16:00 +00:00
|
|
|
result << months_ago << " month" << (months_ago > 1 ? "s" : "") << ago;
|
2014-03-31 20:10:52 +00:00
|
|
|
return result.str();
|
|
|
|
|
}
|
|
|
|
|
uint32_t years_ago = days_ago / 365;
|
2014-07-01 19:20:58 +00:00
|
|
|
result << years_ago << " year" << (months_ago > 1 ? "s " : " ");
|
2014-03-31 20:10:52 +00:00
|
|
|
if (months_ago < 12 * 5)
|
|
|
|
|
{
|
|
|
|
|
uint32_t leftover_days = days_ago - (years_ago * 365);
|
|
|
|
|
uint32_t leftover_months = (leftover_days + 15) / 30;
|
|
|
|
|
if (leftover_months)
|
|
|
|
|
result << leftover_months << " month" << (months_ago > 1 ? "s" : "");
|
|
|
|
|
}
|
2014-06-15 18:16:00 +00:00
|
|
|
result << ago;
|
2014-03-31 20:10:52 +00:00
|
|
|
return result.str();
|
|
|
|
|
}
|
2014-06-15 18:16:00 +00:00
|
|
|
string get_approximate_relative_time_string(const time_point& event_time,
|
|
|
|
|
const time_point& relative_to_time /* = fc::time_point::now() */,
|
|
|
|
|
const std::string& ago /* = " ago" */) {
|
|
|
|
|
return get_approximate_relative_time_string(time_point_sec(event_time), time_point_sec(relative_to_time), ago);
|
2014-03-31 20:10:52 +00:00
|
|
|
}
|
2014-06-04 17:51:32 +00:00
|
|
|
|
|
|
|
|
void to_variant( const microseconds& input_microseconds, variant& output_variant )
|
|
|
|
|
{
|
|
|
|
|
output_variant = input_microseconds.count();
|
|
|
|
|
}
|
|
|
|
|
void from_variant( const variant& input_variant, microseconds& output_microseconds )
|
|
|
|
|
{
|
|
|
|
|
output_microseconds = microseconds(input_variant.as_int64());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} //namespace fc
|