Domanda

Dato un Time_t o Struct Timeval, come ottengo il Timeval o Time_t di Midnight Est / EDT (ora locale) in quel giorno? Come presumere che il timezone locale è EST / EDT, dato un Time_T corrispondente a dire 2010-11-30 08:00:00 EST / EDT, la risposta prevista è un Time_T che corrisponde al 2010-11-30 00:00:00 EST/ EDT

Tentativo 1 (errato: poiché non gestisce DST e assume EST / EDT è sempre 5 ore dietro UTC):

time_t RewindToMidnight ( const time_t temp_time_t_ )
{
  return ( (5*3600) + ((( temp_time_t_ - 5*3600 )/86400 ) * 86400) );
}
.

Tentativo 2 (errato: poiché restituisce un time_t che corrisponde a quando è stato mezzanotte UTC e non EST / EDT, ora locale):

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_ );
}
.

Sento che dovrebbe esserci una soluzione che coinvolge (i) struct tm, mktime o (ii) boost :: local_date_time forse?

È stato utile?

Soluzione 3

Soluzione corrente:

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_ ) ) ;
}
.

Si prega di avvisare.

Altri suggerimenti

AS Time_T è tempo in pochi secondi da quando Epoch (00:00:00 UTC, 1 gennaio 1970), devi solo sbarazzarti dei secondi del giorno.Ci sono 86400 secondi in un giorno (i secondi del salto sono normalmente ignorati), quindi il risultato dovrebbe essere un multiplo di 86400. Quindi:

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);
}
.

Ho usato localtime_r poiché deve essere disponibile come l'hai anche usato nella tua risposta.

Esempio :

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;
}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top