ome-xml  5.2.0
Timestamp.h
1 /*
2  * #%L
3  * OME-XML C++ library for working with OME-XML metadata structures.
4  * %%
5  * Copyright © 2006 - 2016 Open Microscopy Environment:
6  * - Massachusetts Institute of Technology
7  * - National Institutes of Health
8  * - University of Dundee
9  * - Board of Regents of the University of Wisconsin-Madison
10  * - Glencoe Software, Inc.
11  * %%
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  * this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright notice,
18  * this list of conditions and the following disclaimer in the documentation
19  * and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * The views and conclusions contained in the software and documentation are
34  * those of the authors and should not be interpreted as representing official
35  * policies, either expressed or implied, of any organization.
36  * #L%
37  */
38 
39 #ifndef OME_XML_MODEL_PRIMITIVES_TIMESTAMP_H
40 #define OME_XML_MODEL_PRIMITIVES_TIMESTAMP_H
41 
42 #include <string>
43 #include <sstream>
44 #include <stdexcept>
45 
46 #include <boost/date_time/posix_time/posix_time.hpp>
47 
48 #include <ome/compat/cstdint.h>
49 
50 namespace ome
51 {
52  namespace xml
53  {
54  namespace model
55  {
56  namespace primitives
57  {
58 
66  class Timestamp {
67  public:
69  typedef boost::posix_time::ptime value_type;
70 
74  Timestamp();
75 
81  Timestamp(const std::string& value);
82 
88  Timestamp(value_type value);
89 
95  inline
96  operator value_type () const
97  {
98  return this->value;
99  }
100 
101  private:
103  value_type value;
104  };
105 
113  template<class charT, class traits>
114  inline std::basic_ostream<charT,traits>&
115  operator<< (std::basic_ostream<charT,traits>& os,
116  const Timestamp& timestamp)
117  {
118  return os << boost::posix_time::to_iso_extended_string(static_cast<Timestamp::value_type>(timestamp))
119  << 'Z';
120  }
121 
129  template<class charT, class traits>
130  inline std::basic_istream<charT,traits>&
131  operator>> (std::basic_istream<charT,traits>& is,
132  Timestamp& timestamp)
133  {
134  std::istream::sentry s(is);
135  if (s)
136  {
138 
139  // Save locale.
140  std::locale savedlocale = is.getloc();
141 
142  try
143  {
144  boost::posix_time::time_input_facet *input_facet =
145  new boost::posix_time::time_input_facet();
146  input_facet->set_iso_extended_format();
147  std::locale iso8601_loc(std::locale::classic(), input_facet);
148 
149  is.imbue(iso8601_loc);
150  is >> value;
151 
152  if (is)
153  {
154  // Check for zone offset
155  std::char_traits<char>::int_type tztype = is.peek();
156  if(tztype != std::char_traits<char>::eof())
157  {
158  if (tztype == 'Z')
159  {
160  is.ignore(); // Drop above from istream
161  // If Z, we're already using UTC, so don't apply numeric offsets
162  }
163  else if (tztype == '-' || tztype == '+')
164  {
165  is.ignore(); // Drop above from istream
166  if (is.rdbuf()->in_avail() >= 4) // Need 4 numeric chars
167  {
168  // Check that the next 4 characters are only numeric
169  std::string inchars(4, ' ');
170  is.read(&inchars[0], 4);
171  for (std::string::const_iterator i = inchars.begin();
172  i != inchars.end();
173  ++i)
174  if (*i < '0' || *i > '9')
175  is.setstate(std::ios::failbit);
176 
177  if (is)
178  {
179  // Get offset value
180  int offset;
181  std::istringstream valueis(inchars);
182  valueis >> offset;
183  if (valueis)
184  {
185  if (tztype == '+')
186  offset = -offset;
187  // Offset in hours, minutes, seconds
188  boost::posix_time::time_duration d(offset/100, offset%100, 0);
189  // Apply offset
190  value += d;
191  }
192  else
193  is.setstate(std::ios::failbit);
194  }
195  }
196  else
197  {
198  is.setstate(std::ios::failbit);
199  }
200  }
201  }
202  }
203 
204  if (is)
205  timestamp = Timestamp(value);
206  else
207  throw std::runtime_error("Failed to parse timestamp");
208  }
209  catch (const std::exception& e)
210  {
211  is.imbue(savedlocale);
212  throw;
213  }
214 
215  is.imbue(savedlocale);
216  }
217  return is;
218  }
219 
220  }
221  }
222  }
223 }
224 
225 #endif // OME_XML_MODEL_PRIMITIVES_TIMESTAMP_H
226 
227 /*
228  * Local Variables:
229  * mode:C++
230  * End:
231  */
An ISO-8601 timestamp.
Definition: Timestamp.h:66
value_type value
The POSIX time (at least microsecond precision).
Definition: Timestamp.h:103
Timestamp()
Construct a Timestamp (defaults to current UTC time).
Definition: Timestamp.cpp:50
Open Microscopy Environment C++ implementation.
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &is, Color &color)
Set Color from input stream.
Definition: Color.h:472
boost::posix_time::ptime value_type
POSIX time is the underlying time representation.
Definition: Timestamp.h:69