Die Boost C++ Bibliotheken

Ortsabhängige Zeitpunkte

Der Unterschied zu den im vorherigen Abschnitt kennengelernten ortsunabhängigen Zeitpunkten ist, dass ortsabhängige Zeitpunkte Zeitzonen berücksichtigen. Dazu bietet Boost.DateTime eine Klasse boost::local_time::local_date_time an, die die Klasse boost::local_time::posix_time_zone verwendet, in der Einstellungen zur Zeitzone gespeichert sind. Um auf diese Klassen zugreifen zu können, muss die Headerdatei boost/date_time/local_time/local_time.hpp eingebunden werden.

Beispiel 36.17. boost::local_time::local_date_time in Aktion
#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>

using namespace boost::local_time;
using namespace boost::posix_time;
using namespace boost::gregorian;

int main()
{
  time_zone_ptr tz{new posix_time_zone{"CET+1"}};
  ptime pt{date{2014, 5, 12}, time_duration{12, 0, 0}};
  local_date_time dt{pt, tz};
  std::cout << dt.utc_time() << '\n';
  std::cout << dt << '\n';
  std::cout << dt.local_time() << '\n';
  std::cout << dt.zone_name() << '\n';
}

Der Konstruktor der Klasse boost::local_time::local_date_time erwartet als ersten Parameter ein Objekt vom Typ boost::posix_time::ptime und als zweiten Parameter ein Objekt vom Typ boost::local_time::time_zone_ptr. Es handelt sich dabei um eine Typdefinition für boost::shared_ptr<boost::local_time::time_zone>. Die Typdefinition verwendet boost::local_time::time_zone und nicht boost::local_time::posix_time_zone. Das ist insofern kein Problem, als dass boost::local_time::posix_time_zone von boost::local_time::time_zone abgeleitet ist. Das macht es möglich, Boost.DateTime um benutzerdefinierte Zeitzonen zu erweitern.

An den Konstruktor von boost::local_time::local_date_time wird demnach kein Objekt vom Typ boost::local_time::posix_time_zone übergeben, sondern ein Smartpointer auf dieses. So können sich mehrere Objekte vom Typ boost::local_time::local_date_time eine Zeitzone teilen. Wenn das letzte Objekt zerstört wird, wird automatisch das entsprechende Objekt, das die Zeitzone repräsentiert, freigegeben.

Um ein Objekt vom Typ boost::local_time::posix_time_zone zu erstellen, wird dem Konstruktor als einziger Parameter ein String übergeben, der die Zeitzone beschreibt. Im Beispiel 36.17 wird angegeben, dass es sich bei der Zeitzone um Mitteleuropa handelt: CET ist die Abkürzung für Central European Time. Da CET eine Stunde vor UTC liegt, wird als Abweichung in Stunden +1 angegeben. Boost.DateTime interpretiert Abkürzungen für Zeitzonen nicht selbst und weiß nicht, was CET bedeutet. Sie müssen immer eine Abweichung in Stunden angeben. Wollen Sie keine Abweichung verwenden, geben Sie +0 an.

Wenn Sie Beispiel 36.17 ausführen, wird 2014-May-12 12:00:00, 2014-May-12 13:00:00 CET, 2014-May-12 13:00:00 und CET auf die Standardausgabe ausgegeben. Werte, mit denen Objekte vom Typ boost::posix_time::ptime und boost::local_time::local_date_time initialisiert werden, werden grundsätzlich auf die UTC-Zeitzone bezogen. Erst bei der Ausgabe eines Objekts vom Typ boost::local_time::local_date_time auf die Standardausgabe und beim Aufruf von local_time() wird die Abweichung in Stunden zur Berechnung der lokalen Uhrzeit herangezogen.

Beispiel 36.18. Ortsabhängige Zeitpunkte und unterschiedliche Zeitzonen
#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>

using namespace boost::local_time;
using namespace boost::posix_time;
using namespace boost::gregorian;

int main()
{
  time_zone_ptr tz{new posix_time_zone{"CET+1"}};

  ptime pt{date{2014, 5, 12}, time_duration{12, 0, 0}};
  local_date_time dt{pt, tz};
  std::cout << dt.local_time() << '\n';

  time_zone_ptr tz2{new posix_time_zone{"EET+2"}};
  std::cout << dt.local_time_in(tz2).local_time() << '\n';
}

Wenn Sie die Methode local_time() verwenden, wird die Abweichung in der Zeitzone berücksichtigt. Wenn der UTC-Zeitpunkt 12 Uhr mittags in dt für die Zeitzone CET berechnet werden soll, bedeutet das, dass eine Stunde hinzugefügt werden muss. Denn CET ist der Zeitzone UTC um eine Stunde voraus. Die Methode local_time() gibt demnach 2014-May-12 13:00:00 zurück.

Die Methode local_time_in() interpretiert den Zeitpunkt in dt so, als läge er in der Zeitzone, die als Parameter übergeben wird. Für Beispiel 36.18 bedeutet dies, dass 12 Uhr mittags in UTC 14 Uhr in EET ergibt. EET ist die Abkürzung für Eastern European Time, die um zwei Stunden vor UTC liegt.

Nachdem Sie ortsabhängige Zeitpunkte kennengelernt haben, wird Ihnen abschließend das ortsabhängige Zeitintervall vorgestellt. Dazu stellt Boost.DateTime die Klasse boost::local_time::local_time_period zur Verfügung.

Beispiel 36.19. boost::local_time::local_time_period in Aktion
#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>

using namespace boost::local_time;
using namespace boost::posix_time;
using namespace boost::gregorian;

int main()
{
  time_zone_ptr tz{new posix_time_zone{"CET+0"}};

  ptime pt1{date{2014, 12, 5}, time_duration{12, 0, 0}};
  local_date_time dt1{pt1, tz};

  ptime pt2{date{2014, 12, 5}, time_duration{18, 0, 0}};
  local_date_time dt2{pt2, tz};

  local_time_period tp{dt1, dt2};

  std::cout.setf(std::ios::boolalpha);
  std::cout << tp.contains(dt1) << '\n';
  std::cout << tp.contains(dt2) << '\n';
}

Wie im Beispiel 36.19 zu sehen, erwartet der Konstruktor von boost::local_time::local_time_period zwei Parameter vom Typ boost::local_time::local_date_time. So wie bei den anderen Typen für Zeitintervalle, die Boost.DateTime anbietet, ist der zweite Parameter, der den Endzeitpunkt darstellt, gerade nicht mehr im Zeitintervall enthalten. Über die in diesem Kapitel mehrfach erwähnten Methoden contains(), intersection(), merge() und andere können auch bei boost::local_time::local_time_period Zeitintervalle verarbeitet werden.