Line data Source code
1 :
2 : #include "oksutils/oks/tz.hpp"
3 :
4 : #include "ers/ers.hpp"
5 : #include "logging/Logging.hpp"
6 :
7 : #include <boost/date_time/posix_time/posix_time_types.hpp>
8 : #include <boost/date_time/posix_time/time_formatters.hpp>
9 : #include <boost/date_time/posix_time/time_parsers.hpp>
10 :
11 : #include <iostream>
12 : #include <stdexcept>
13 : #include <string>
14 :
15 0 : oks::tz::DB::DB()
16 : {
17 0 : const char * tz_spec_file = ::getenv("BOOST_DATE_TIME_TZ_SPEC");
18 :
19 0 : if(!tz_spec_file || !*tz_spec_file)
20 : {
21 0 : throw std::runtime_error ("cannot read value of BOOST_DATE_TIME_TZ_SPEC environment variable");
22 : }
23 :
24 0 : TLOG_DEBUG(1) << "Boost time-zone specification file is \'" << tz_spec_file << '\'' ;
25 :
26 0 : try
27 : {
28 0 : m_tz_db.load_from_file(tz_spec_file);
29 : }
30 0 : catch(const std::exception& ex)
31 : {
32 0 : std::ostringstream text;
33 0 : text << "cannot read Boost time-zone specification file \"" << tz_spec_file << "\": " << ex.what();
34 0 : throw std::runtime_error (text.str().c_str());
35 0 : }
36 0 : }
37 :
38 : boost::local_time::time_zone_ptr
39 0 : oks::tz::DB::get_tz_ptr(const std::string& region)
40 : {
41 0 : boost::local_time::time_zone_ptr tz_ptr = m_tz_db.time_zone_from_region(region);
42 :
43 0 : if (!tz_ptr)
44 : {
45 0 : std::ostringstream text;
46 0 : text << "cannot find time-zone \'" << region << '\'';
47 0 : throw std::runtime_error(text.str().c_str());
48 0 : }
49 :
50 0 : return tz_ptr;
51 0 : }
52 :
53 : std::vector<std::string>
54 0 : oks::tz::DB::get_regions()
55 : {
56 0 : return m_tz_db.region_list();
57 : }
58 :
59 : boost::posix_time::ptime
60 0 : oks::tz::str_2_posix_time(const std::string& in, boost::local_time::time_zone_ptr tz_ptr, const char * value)
61 : {
62 0 : std::string s(in);
63 0 : std::replace(s.begin(), s.end(), 'T', ' ');
64 :
65 0 : boost::posix_time::ptime t;
66 :
67 : // convert string to time
68 0 : try
69 : {
70 0 : t = boost::posix_time::time_from_string(s);
71 : }
72 0 : catch (const std::exception& ex)
73 : {
74 0 : std::ostringstream text;
75 0 : text << "cannot parse " << value << " = \'" << in << "\': \"" << ex.what() << "\" (ISO 8601 format (YYYY-MM-DD HH:MM:SS) is expected).";
76 0 : throw std::runtime_error(text.str().c_str());
77 0 : }
78 :
79 :
80 : // convert local time to UTC, if the time zone was provided
81 0 : if (tz_ptr)
82 : {
83 0 : try
84 : {
85 0 : boost::local_time::local_date_time lt(t.date(), t.time_of_day(), tz_ptr, boost::local_time::local_date_time::EXCEPTION_ON_ERROR);
86 0 : TLOG_DEBUG(1) << "Build zone\'s time \'" << in << "\' => \'" << lt.to_string() << "\' using \'" << tz_ptr->to_posix_string() << '\'' ;
87 0 : t = lt.utc_time();
88 0 : }
89 0 : catch(std::exception& e)
90 : {
91 0 : std::ostringstream text;
92 0 : text << "cannot parse " << value << " = \'" << in << "\' in time zone \"" << tz_ptr->to_posix_string() << "\": \"" << e.what() << '\"' << std::endl;
93 0 : throw std::runtime_error(text.str().c_str());
94 0 : }
95 : }
96 :
97 0 : return t;
98 0 : }
99 :
100 : uint64_t
101 0 : oks::tz::posix_time_2_to_ns(boost::posix_time::ptime t)
102 : {
103 0 : static boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
104 0 : return ((t - epoch).total_nanoseconds());
105 : }
106 :
107 : std::string
108 0 : oks::tz::posix_time_2_iso_string(boost::posix_time::ptime t)
109 : {
110 0 : return boost::posix_time::to_iso_string(t);
111 : }
|