Updated Examples and Recipes (markdown)

Howard Hinnant
2017-04-17 13:16:09 -04:00
parent 6691fc2b9f
commit b2b63744ca

@@ -1612,6 +1612,74 @@ Once we have a string of form 2), give this sample code a try (thank you [Aaron]
cout << format("%F %T %Ez", zt) << ' ' << zt.get_time_zone()->name() << '\n'; cout << format("%F %T %Ez", zt) << ' ' << zt.get_time_zone()->name() << '\n';
} }
***
Update from [Howard](https://github.com/HowardHinnant):
There is now functionality to parse the original format:
1) 1999-10-31 01:30:00 US/Pacific PST
And check if the time zone abbreviation is consistent, and in the ambiguous case, use the time zone abbreviation to disambiguate the time stamp:
#include <iostream>
#include <sstream>
#include <string>
#include "tz.h"
int main()
{
using namespace std;
using namespace date;
istringstream inputStream{ "1999-10-31 00:30:00 US/Pacific PST" };
// Using local_seconds would resolve in ambiguous date exception
local_seconds tp;
string tz_name;
string tz_abbrev;
inputStream >> parse("%F %T", tp) >> tz_name >> tz_abbrev;
// bool operator tells us whether stream was successfully parsed
assert(bool(inputStream));
// Check for ambiguous and nonexistent timestamps
auto zone = locate_zone(tz_name);
auto info = zone->get_info(tp);
zoned_seconds zt{zone};
switch (info.result)
{
case local_info::unique:
zt = tp; // easy case
// One can check that the tz_abbrev is consistent with
// info.first.abbrev if desired.
break;
case local_info::nonexistent:
// time stamp never existed. Throw an error?
// Or here is how map to a unique UTC equivalent:
zt = make_zoned(zone, tp, choose::earliest); // choose::latest also
// gives same answer.
break;
case local_info::ambiguous:
// Use tz_abbrev to break the ambiguity
if (info.first.abbrev == tz_abbrev)
zt = make_zoned(zone, tp, choose::earliest);
else if (info.second.abbrev == tz_abbrev)
zt = make_zoned(zone, tp, choose::latest);
else
throw std::runtime_error(tz_abbrev +
" is not a valid abbreviation for " + tz_name);
break;
}
// This will output America/Los_Angeles, because US/Pacific is an alias of it.
cout << format("%F %T %Ez", zt) << ' ' << zt.get_time_zone()->name() << '\n';
}
This involves getting the `local_info` structure from the `time_zone` for that `local_time`. The `local_info` will have all of the information about that `time_zone/local_time` combination, including whether there is a unique mapping to UTC, a non-existing mapping (as in the gap created by "spring forward"), or an ambiguous mapping (created by a local time occurring twice during a "fall back").
In the ambiguous case you can view both mappings, including their abbreviations, and compare that to the abbreviation you parsed, and then choose either the earlier mapping, or the later mapping.
<a name="microfortnights"></a> <a name="microfortnights"></a>
### `microfortnights`?! Are you serious? ### `microfortnights`?! Are you serious?
(by [Howard Hinnant](https://github.com/HowardHinnant)) (by [Howard Hinnant](https://github.com/HowardHinnant))