@@ -50,15 +50,6 @@ using std::chrono::minutes;
5050using std::chrono::nanoseconds;
5151using std::chrono::seconds;
5252
53- StatusOr<absl::TimeZone> LoadTimeZone (absl::string_view name) {
54- absl::TimeZone tz;
55- if (!absl::LoadTimeZone (name, &tz)) {
56- return internal::InvalidArgumentError (
57- absl::StrFormat (" %s: Invalid time zone" , name), GCP_ERROR_INFO ());
58- }
59- return tz;
60- }
61-
6253// Round d to a microsecond boundary (to even in halfway cases).
6354microseconds Round (nanoseconds d) {
6455 auto trunc = duration_cast<microseconds>(d);
@@ -252,56 +243,6 @@ auto NameIs(char name) {
252243 return [name](ISO8601UnitFactory const & u) { return u.name == name; };
253244}
254245
255- StatusOr<Interval> ParseISO8601Interval (absl::string_view str) {
256- Interval intvl;
257- absl::string_view s = str;
258-
259- auto const * units = std::begin (kISO8601DateUnitFactories );
260- auto const * units_end = std::end (kISO8601DateUnitFactories );
261- enum { kValue , kUnit , kNothing } expecting = kValue ;
262- bool negated = false ;
263-
264- for (;;) {
265- if (units == std::begin (kISO8601DateUnitFactories )) {
266- negated = !absl::ConsumePrefix (&s, " +" ) && absl::ConsumePrefix (&s, " -" );
267- if (!absl::ConsumePrefix (&s, " P" )) break ;
268- }
269- if (units_end == std::end (kISO8601DateUnitFactories )) {
270- if (absl::ConsumePrefix (&s, " T" )) {
271- units = std::begin (kISO8601TimeUnitFactories );
272- units_end = std::end (kISO8601TimeUnitFactories );
273- expecting = kValue ;
274- }
275- }
276- if (units == units_end) break ;
277- double vf;
278- if (ParseDouble (s, vf, true , true )) {
279- expecting = kUnit ;
280- if (s.empty ()) break ;
281- units = std::find_if (units, units_end, NameIs (s.front ()));
282- if (units == units_end) break ;
283- intvl += units++->factory (1 ) * vf;
284- expecting = kNothing ;
285- s.remove_prefix (1 );
286- break ; // must be last unit
287- }
288- std::int32_t vn;
289- if (!ParseInteger (s, vn, true )) break ;
290- expecting = kUnit ;
291- if (s.empty ()) break ;
292- units = std::find_if (units, units_end, NameIs (s.front ()));
293- if (units == units_end) break ;
294- intvl += units++->factory (vn);
295- expecting = kNothing ;
296- s.remove_prefix (1 );
297- }
298-
299- if (!s.empty () || expecting != kNothing ) {
300- return SyntaxError (str, s, GCP_ERROR_INFO ());
301- }
302- return negated ? -intvl : intvl;
303- }
304-
305246/* *
306247 * https://www.postgresql.org/docs/current/datatype-datetime.html
307248 *
@@ -398,7 +339,59 @@ Interval PostgreSqlUnit(absl::string_view& s, std::int32_t n) {
398339 return Interval (0 , 0 , n); // default to days without removing unit
399340}
400341
401- StatusOr<Interval> ParsePostgreSqlInterval (absl::string_view str) {
342+ } // namespace
343+
344+ StatusOr<Interval> Interval::ParseISO8601Interval (absl::string_view str) {
345+ Interval intvl;
346+ absl::string_view s = str;
347+
348+ auto const * units = std::begin (kISO8601DateUnitFactories );
349+ auto const * units_end = std::end (kISO8601DateUnitFactories );
350+ enum { kValue , kUnit , kNothing } expecting = kValue ;
351+ bool negated = false ;
352+
353+ for (;;) {
354+ if (units == std::begin (kISO8601DateUnitFactories )) {
355+ negated = !absl::ConsumePrefix (&s, " +" ) && absl::ConsumePrefix (&s, " -" );
356+ if (!absl::ConsumePrefix (&s, " P" )) break ;
357+ }
358+ if (units_end == std::end (kISO8601DateUnitFactories )) {
359+ if (absl::ConsumePrefix (&s, " T" )) {
360+ units = std::begin (kISO8601TimeUnitFactories );
361+ units_end = std::end (kISO8601TimeUnitFactories );
362+ expecting = kValue ;
363+ }
364+ }
365+ if (units == units_end) break ;
366+ double vf;
367+ if (ParseDouble (s, vf, true , true )) {
368+ expecting = kUnit ;
369+ if (s.empty ()) break ;
370+ units = std::find_if (units, units_end, NameIs (s.front ()));
371+ if (units == units_end) break ;
372+ intvl += units++->factory (1 ) * vf;
373+ expecting = kNothing ;
374+ s.remove_prefix (1 );
375+ break ; // must be last unit
376+ }
377+ std::int32_t vn;
378+ if (!ParseInteger (s, vn, true )) break ;
379+ expecting = kUnit ;
380+ if (s.empty ()) break ;
381+ units = std::find_if (units, units_end, NameIs (s.front ()));
382+ if (units == units_end) break ;
383+ intvl += units++->factory (vn);
384+ expecting = kNothing ;
385+ s.remove_prefix (1 );
386+ }
387+
388+ if (!s.empty () || expecting != kNothing ) {
389+ return SyntaxError (str, s, GCP_ERROR_INFO ());
390+ }
391+ return negated ? -intvl : intvl;
392+ }
393+
394+ StatusOr<Interval> Interval::ParsePostgreSqlInterval (absl::string_view str) {
402395 Interval intvl;
403396 absl::string_view s = str;
404397
@@ -441,8 +434,6 @@ StatusOr<Interval> ParsePostgreSqlInterval(absl::string_view str) {
441434 return intvl;
442435}
443436
444- } // namespace
445-
446437bool operator ==(Interval const & a, Interval const & b) {
447438 return Cmp<std::equal_to>(a.months_ , a.days_ , a.offset_ , //
448439 b.months_ , b.days_ , b.offset_ );
@@ -491,10 +482,11 @@ Interval::operator std::string() const {
491482}
492483
493484StatusOr<Interval> MakeInterval (absl::string_view s) {
494- auto interval = ParseISO8601Interval (s);
485+ auto interval = Interval:: ParseISO8601Interval (s);
495486 if (interval.ok ()) return interval;
496487
497- auto pg_interval = ParsePostgreSqlInterval (absl::AsciiStrToLower (s));
488+ auto pg_interval =
489+ Interval::ParsePostgreSqlInterval (absl::AsciiStrToLower (s));
498490 if (pg_interval.ok ()) return pg_interval;
499491
500492 // We failed to parse the argument using either syntax. The most
@@ -532,34 +524,6 @@ Interval JustifyInterval(Interval intvl) {
532524 return JustifyDays (JustifyHours (intvl));
533525}
534526
535- StatusOr<Timestamp> Add (Timestamp const & ts, Interval const & intvl,
536- absl::string_view time_zone) {
537- auto tz = LoadTimeZone (time_zone);
538- if (!tz) return tz.status ();
539- auto ci = tz->At (*ts.get <absl::Time>());
540- auto cs = absl::CivilSecond ( // add the civil-time parts
541- ci.cs .year (), ci.cs .month () + intvl.months_ , ci.cs .day () + intvl.days_ ,
542- ci.cs .hour (), ci.cs .minute (), ci.cs .second ());
543- return *MakeTimestamp (internal::ToProtoTimestamp ( // overflow saturates
544- absl::FromCivil (cs, *tz) + ci.subsecond +
545- absl::FromChrono (intvl.offset_ )));
546- }
547-
548- StatusOr<Interval> Diff (Timestamp const & ts1, Timestamp const & ts2,
549- absl::string_view time_zone) {
550- auto tz = LoadTimeZone (time_zone);
551- if (!tz) return tz.status ();
552- auto ci1 = tz->At (*ts1.get <absl::Time>());
553- auto ci2 = tz->At (*ts2.get <absl::Time>());
554- auto days = absl::CivilDay (ci1.cs ) - absl::CivilDay (ci2.cs );
555- auto offset = absl::Hours (ci1.cs .hour () - ci2.cs .hour ()) +
556- absl::Minutes (ci1.cs .minute () - ci2.cs .minute ()) +
557- absl::Seconds (ci1.cs .second () - ci2.cs .second ()) +
558- (ci1.subsecond - ci2.subsecond );
559- return JustifyHours (Interval (0 , 0 , static_cast <std::int32_t >(days),
560- absl::ToChronoNanoseconds (offset)));
561- }
562-
563527GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
564528} // namespace spanner
565529} // namespace cloud
0 commit comments