Expand some query-related testcases
[xapian.git] / xapian-applications / omega / datetime.cc
blobd231841dbe81febd8eddca45710109dae26acf36
1 /** @file
2 * @brief Parse date/time strings
3 */
4 /* Copyright (c) 2013,2014,2015 Olly Betts
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
25 #include <config.h>
27 #include "datetime.h"
29 #include "timegm.h"
31 #include <cstdlib>
33 using namespace std;
35 time_t
36 parse_datetime(const string & s)
38 struct tm t;
39 const char * p = s.c_str();
40 char * q;
41 if (s.find('T') != string::npos || s.find('-') != string::npos) {
42 // E.g. "2013-01-17T09:10:55Z"
43 t.tm_year = strtoul(p, &q, 10) - 1900;
44 p = q;
45 if (*p == '-') {
46 t.tm_mon = strtoul(p + 1, &q, 10) - 1;
47 p = q;
48 } else {
49 t.tm_mon = 0;
51 if (*p == '-') {
52 t.tm_mday = strtoul(p + 1, &q, 10);
53 p = q;
54 } else {
55 t.tm_mday = 1;
57 if (*p == 'T') {
58 t.tm_hour = strtoul(p + 1, &q, 10);
59 p = q;
60 if (*p == ':') {
61 t.tm_min = strtoul(p + 1, &q, 10);
62 p = q;
63 } else {
64 t.tm_min = 0;
66 if (*p == ':') {
67 t.tm_sec = strtoul(p + 1, &q, 10);
68 p = q;
69 } else {
70 t.tm_sec = 0;
72 } else {
73 t.tm_hour = t.tm_min = t.tm_sec = 0;
75 if (*p == 'Z') {
76 // FIXME: always assume UTC for now...
78 } else {
79 // As produced by LibreOffice HTML export.
80 // E.g.
81 // "20130117;09105500" == 2013-01-17T09:10:55
82 // "20070903;200000000000" == 2007-09-03T00:02:00
83 // "20070831;5100000000000" == 2007-08-31T00:51:00
84 unsigned long v = strtoul(p, &q, 10);
85 if (v == 0) {
86 // LibreOffice sometimes exports "0;0". A date of "0" is
87 // clearly invalid.
88 return time_t(-1);
90 p = q;
91 t.tm_mday = v % 100;
92 v /= 100;
93 t.tm_mon = v % 100 - 1;
94 t.tm_year = v / 100 - 1900;
95 if (*p == ';') {
96 ++p;
97 v = strtoul(p, &q, 10);
98 v /= (q - p > 10) ? 1000000000 : 100;
99 t.tm_sec = v % 100;
100 v /= 100;
101 t.tm_min = v % 100;
102 t.tm_hour = v / 100;
103 } else {
104 t.tm_hour = t.tm_min = t.tm_sec = 0;
107 t.tm_isdst = -1;
109 return timegm(&t);