bioformats  5.1.0
Timestamp.h
1 /*
2  * #%L
3  * OME-XML C++ library for working with OME-XML metadata structures.
4  * %%
5  * Copyright © 2006 - 2015 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  Timestamp::value_type value;
135 
136  // Save locale.
137  std::locale savedlocale = is.getloc();
138 
139  try
140  {
141  boost::posix_time::time_input_facet *input_facet =
142  new boost::posix_time::time_input_facet();
143  input_facet->set_iso_extended_format();
144  std::locale iso8601_loc(std::locale::classic(), input_facet);
145 
146  is.imbue(iso8601_loc);
147  is >> value;
148 
149  if (is)
150  {
151  // Check for zone offset
152  std::char_traits<char>::int_type tztype = is.peek();
153  if(tztype != std::char_traits<char>::eof())
154  {
155  if (tztype == 'Z')
156  {
157  is.ignore(); // Drop above from istream
158  // If Z, we're already using UTC, so don't apply numeric offsets
159  }
160  else if (tztype == '-' || tztype == '+')
161  {
162  is.ignore(); // Drop above from istream
163  if (is.rdbuf()->in_avail() >= 4) // Need 4 numeric chars
164  {
165  // Check that the next 4 characters are only numeric
166  char inchars[4];
167  is.read(&inchars[0], 4);
168  for (int i=0; i < 4; ++i)
169  if (inchars[i] < '0' || inchars[i] > '9')
170  is.setstate(std::ios::failbit);
171 
172  if (is)
173  {
174  // Get offset value
175  int offset;
176  std::istringstream valueis(inchars);
177  valueis >> offset;
178  if (valueis)
179  {
180  if (tztype == '+')
181  offset = -offset;
182  // Offset in hours, minutes, seconds
183  boost::posix_time::time_duration d(offset/100, offset%100, 0);
184  // Apply offset
185  value += d;
186  }
187  else
188  is.setstate(std::ios::failbit);
189  }
190  }
191  else
192  {
193  is.setstate(std::ios::failbit);
194  }
195  }
196  }
197  }
198 
199  if (is)
200  timestamp = Timestamp(value);
201  else
202  throw std::runtime_error("Failed to parse timestamp");
203  }
204  catch (const std::exception& e)
205  {
206  is.imbue(savedlocale);
207  throw;
208  }
209 
210  is.imbue(savedlocale);
211  return is;
212  }
213 
214  }
215  }
216  }
217 }
218 
219 #endif // OME_XML_MODEL_PRIMITIVES_TIMESTAMP_H
220 
221 /*
222  * Local Variables:
223  * mode:C++
224  * End:
225  */
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.
Definition: CoreMetadata.cpp:40
Standard integer types.
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
Xerces-C modern C++ wrapper.
Definition: Base.h:53