43 votes

Comment convertir boost::posix_time::ptime en time_t ?

Existe-t-il une méthode "standard" ou le mieux que je puisse faire est de le calculer directement en soustrayant de gregorian::date(1970,1,1) ?

4 votes

Juste une idée ; j'utilise boost::posix_time::from_time_t(0) au lieu d'un temps explicite dans le calendrier grégorien, pour obtenir un point de référence qui s'ajustera automatiquement à l'époque du système compilé.

0 votes

@Rawler, c'est probablement beaucoup mieux -- j'ai découvert que l'époque réelle est apparemment 2000ns avant ce qui est représenté par gregorian::date(1970,1,1) .

1 votes

@BrianCain D'où vient l'idée de 2000ns avant le fameux timestamp epoch ? D'aussi loin que je me souvienne et que j'ai lu, j'ai toujours entendu dire que epoch était 1970-01-01 00:00:00.0 UTC.

37voto

ybungalobill Points 31467

Comme la méthode de @icecrime convertit deux fois (ptime utilise la représentation linéaire en interne), j'ai décidé d'utiliser le calcul direct à la place. Le voici :

time_t to_time_t(boost::posix_time::ptime t)
{
    using namespace boost::posix_time;
    ptime epoch(boost::gregorian::date(1970,1,1));
    time_duration::sec_type x = (t - epoch).total_seconds();

    // ... check overflow here ...

    return time_t(x);
}

EDITAR: Merci @jaaw d'avoir attiré mon attention sur ce point. Depuis boost 1.58 cette fonction est incluse dans date_time/posix_time/conversion.hpp , std::time_t to_time_t(ptime pt) .

16 votes

C'est vraiment dommage qu'ils n'aient pas ajouté cet appel de fonction direct dans la bibliothèque... Je me demande quelles étaient les raisons...

2 votes

Pourrait rendre ptime epoch statique plutôt que de calculer chaque appel.

3 votes

Use std::time_t posix_time::to_time_t(posix_time::ptime pt) in conversion.hpp

16voto

Nim Points 22570

time_t est le type utilisé pour contenir le temps en secondes (typiquement le temps de l'époque). Je suppose que vous recherchez le temps d'époque, si c'est le cas, je ne connais aucun moyen d'obtenir directement le temps d'époque, en dehors de la soustraction que vous avez déjà effectuée. Une fois que vous avez un time_duration (résultat de la soustraction), vous pouvez appeler total_seconds() sur la durée et le stocker dans time_t .

En fait, si vous recherchez le temps de l'époque, vous pouvez simplement utiliser gettimeofday() et vous épargner des maux de tête !

15voto

kgriffs Points 1839

Voici une variante de la méthode de @ybungalobill qui vous permettra de dépasser 2038, juste au cas où. :)

int64_t rax::ToPosix64(const boost::posix_time::ptime& pt)
{
  using namespace boost::posix_time;
  static ptime epoch(boost::gregorian::date(1970, 1, 1));
  time_duration diff(pt - epoch);
  return (diff.ticks() / diff.ticks_per_second());
}

1 votes

Oui, mais lorsque vous écrivez une application multiplateforme, vous devez également prendre en charge le 32 bits.

2 votes

@ybungalobill : Le problème n'est pas tant time_t mais time_duration::sec_type qui est en 32 bits (du moins sur ma machine).

0 votes

N'oubliez pas qu'un ptime peut également avoir plusieurs valeurs spéciales ( not_a_date_time , pos_infin y neg_infin ). Ajout de assert(!pt.is_special()); peut être une bonne idée.

5voto

icecrime Points 23650

Je crois que le mieux que vous puissiez faire est d'utiliser to_tm pour obtenir un tm y mktime pour convertir le tm à un time_t .

3 votes

Mais je crois que mktime a un ajustement implicite du fuseau horaire (il indique le nombre de secondes depuis l'époque en heure locale)'.

2voto

Ramesh Points 11

Ces 2 lignes devraient le faire.

tm td_tm = to_tm(pt);
time_t tt = mktime(&td_tm);

5 votes

La chose à laquelle il faut faire attention avec ceci et la solution d'icecrime ci-dessus est le contrat d'entrée de posix mktime. mktime prend une structure "exprimée en tant que temps local, en représentation de temps calendaire" et la convertit pour vous. Cependant, boost p_time ne fait aucune conversion TZ pour vous lorsque vous remplissez la structure tm. Donc, si vous cherchez un temps d'époque absolu sous la forme d'un nombre de secondes depuis le 1er janvier 1970 à minuit UTC et que la ZT locale de votre machine n'est pas GMT, cet appel ne vous donnera pas ce que vous voulez. Soustraire une époque explicitement construite et prendre la seconde différence est clair, évident et sûr pour le TZ.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X