Получите time_t / timeval, соответствующие (local_timezone) полуночи на данной дате
-
29-10-2019 - |
Вопрос
Учитывая time_t или struct timeval, как получить timeval или time_t midnight est / edt (локальный часовой пояс) в этот день? Как предполагая, что локальный часовой пояс есть EST / EDT, учитывая Time_t, соответствующий скажению, 2010-11-30 08:00:00 est / Estt, ожидаемый ответ - это Time_t, который соответствует 2010-11-30 00:00:00/ EDT
Попытка 1 (неверно: поскольку он не обрабатывает DST, и предполагает, что EST / EDT всегда 5 часов за UTC):
time_t RewindToMidnight ( const time_t temp_time_t_ )
{
return ( (5*3600) + ((( temp_time_t_ - 5*3600 )/86400 ) * 86400) );
}
.
Попытка 2 (неверно: поскольку он возвращает time_t, который соответствует, когда он был полуночным UTC, а не EST / EDT, локальный часовой пояс):
time_t RewindToMidnight ( const time_t temp_time_t_ )
{
boost::posix_time::ptime temp_ptime_ = boost::posix_time::from_time_t ( temp_time_t_ );
boost::gregorian::date temp_date_ = temp_ptime_.date();
boost::posix_time::ptime temp_ptime_midnight_ ( temp_date_,
boost::posix_time::time_duration ( 0, 0, 0 ) );
return to_time_t ( temp_ptime_midnight_ );
}
time_t to_time_t ( const boost::posix_time::ptime & temp_ptime_ )
{
boost::posix_time::ptime temp_epoch_ptime_(boost::gregorian::date(1970,1,1));
boost::posix_time::time_duration::sec_type temp_sec_type_ = ( temp_ptime_ - temp_epoch_ptime_ ).total_seconds();
return time_t ( temp_sec_type_ );
}
.
Я чувствую, что должно быть решение, связанное с (i) struct tm, mktime или (ii) Boost :: local_date_time Возможно?
Решение 3
Текущее решение:
time_t RewindToMidnight ( const time_t & temp_time_t_ )
{
int temp_yyyymmdd_ = iso_date_from_time_t ( temp_time_t_ );
return time_t_from_iso_date ( temp_yyyymmdd_ );
}
int iso_date_from_time_t ( const time_t & in_time_t_ )
{
tm temp_this_tm_;
{ // the following to set local dst fields of struct tm ?
time_t tvsec_ = time(NULL);
localtime_r ( & tvsec_, & temp_this_tm_ ) ;
}
localtime_r ( & in_time_t, & temp_this_tm_ ) ;
return ( ( ( ( 1900 + temp_this_tm_.tm_year ) * 100 + ( 1 + temp_this_tm_.tm_mon ) ) * 100 ) + temp_this_tm_.tm_mday ) ;
}
time_t time_t_from_iso_date ( const int & temp_yyyymmdd_ )
{
boost::gregorian::date d1 ( (int)( temp_yyyymmdd_/10000),
(int)( ( temp_yyyymmdd_/100) % 100),
(int)( temp_yyyymmdd_ % 100) );
std::tm this_tm_ = to_tm ( d1 );
return ( mktime ( & this_tm_ ) ) ;
}
.
Пожалуйста, посоветуйте.
Другие советы
как Time_t - это время в считанные секунды с момента эпохи (00:00:00 UTC, 1 января, 1970), вам просто нужно избавиться от секунды дня.В день в день 86400 секунд (выпрыгивающие секунды обычно игнорируются), поэтому результат должен быть кратным 86400. Следовательно:
time_t now = time();
time_t midnight = now / 86400 * 86400
. time_t local_midnight(time_t x) {
struct tm t;
localtime_r(&x, &t);
t.tm_sec = t.tm_min = t.tm_hour = 0;
return mktime(&t);
}
.
Я использовал localtime_r, поскольку он должен быть доступен, так как вы также использовали его в вашем ответе.
Пример :
int main() {
time_t now = time(0);
cout << "local: " << asctime(localtime(&now));
cout << "UTC: " << asctime(gmtime(&now));
time_t midnight = local_midnight(now);
cout << "\n " << asctime(localtime(&midnight));
return 0;
}
.