mirror of
https://github.com/HowardHinnant/date.git
synced 2025-08-04 13:14:26 +02:00
Updated Examples and Recipes (markdown)
@@ -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.
|
||||||
|
Reference in New Issue
Block a user