ex_meeting_planner.xml 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
  3. "../../../tools/boostbook/dtd/boostbook.dtd">
  4. <!-- Copyright (c) 2001-2005 CrystalClear Software, Inc.
  5. Subject to the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  7. -->
  8. <section id="date_time.examples.meeting_planner">
  9. <title>Teleconference Scheduler (partial listing)</title>
  10. <para>
  11. The Teleconference Scheduler is a Qt based example (found in the examples/qt directory). Partial listings of <link linkend="meeting_planner_hpp">meeting_planner.hpp</link> and <link linkend="planner_form_cpp">planner_form.cpp</link> are provided to illustrate techniques for using the local_date_time and tz_database objects.
  12. </para>
  13. <anchor id="planner_form_cpp" />
  14. <para>
  15. The planner_form class is derived from a QDialog. This listing illustrates the initialization of a tz_database object and using it to populate combo boxes with region lists. Only the init function is listed here for the sake of brevity.
  16. </para>
  17. <programlisting>
  18. <![CDATA[
  19. void planner_form::init() {
  20. try{
  21. tz_db.load_from_file("../../data/date_time_zonespec.csv");
  22. }catch(boost::local_time::data_not_accessible dna) {
  23. std::cerr << "Error with time zone data file: " << dna.what() << std::endl;
  24. exit(EXIT_FAILURE);
  25. }catch(boost::local_time::bad_field_count bfc) {
  26. std::cerr << "Error with time zone data file: " << bfc.what() << std::endl;
  27. exit(EXIT_FAILURE);
  28. }
  29. // populate combo boxes with region names
  30. typedef std::vector<std::string> vect;
  31. vect regions = tz_db.region_list();
  32. vect::const_iterator itr = regions.begin();
  33. while(itr != regions.end()) {
  34. comboBox1->insertItem(*itr);
  35. comboBox2->insertItem(*itr);
  36. comboBox3->insertItem(*itr);
  37. ++itr;
  38. }
  39. comboBox1->insertItem("<Select Region>", 0);
  40. comboBox2->insertItem("<Select Region>", 0);
  41. comboBox3->insertItem("<Select Region>", 0);
  42. // set up dateEdit
  43. dateEdit2->setSeparator("-");
  44. this->reset();
  45. }
  46. ]]>
  47. </programlisting>
  48. <anchor id="meeting_planner_hpp" />
  49. <para>
  50. This class coordinates local times across multiple time zones. It accomplishes this by iterating across a collection of time zones and verifying that the target time falls within a set period (a workday).
  51. </para>
  52. <programlisting>
  53. <![CDATA[
  54. /* The heart of the meeting_planner is the synchronization of different
  55. * time zones to a single point in time.
  56. * The class takes a vector of regions and a date. The default time
  57. * range is 9am to 5pm but can be changed.
  58. * The resulting time specs are returned as a vector of strings
  59. */
  60. #include "boost/date_time/gregorian/gregorian.hpp"
  61. #include "boost/date_time/posix_time/posix_time.hpp"
  62. #include "boost/date_time/local_time/local_time.hpp"
  63. #include "boost/shared_ptr.hpp"
  64. #include <string>
  65. #include <vector>
  66. #include <locale>
  67. using namespace boost;
  68. using namespace local_time;
  69. using namespace posix_time;
  70. //! Coordinates meeting times accounting for time zone differences
  71. class meeting_planner {
  72. public:
  73. typedef std::vector<shared_ptr<time_zone_base> > vector_type;
  74. // a multimap is used so time_zones can be sorted according to utc_offset
  75. typedef std::multimap<posix_time::time_duration, shared_ptr<time_zone_base> > zone_map_type;
  76. typedef std::vector<std::string> result_type;
  77. meeting_planner(const gregorian::date& d, const vector_type& v)
  78. : l_time(posix_time::not_a_date_time, shared_ptr<time_zone_base>()),
  79. workday(ptime(d,hours(9)), time_duration(8,0,0,1))
  80. {
  81. vector_type::const_iterator iter = v.begin();
  82. while(iter != v.end()) {
  83. time_duration offset(0,0,0);
  84. if(*iter == NULL) {
  85. offset = hours(0);
  86. }
  87. else{
  88. // null pointers may wind up in the vector
  89. // TODO: this should be fixed in tz_database
  90. offset = (*iter)->base_utc_offset();
  91. }
  92. zones.insert(zone_map_type::value_type(offset, *iter));
  93. ++iter;
  94. }
  95. // set l_time to noon UTC
  96. l_time = local_date_time(posix_time::ptime(d, posix_time::hours(12)),
  97. shared_ptr<time_zone_base>());
  98. }
  99. //! Changes range of valid meeting times (ie. The hours in a workday) times are inclusive
  100. void change_range(const time_duration& start, const time_duration& end)
  101. {
  102. ptime pt(l_time.date(), start);
  103. // add one unit to make the give times inclusive
  104. workday = time_period(pt, (end - start) + time_duration::unit());
  105. }
  106. //! strings returned in the form of "yyyy-Mon-dd: hh:mm Zzz [repeat]"
  107. result_type coordinate_time() const
  108. {
  109. using namespace posix_time;
  110. result_type result;
  111. bool flag = true;
  112. std::stringstream ss;
  113. ss.str("");
  114. // set the output format for local_date_time to only give
  115. // time_of_day & zone offset
  116. typedef boost::date_time::time_facet<local_date_time, char> ldt_facet;
  117. ldt_facet* timefacet = new ldt_facet("%H:%M (%q)");
  118. std::locale loc(std::locale::classic(), timefacet);
  119. ss.imbue(loc);
  120. // backup a full day and start iterating from there
  121. // I went overkill because I've got no decent
  122. // algorithm to set a starting point (yet)
  123. local_date_time tmp = l_time - gregorian::days(1);
  124. zone_map_type::const_iterator iter;
  125. for(int i = 0; i < 48; ++i) {
  126. iter = zones.begin();
  127. flag = true;
  128. tmp += posix_time::hours(1);
  129. while(iter != zones.end() && flag) {
  130. if(!workday.contains(tmp.local_time_in(iter->second).local_time())) {
  131. flag = false;
  132. }
  133. ++iter;
  134. }
  135. if(flag) {
  136. iter = zones.begin();
  137. ss << tmp.date() << ':';
  138. while(iter != zones.end()) {
  139. ss << ' ' << tmp.local_time_in(iter->second);
  140. ++iter;
  141. if(iter != zones.end()) {
  142. ss << ',';
  143. }
  144. }
  145. result.push_back(ss.str());
  146. ss.str("");
  147. }
  148. }
  149. if(result.empty()) {
  150. result.push_back("Scheduling within the time period given is not possible for these time zones.");
  151. }
  152. return result;
  153. }
  154. private:
  155. zone_map_type zones;
  156. local_date_time l_time;
  157. time_period workday;
  158. };
  159. ]]>
  160. </programlisting>
  161. </section>