Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
timestamp-value.h
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 
16 #ifndef IMPALA_RUNTIME_TIMESTAMP_VALUE_H
17 #define IMPALA_RUNTIME_TIMESTAMP_VALUE_H
18 
19 #include <ctime>
20 #include <string>
21 
22 #include <boost/cstdint.hpp>
23 #include <boost/date_time/posix_time/posix_time.hpp>
24 #include <gflags/gflags.h>
25 
27 #include "udf/udf.h"
28 #include "util/hash-util.h"
29 
33 DECLARE_bool(use_local_tz_for_unix_timestamp_conversions);
34 
35 namespace impala {
36 
40 //
49 //
55 //
60 //
66  public:
68 
69  TimestampValue(const boost::gregorian::date& d,
70  const boost::posix_time::time_duration& t)
71  : time_(t),
72  date_(d) {}
73  TimestampValue(const boost::posix_time::ptime& t)
74  : time_(t.time_of_day()),
75  date_(t.date()) {}
77  TimestampValue(const char* str, int len);
78  TimestampValue(const char* str, int len, const DateTimeFormatContext& dt_ctx);
79 
83  template <typename Number>
84  explicit TimestampValue(Number unix_time) {
85  *this = UnixTimeToPtime(unix_time);
86  }
87 
88  TimestampValue(int64_t unix_time, int64_t nanos) {
89  boost::posix_time::ptime temp = UnixTimeToPtime(unix_time);
90  temp += boost::posix_time::nanoseconds(nanos);
91  *this = temp;
92  }
93 
94  explicit TimestampValue(double unix_time) {
95  const time_t unix_time_whole = unix_time;
96  boost::posix_time::ptime temp = UnixTimeToPtime(unix_time_whole);
97  temp += boost::posix_time::nanoseconds((unix_time - unix_time_whole) / ONE_BILLIONTH);
98  *this = temp;
99  }
100 
106  return TimestampValue(boost::posix_time::microsec_clock::local_time());
107  }
108 
112  DCHECK(!udf_value.is_null);
113  TimestampValue value;
114  memcpy(&value.date_, &udf_value.date, sizeof(value.date_));
115  memcpy(&value.time_, &udf_value.time_of_day, sizeof(value.time_));
116  return value;
117  }
118 
122  DCHECK(HasDateOrTime());
123  memcpy(&tv->date, &date_, sizeof(date_));
124  memcpy(&tv->time_of_day, &time_, sizeof(time_));
125  tv->is_null = false;
126  }
127 
128  void ToPtime(boost::posix_time::ptime* ptp) const {
129  *ptp = boost::posix_time::ptime(date_, time_);
130  }
131 
132  bool HasDate() const { return !date_.is_special(); }
133  bool HasTime() const { return !time_.is_special(); }
134  bool HasDateOrTime() const { return HasDate() || HasTime(); }
135  bool HasDateAndTime() const { return HasDate() && HasTime(); }
136 
137  std::string DebugString() const {
138  std::stringstream ss;
139  if (HasDate()) {
140  ss << boost::gregorian::to_iso_extended_string(date_);
141  }
142  if (HasTime()) {
143  if (HasDate()) ss << " ";
144  ss << boost::posix_time::to_simple_string(time_);
145  }
146  return ss.str();
147  }
148 
156  int Format(const DateTimeFormatContext& dt_ctx, int len, char* buff);
157 
164  time_t ToUnixTime() const {
165  DCHECK(HasDate());
166  const boost::posix_time::ptime temp(date_, time_);
167  tm temp_tm = boost::posix_time::to_tm(temp);
168  if (FLAGS_use_local_tz_for_unix_timestamp_conversions) {
169  return mktime(&temp_tm);
170  } else {
171  return timegm(&temp_tm);
172  }
173  }
174 
175  double ToSubsecondUnixTime() const {
176  double temp = ToUnixTime();
177  if (LIKELY(HasTime())) {
178  temp += time_.fractional_seconds() * ONE_BILLIONTH;
179  }
180  return temp;
181  }
182 
185  void UtcToLocal();
186 
187  void set_date(const boost::gregorian::date d) { date_ = d; }
188  void set_time(const boost::posix_time::time_duration t) { time_ = t; }
189  const boost::gregorian::date& date() const { return date_; }
190  const boost::posix_time::time_duration& time() const { return time_; }
191 
192  TimestampValue& operator=(const boost::posix_time::ptime& ptime) {
193  date_ = ptime.date();
194  time_ = ptime.time_of_day();
195  return *this;
196  }
197 
198  bool operator==(const TimestampValue& other) const {
199  return date_ == other.date_ && time_ == other.time_;
200  }
201 
202  bool operator!=(const TimestampValue& other) const { return !(*this == other); }
203 
204  bool operator<(const TimestampValue& other) const {
205  return date_ < other.date_ || (date_ == other.date_ && time_ < other.time_);
206  }
207 
208  bool operator<=(const TimestampValue& other) const {
209  return *this < other || *this == other; }
210 
211  bool operator>(const TimestampValue& other) const {
212  return date_ > other.date_ || (date_ == other.date_ && time_ > other.time_);
213  }
214 
215  bool operator>=(const TimestampValue& other) const {
216  return *this > other || *this == other;
217  }
218 
219  static size_t Size() {
220  return sizeof(boost::posix_time::time_duration) + sizeof(boost::gregorian::date);
221  }
222 
223  inline uint32_t Hash(int seed = 0) const {
224  uint32_t hash = HashUtil::Hash(&time_, sizeof(time_), seed);
225  return HashUtil::Hash(&date_, sizeof(date_), hash);
226  }
227 
228  static const char* LLVM_CLASS_NAME;
229 
230  private:
231  friend class UnusedClass;
232 
235  static const double ONE_BILLIONTH;
236 
241 
243  boost::posix_time::time_duration time_;
244 
246  boost::gregorian::date date_;
247 
252  boost::posix_time::ptime UnixTimeToPtime(time_t unix_time) const {
256  tm temp_tm;
257  if (FLAGS_use_local_tz_for_unix_timestamp_conversions) {
258  if (UNLIKELY(localtime_r(&unix_time, &temp_tm) == NULL)) {
259  return boost::posix_time::ptime(boost::posix_time::not_a_date_time);
260  }
261  } else {
262  if (UNLIKELY(gmtime_r(&unix_time, &temp_tm) == NULL)) {
263  return boost::posix_time::ptime(boost::posix_time::not_a_date_time);
264  }
265  }
266  try {
267  return boost::posix_time::ptime_from_tm(temp_tm);
268  } catch (std::exception& e) {
269  return boost::posix_time::ptime(boost::posix_time::not_a_date_time);
270  }
271  }
272 };
273 
275 inline std::size_t hash_value(const TimestampValue& v) {
276  return v.Hash();
277 }
278 
279 std::ostream& operator<<(std::ostream& os, const TimestampValue& timestamp_value);
280 }
281 
282 #endif
int Format(const DateTimeFormatContext &dt_ctx, int len, char *buff)
int64_t time_of_day
Nanoseconds in current day.
Definition: udf.h:499
TimestampValue(int64_t unix_time, int64_t nanos)
bool operator!=(const TimestampValue &other) const
boost::posix_time::ptime UnixTimeToPtime(time_t unix_time) const
TimestampValue(const boost::posix_time::ptime &t)
const StringSearch UrlParser::hash_search & hash
Definition: url-parser.cc:41
boost::gregorian::date date_
4 -bytes - stores the date as a day
bool HasDateOrTime() const
const boost::posix_time::time_duration & time() const
int32_t date
Gregorian date. This has the same binary format as boost::gregorian::date.
Definition: udf.h:497
This object has a compatible storage format with boost::ptime.
Definition: udf.h:495
std::size_t hash_value(const Decimal4Value &v)
This function must be called 'hash_value' to be picked up by boost.
TimestampValue(const boost::gregorian::date &d, const boost::posix_time::time_duration &t)
void ToTimestampVal(impala_udf::TimestampVal *tv) const
bool is_null
Definition: udf.h:359
void set_time(const boost::posix_time::time_duration t)
bool operator<(const TimestampValue &other) const
TimestampValue & operator=(const boost::posix_time::ptime &ptime)
static uint32_t Hash(const void *data, int32_t bytes, uint32_t seed)
Definition: hash-util.h:135
uint32_t Hash(int seed=0) const
bool operator==(const TimestampValue &other) const
void set_date(const boost::gregorian::date d)
bool operator>(const TimestampValue &other) const
static TimestampValue FromTimestampVal(const impala_udf::TimestampVal &udf_value)
static const char * LLVM_CLASS_NAME
TimestampValue(double unix_time)
static const double ONE_BILLIONTH
double ToSubsecondUnixTime() const
#define UNLIKELY(expr)
Definition: compiler-util.h:33
DECLARE_bool(use_local_tz_for_unix_timestamp_conversions)
TimestampValue(const TimestampValue &tv)
#define LIKELY(expr)
Definition: compiler-util.h:32
bool operator>=(const TimestampValue &other) const
void ToPtime(boost::posix_time::ptime *ptp) const
ostream & operator<<(ostream &os, const map< TNetworkAddress, llama::TAllocatedResource > &resources)
TimestampValue(Number unix_time)
const boost::gregorian::date & date() const
bool HasDateAndTime() const
boost::posix_time::time_duration time_
8 bytes - stores the nanoseconds within the current day
bool operator<=(const TimestampValue &other) const
time_t ToUnixTime() const
static TimestampValue LocalTime()
std::string DebugString() const