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