summaryrefslogtreecommitdiff
path: root/src/times.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/times.cc')
-rw-r--r--src/times.cc118
1 files changed, 13 insertions, 105 deletions
diff --git a/src/times.cc b/src/times.cc
index 8e4df020..74773755 100644
--- a/src/times.cc
+++ b/src/times.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2018, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2019, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -43,23 +43,11 @@ optional<datetime_t> epoch;
date_time::weekdays start_of_week = gregorian::Sunday;
-//#define USE_BOOST_FACETS 1
-#if defined(USE_BOOST_FACETS)
-#error "Boost facets are not quite working yet"
-#endif
-
namespace {
template <typename T, typename InputFacetType, typename OutputFacetType>
class temporal_io_t : public noncopyable
{
- string fmt_str;
-#if defined(USE_BOOST_FACETS)
- std::istringstream input_stream;
- std::ostringstream output_stream;
- InputFacetType * input_facet;
- OutputFacetType * output_facet;
- std::string temp_string;
-#endif // USE_BOOST_FACETS
+ string fmt_str;
public:
date_traits_t traits;
@@ -71,15 +59,6 @@ namespace {
icontains(fmt_str, "%m") || icontains(fmt_str, "%b"),
icontains(fmt_str, "%d")),
input(_input) {
-#if defined(USE_BOOST_FACETS)
- if (input) {
- input_facet = new InputFacetType(fmt_str);
- input_stream.imbue(std::locale(std::locale::classic(), input_facet));
- } else {
- output_facet = new OutputFacetType(fmt_str);
- output_stream.imbue(std::locale(std::locale::classic(), output_facet));
- }
-#endif // USE_BOOST_FACETS
}
void set_format(const char * fmt) {
@@ -88,29 +67,15 @@ namespace {
icontains(fmt_str, "%m") ||
icontains(fmt_str, "%b"),
icontains(fmt_str, "%d"));
-#if defined(USE_BOOST_FACETS)
- if (input)
- input_facet->format(fmt_str);
- else
- output_facet->format(fmt_str);
-#endif // USE_BOOST_FACETS
}
T parse(const char *) {}
std::string format(const T& when) {
-#if defined(USE_BOOST_FACETS)
- output_stream.str(temp_string);
- output_stream.seekp(std::ios_base::beg);
- output_stream.clear();
- output_stream << when;
- return output_stream.str();
-#else // USE_BOOST_FACETS
std::tm data(to_tm(when));
char buf[128];
std::strftime(buf, 127, fmt_str.c_str(), &data);
return buf;
-#endif // USE_BOOST_FACETS
}
};
@@ -119,34 +84,12 @@ namespace {
posix_time::time_facet>
::parse(const char * str)
{
-#if defined(USE_BOOST_FACETS)
- input_stream.seekg(std::ios_base::beg);
- input_stream.clear();
- input_stream.str(str);
-
- datetime_t when;
- input_stream >> when;
-#if DEBUG_ON
- if (when.is_not_a_date_time())
- DEBUG("times.parse", "Failed to parse date/time '" << str
- << "' using pattern '" << fmt_str << "'");
-#endif
-
- if (! when.is_not_a_date_time() &&
- input_stream.good() && ! input_stream.eof() &&
- input_stream.peek() != EOF) {
- DEBUG("times.parse", "This string has leftovers: '" << str << "'");
- return datetime_t();
- }
- return when;
-#else // USE_BOOST_FACETS
std::tm data;
std::memset(&data, 0, sizeof(std::tm));
if (strptime(str, fmt_str.c_str(), &data))
return posix_time::ptime_from_tm(data);
else
return datetime_t();
-#endif // USE_BOOST_FACETS
}
template <>
@@ -154,27 +97,6 @@ namespace {
gregorian::date_facet>
::parse(const char * str)
{
-#if defined(USE_BOOST_FACETS)
- input_stream.seekg(std::ios_base::beg);
- input_stream.clear();
- input_stream.str(str);
-
- date_t when;
- input_stream >> when;
-#if DEBUG_ON
- if (when.is_not_a_date())
- DEBUG("times.parse", "Failed to parse date '" << str
- << "' using pattern '" << fmt_str << "'");
-#endif
-
- if (! when.is_not_a_date() &&
- input_stream.good() && ! input_stream.eof() &&
- input_stream.peek() != EOF) {
- DEBUG("times.parse", "This string has leftovers: '" << str << "'");
- return date_t();
- }
- return when;
-#else // USE_BOOST_FACETS
std::tm data;
std::memset(&data, 0, sizeof(std::tm));
data.tm_year = CURRENT_DATE().year() - 1900;
@@ -183,7 +105,6 @@ namespace {
return gregorian::date_from_tm(data);
else
return date_t();
-#endif // USE_BOOST_FACETS
}
typedef temporal_io_t<datetime_t, posix_time::time_input_facet,
@@ -206,7 +127,9 @@ namespace {
date_t parse_date_mask_routine(const char * date_str, date_io_t& io,
date_traits_t * traits = NULL)
{
- VERIFY(std::strlen(date_str) < 127);
+ if (std::strlen(date_str) > 127) {
+ throw_(date_error, _f("Invalid date: %1%") % date_str);
+ }
char buf[128];
std::strcpy(buf, date_str);
@@ -420,7 +343,6 @@ class date_parser_t
TOK_DASH,
TOK_DOT,
- TOK_A_YEAR,
TOK_A_MONTH,
TOK_A_WDAY,
@@ -512,9 +434,6 @@ class date_parser_t
case TOK_SLASH: return "/";
case TOK_DASH: return "-";
case TOK_DOT: return ".";
- case TOK_A_YEAR:
- out << boost::get<date_specifier_t::year_type>(*value);
- break;
case TOK_A_MONTH:
out << date_specifier_t::month_type
(boost::get<date_time::months_of_year>(*value));
@@ -566,7 +485,6 @@ class date_parser_t
case TOK_SLASH: out << "TOK_SLASH"; break;
case TOK_DASH: out << "TOK_DASH"; break;
case TOK_DOT: out << "TOK_DOT"; break;
- case TOK_A_YEAR: out << "TOK_A_YEAR"; break;
case TOK_A_MONTH: out << "TOK_A_MONTH"; break;
case TOK_A_WDAY: out << "TOK_A_WDAY"; break;
case TOK_AGO: out << "TOK_AGO"; break;
@@ -727,7 +645,11 @@ void date_parser_t::determine_when(date_parser_t::lexer_t::token_t& tok,
when += gregorian::days(amount * adjust);
break;
default:
- specifier.day = date_specifier_t::day_type(amount);
+ if (amount > 31) {
+ specifier.year = date_specifier_t::year_type(amount);
+ } else {
+ specifier.day = date_specifier_t::day_type(amount);
+ }
break;
}
@@ -832,16 +754,13 @@ void date_parser_t::determine_when(date_parser_t::lexer_t::token_t& tok,
break;
}
- case lexer_t::token_t::TOK_A_YEAR:
- specifier.year = boost::get<date_specifier_t::year_type>(*tok.value);
- break;
case lexer_t::token_t::TOK_A_MONTH:
specifier.month =
date_specifier_t::month_type
(boost::get<date_time::months_of_year>(*tok.value));
tok = lexer.peek_token();
switch (tok.kind) {
- case lexer_t::token_t::TOK_A_YEAR:
+ case lexer_t::token_t::TOK_INT:
specifier.year = boost::get<date_specifier_t::year_type>(*tok.value);
break;
case lexer_t::token_t::END_REACHED:
@@ -898,12 +817,6 @@ date_interval_t date_parser_t::parse()
determine_when(tok, *inclusion_specifier);
break;
- case lexer_t::token_t::TOK_A_YEAR:
- if (! inclusion_specifier)
- inclusion_specifier = date_specifier_t();
- determine_when(tok, *inclusion_specifier);
- break;
-
case lexer_t::token_t::TOK_A_MONTH:
if (! inclusion_specifier)
inclusion_specifier = date_specifier_t();
@@ -1612,13 +1525,8 @@ date_parser_t::lexer_t::token_t date_parser_t::lexer_t::next_token()
if (! term.empty()) {
if (std::isdigit(term[0])) {
- if (term.length() == 4)
- return token_t(token_t::TOK_A_YEAR,
- token_t::content_t
- (lexical_cast<date_specifier_t::year_type>(term)));
- else
- return token_t(token_t::TOK_INT,
- token_t::content_t(lexical_cast<unsigned short>(term)));
+ return token_t(token_t::TOK_INT,
+ token_t::content_t(lexical_cast<unsigned short>(term)));
}
else if (std::isalpha(term[0])) {
to_lower(term);