18 #include <boost/assign/list_of.hpp>
19 #include <gtest/gtest.h>
28 using boost::assign::list_of;
29 using boost::date_time::Dec;
30 using boost::date_time::not_a_date_time;
31 using boost::gregorian::date;
32 using boost::posix_time::time_duration;
85 should_format(should_format),
86 expected_year(expected_year),
87 expected_month(expected_month),
88 expected_day(expected_day),
93 fmt_has_date_toks(fmt_has_date_toks),
94 fmt_has_time_toks(fmt_has_time_toks) {
132 return strcmp(lhs.
fmt, rhs.
fmt) < 0;
137 string& fmt_val,
int year,
int month,
int day,
int hours,
int mins,
int secs,
139 boost::gregorian::date not_a_date;
140 boost::gregorian::date cust_date = tv.
date();
141 boost::posix_time::time_duration cust_time = tv.
time();
142 EXPECT_NE(not_a_date, cust_date) << fmt_val;
143 EXPECT_NE(not_a_date_time, cust_time) << fmt_val;
144 EXPECT_EQ(year, cust_date.year()) << fmt_val;
145 EXPECT_EQ(month, cust_date.month()) << fmt_val;
146 EXPECT_EQ(day, cust_date.day()) << fmt_val;
147 EXPECT_EQ(hours, cust_time.hours()) << fmt_val;
148 EXPECT_EQ(mins, cust_time.minutes()) << fmt_val;
149 EXPECT_EQ(secs, cust_time.seconds()) << fmt_val;
150 EXPECT_EQ(frac, cust_time.fractional_seconds()) << fmt_val;
158 int day,
int hours,
int mins,
int secs,
int frac) {
159 const char* SEPARATORS =
" ~!@%^&*_+-:;|\\,./";
160 int toks_len = toks->size();
161 sort(toks->begin(), toks->end());
167 for (
int i = 0; i < toks_len; ++i) {
168 fmt.append((*toks)[i].fmt);
169 if ((*toks)[i].str != NULL) {
170 val.append(
string((*toks)[i].str));
172 val.append(lexical_cast<string>((*toks)[i].val));
175 string fmt_val =
"Format: " + fmt +
", Val: " + val;
179 ValidateTimestamp(tv, fmt, val, fmt_val, year, month, day, hours, mins, secs,
181 int buff_len = dt_ctx.fmt_out_len + 1;
183 int actual_len = tv.Format(dt_ctx, buff_len, buff);
184 EXPECT_GT(actual_len, 0) << fmt_val;
185 EXPECT_LE(actual_len, dt_ctx.fmt_len) << fmt_val;
186 string buff_str(buff);
187 EXPECT_EQ(buff_str, val) << fmt_val <<
" " << buff_str;
193 for (
const char* separator = SEPARATORS; *separator != 0;
195 for (
int i = 0; i < toks_len; ++i) {
196 fmt.append((*toks)[i].fmt);
197 if (i + 1 < toks_len) fmt.push_back(*separator);
198 if ((*toks)[i].str != NULL) {
199 val.append(
string((*toks)[i].str));
201 val.append(lexical_cast<string>((*toks)[i].val));
203 if (i + 1 < toks_len) val.push_back(*separator);
205 string fmt_val =
"Format: " + fmt +
", Val: " + val;
209 ValidateTimestamp(tv, fmt, val, fmt_val, year, month, day, hours, mins, secs,
211 int buff_len = dt_ctx.fmt_out_len + 1;
213 int actual_len = tv.Format(dt_ctx, buff_len, buff);
214 EXPECT_GT(actual_len, 0) << fmt_val;
215 EXPECT_LE(actual_len, dt_ctx.fmt_len) << fmt_val;
216 string buff_str(buff);
217 EXPECT_EQ(buff_str, val) << fmt_val <<
" " << buff_str;
222 }
while (next_permutation(toks->begin(), toks->end()));
226 char s1[] =
"2012-01-20 01:10:01";
227 char s2[] =
"1990-10-20 10:10:10.123456789 ";
228 char s3[] =
" 1990-10-20 10:10:10.123456789";
234 EXPECT_EQ(v1.
date().year(), 2012);
235 EXPECT_EQ(v1.
date().month(), 1);
236 EXPECT_EQ(v1.
date().day(), 20);
237 EXPECT_EQ(v1.
time().hours(), 1);
238 EXPECT_EQ(v1.
time().minutes(), 10);
239 EXPECT_EQ(v1.
time().seconds(), 1);
240 EXPECT_EQ(v1.
time().fractional_seconds(), 0);
241 EXPECT_EQ(v2.
time().fractional_seconds(), 123456789);
255 char s4[] =
"2012-01-20T01:10:01";
256 char s5[] =
"1990-10-20T10:10:10.123456789";
261 EXPECT_EQ(v4.
date().year(), 2012);
262 EXPECT_EQ(v4.
date().month(), 1);
263 EXPECT_EQ(v4.
date().day(), 20);
264 EXPECT_EQ(v4.
time().hours(), 1);
265 EXPECT_EQ(v4.
time().minutes(), 10);
266 EXPECT_EQ(v4.
time().seconds(), 1);
267 EXPECT_EQ(v4.
time().fractional_seconds(), 0);
268 EXPECT_EQ(v5.
date().year(), 1990);
269 EXPECT_EQ(v5.
date().month(), 10);
270 EXPECT_EQ(v5.
date().day(), 20);
271 EXPECT_EQ(v5.
time().hours(), 10);
272 EXPECT_EQ(v5.
time().minutes(), 10);
273 EXPECT_EQ(v5.
time().seconds(), 10);
274 EXPECT_EQ(v5.
time().fractional_seconds(), 123456789);
277 char d1[] =
"2012-01-20";
278 char d2[] =
"1990-10-20";
289 EXPECT_EQ(dv1.
date().year(), 2012);
290 EXPECT_EQ(dv1.
date().month(), 1);
291 EXPECT_EQ(dv1.
date().day(), 20);
293 char t1[] =
"10:11:12.123456789";
294 char t2[] =
"00:00:00";
301 EXPECT_EQ(tv1.
time().hours(), 10);
302 EXPECT_EQ(tv1.
time().minutes(), 11);
303 EXPECT_EQ(tv1.
time().seconds(), 12);
304 EXPECT_EQ(tv1.
time().fractional_seconds(), 123456789);
305 EXPECT_EQ(tv2.
time().fractional_seconds(), 0);
308 const char* FRACTION_MAX_STR =
"123456789";
309 const char* TEST_VALS[] = {
"2013-12-10 12:04:17.",
"2013-12-10T12:04:17.",
311 const int TEST_VAL_CNT =
sizeof(TEST_VALS) /
sizeof(
char*);
312 for (
int i = 0; i < TEST_VAL_CNT; ++i) {
313 const int VAL_LEN = strlen(TEST_VALS[i]);
314 int fraction_len = strlen(FRACTION_MAX_STR);
315 char frac_buff[VAL_LEN + fraction_len + 1];
316 while (fraction_len > 0) {
317 memcpy(frac_buff, TEST_VALS[i], VAL_LEN);
318 memcpy(frac_buff + VAL_LEN, FRACTION_MAX_STR, fraction_len);
319 *(frac_buff + VAL_LEN + fraction_len) =
'\0';
321 if (frac_buff[4] ==
'-') {
322 EXPECT_EQ(tv_frac.
date().year(), 2013);
323 EXPECT_EQ(tv_frac.
date().month(), 12);
324 EXPECT_EQ(tv_frac.
date().day(), 10);
326 EXPECT_EQ(tv_frac.
time().hours(), 12);
327 EXPECT_EQ(tv_frac.
time().minutes(), 4);
328 EXPECT_EQ(tv_frac.
time().seconds(), 17);
331 StringParser::StringToInt<int32_t>(FRACTION_MAX_STR, fraction_len, &status);
333 for (
int i = fraction_len; i < 9; ++i) fraction *= 10;
334 EXPECT_EQ(tv_frac.
time().fractional_seconds(), fraction);
340 char b1[] =
"1990-10 10:10:10.123456789";
342 boost::gregorian::date not_a_date;
344 EXPECT_EQ(bv1.
date(), not_a_date);
345 EXPECT_EQ(bv1.
time(), not_a_date_time);
347 char b2[] =
"1991-10-10 99:10:10.123456789";
350 EXPECT_EQ(bv2.
time(), not_a_date_time);
351 EXPECT_EQ(bv2.
date(), not_a_date);
353 char b3[] =
"1990-10- 10:10:10.123456789";
356 EXPECT_EQ(bv3.
date(), not_a_date);
357 EXPECT_EQ(bv3.
time(), not_a_date_time);
359 char b4[] =
"10:1010.123456789";
362 EXPECT_EQ(bv4.
date(), not_a_date);
363 EXPECT_EQ(bv4.
time(), not_a_date_time);
365 char b5[] =
"10:11:12.123456 1991-10-10";
368 EXPECT_EQ(bv5.
date(), not_a_date);
369 EXPECT_EQ(bv5.
time(), not_a_date_time);
371 char b6[] =
"2012-01-20 01:10:00.123.466";
374 EXPECT_EQ(bv6.
date(), not_a_date);
375 EXPECT_EQ(bv6.
time(), not_a_date_time);
377 char b7[] =
"2012-01-20 01:10:00.123 477 ";
380 EXPECT_EQ(bv7.
date(), not_a_date);
381 EXPECT_EQ(bv7.
time(), not_a_date_time);
387 const int YEAR = 2013;
388 const int MONTH = 10;
390 const int HOURS = 14;
393 const int FRAC = 123456789;
395 vector<TimestampToken> dt_toks = list_of
403 const char* months[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
404 "Sep",
"Oct",
"Nov",
"Dec"
407 const int MONTH_CNT = (
sizeof(months) /
sizeof(
char**));
408 for (
int i = 0; i < MONTH_CNT; ++i) {
410 vector<TimestampToken> dt_lm_toks = list_of
418 vector<TimestampTC> test_cases = boost::assign::list_of
420 (
TimestampTC(
"Myyd",
"4139",
true,
true,
false, 2013, 4, 9))
422 (
TimestampTC(
"yyyy-MMM-dd",
"2013-OCT-01",
false,
true,
false, 2013, 10, 1))
424 (
TimestampTC(
"yyyy-MMM-dd",
"2013-oct-01",
false,
true,
false, 2013, 10, 1))
426 (
TimestampTC(
"yyyy-MMM-dd",
"2013-oCt-01",
false,
true,
false, 2013, 10, 1))
428 (
TimestampTC(
"MMMyyyyyydd",
"Apr00201309",
true,
true,
false, 2013, 4, 9))
430 (
TimestampTC(
"yyyy MM dd ddMMMyyyy (HH:mm:ss.SSSS)",
431 "2013 05 12 16Apr1952 (16:53:21.1234)",
false,
true,
true, 1952, 4, 16, 16,
442 (
TimestampTC(
"yyyyyMMdd",
"120130101",
false,
true))
468 for (
int i = 0; i < test_cases.size(); ++i) {
473 EXPECT_FALSE(parse_result) <<
"TC: " << i;
476 ASSERT_TRUE(parse_result) <<
"TC: " << i;
479 boost::gregorian::date cust_date = cust_tv.
date();
480 boost::posix_time::time_duration cust_time = cust_tv.
time();
482 EXPECT_EQ(not_a_date, cust_date) <<
"TC: " << i;
483 EXPECT_EQ(cust_time, not_a_date_time) <<
"TC: " << i;
487 EXPECT_TRUE((!cust_date.is_special())
488 || (cust_time != not_a_date_time)) <<
"TC: " << i;
491 EXPECT_NE(cust_date, not_a_date) <<
"TC: " << i;
492 EXPECT_EQ(test_case.
expected_year, cust_date.year()) <<
"TC: " << i;
493 EXPECT_EQ(test_case.
expected_month, cust_date.month()) <<
"TC: " << i;
494 EXPECT_EQ(test_case.
expected_day, cust_date.day()) <<
"TC: " << i;
496 EXPECT_EQ(not_a_date, cust_date) <<
"TC: " << i;
501 EXPECT_NE(cust_time, not_a_date_time) <<
"TC: " << i;
502 EXPECT_EQ(test_case.
expected_hours, cust_time.hours()) <<
"TC: " << i;
510 int actual_len = cust_tv.
Format(dt_ctx, buff_len, buff);
511 EXPECT_GT(actual_len, 0) <<
"TC: " << i;
512 EXPECT_LE(actual_len, dt_ctx.
fmt_len) <<
"TC: " << i;
513 EXPECT_EQ(
string(test_case.
str, strlen(test_case.
str)),
string(buff, actual_len))
516 EXPECT_EQ(cust_time, not_a_date_time) << test_case.
fmt <<
" " << test_case.
str;
520 vector<TimestampFormatTC> fmt_test_cases = list_of
522 "2013-10-21 06:43:12.000000000"))
526 "1970-01-01T00:00:00.000000000Z"))
542 for (
int i = 0; i < fmt_test_cases.size(); ++i) {
547 EXPECT_NE(cust_tv.
date(), not_a_date) <<
"TC: " << i;
548 EXPECT_NE(cust_tv.
time(), not_a_date_time) <<
"TC: " << i;
552 int actual_len = cust_tv.
Format(dt_ctx, buff_len, buff);
553 EXPECT_GT(actual_len, 0) <<
"TC: " << i;
554 EXPECT_LE(actual_len, dt_ctx.
fmt_out_len) <<
"TC: " << i;
555 EXPECT_EQ(
string(buff, actual_len),
556 string(test_case.
str, strlen(test_case.
str))) <<
"TC: " << i;
560 EXPECT_TRUE(min_date.
HasDate());
561 EXPECT_TRUE(min_date.
HasTime());
562 EXPECT_EQ(-17987443200, min_date.
ToUnixTime());
565 EXPECT_FALSE(too_early.
HasDate());
566 EXPECT_FALSE(too_early.
HasTime());
572 EXPECT_TRUE(max_date.HasDate());
573 EXPECT_TRUE(max_date.HasTime());
574 EXPECT_EQ(253433923199, max_date.ToUnixTime());
577 EXPECT_FALSE(too_late.
HasDate());
578 EXPECT_FALSE(too_late.
HasTime());
585 EXPECT_EQ(1382337792.07,
586 TimestampValue(
"2013-10-21 06:43:12.07", 22).ToSubsecondUnixTime());
592 int main(
int argc,
char **argv) {
593 ::testing::InitGoogleTest(&argc, argv);
595 return RUN_ALL_TESTS();
int Format(const DateTimeFormatContext &dt_ctx, int len, char *buff)
static bool ParseFormatTokens(DateTimeFormatContext *dt_ctx)
void InitCommonRuntime(int argc, char **argv, bool init_jvm, TestInfo::Mode m=TestInfo::NON_TEST)
friend bool operator<(const TimestampToken &lhs, const TimestampToken &rhs)
const boost::posix_time::time_duration & time() const
int main(int argc, char **argv)
std::string DebugString(const T &val)
TimestampToken(const char *fmt, int val, const char *str)
void TestTimestampTokens(vector< TimestampToken > *toks, int year, int month, int day, int hours, int mins, int secs, int frac)
TimestampTC(const char *fmt, const char *str, bool fmt_should_fail=true, bool str_should_fail=true)
TimestampTC(const char *fmt, const char *str, bool should_format, bool fmt_has_date_toks, bool fmt_has_time_toks, int expected_year, int expected_month, int expected_day, int expected_hours=0, int expected_minutes=0, int expected_seconds=0, int expected_fraction=0)
TimestampToken(const char *fmt, int val)
const boost::gregorian::date & date() const
time_t ToUnixTime() const
static uint32_t GetHashValue(const void *v, const ColumnType &type, uint32_t seed=0)
void ValidateTimestamp(TimestampValue &tv, string &fmt, string &val, string &fmt_val, int year, int month, int day, int hours, int mins, int secs, int frac)