Updated Examples and Recipes (markdown)

Howard Hinnant
2017-04-17 13:33:52 -04:00
parent 8fd308e2d7
commit 988ec745b2

@@ -1614,31 +1614,33 @@ and then the solution is simple. To convert PST to -08:00 is in general non-triv
Once we have a string of form 2), give this sample code a try (thank you [Aaron](https://github.com/ahn6) who provided the draft): Once we have a string of form 2), give this sample code a try (thank you [Aaron](https://github.com/ahn6) who provided the draft):
#include <iostream> ```c++
#include <sstream> #include <iostream>
#include <string> #include <sstream>
#include "tz.h" #include <string>
#include "tz.h"
int main() int main()
{ {
using namespace std; using namespace std;
using namespace date; using namespace date;
istringstream inputStream{ "1999-10-31 01:30:00 -08:00 US/Pacific" }; istringstream inputStream{ "1999-10-31 01:30:00 -08:00 US/Pacific" };
// Using local_seconds would resolve in ambiguous date exception
sys_seconds tp;
string tz_name;
inputStream >> parse("%F %T %Ez %Z", tp, tz_name);
// bool operator tells us whether stream was successfully parsed // Using local_seconds would resolve in ambiguous date exception
assert(bool(inputStream)); sys_seconds tp;
string tz_name;
inputStream >> parse("%F %T %Ez %Z", tp, tz_name);
auto zt = make_zoned(tz_name, tp); // bool operator tells us whether stream was successfully parsed
assert(bool(inputStream));
// This will output America/Los_Angeles, because US/Pacific is an alias of it. auto zt = make_zoned(tz_name, tp);
cout << format("%F %T %Ez", zt) << ' ' << zt.get_time_zone()->name() << '\n';
} // 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';
}
```
*** ***
@@ -1650,60 +1652,62 @@ There is now functionality to parse the original format:
And check if the time zone abbreviation is consistent, and in the ambiguous case, use the time zone abbreviation to disambiguate the time stamp: 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> ```c++
#include <sstream> #include <iostream>
#include <string> #include <sstream>
#include "tz.h" #include <string>
#include "tz.h"
int main() 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)
{ {
using namespace std; case local_info::unique:
using namespace date; zt = tp; // easy case
// One can check that the tz_abbrev is consistent with
istringstream inputStream{ "1999-10-31 00:30:00 US/Pacific PST" }; // info.first.abbrev if desired.
break;
// Using local_seconds would resolve in ambiguous date exception case local_info::nonexistent:
local_seconds tp; // time stamp never existed. Throw an error?
string tz_name; // Or here is how map to a unique UTC equivalent:
string tz_abbrev; zt = make_zoned(zone, tp, choose::earliest); // choose::latest also
inputStream >> parse("%F %T", tp) >> tz_name >> tz_abbrev; // gives same answer.
break;
// bool operator tells us whether stream was successfully parsed case local_info::ambiguous:
assert(bool(inputStream)); // Use tz_abbrev to break the ambiguity
if (info.first.abbrev == tz_abbrev)
// Check for ambiguous and nonexistent timestamps zt = make_zoned(zone, tp, choose::earliest);
auto zone = locate_zone(tz_name); else if (info.second.abbrev == tz_abbrev)
auto info = zone->get_info(tp); zt = make_zoned(zone, tp, choose::latest);
zoned_seconds zt{zone}; else
switch (info.result) throw std::runtime_error(tz_abbrev +
{ " is not a valid abbreviation for " + tz_name);
case local_info::unique: break;
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 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"). 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. 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.