Force time string

I have looked at many examples that seem to solve this simple case. The line I want disassembly:

"2012-06-01 16:45:34 EDT"

I tried to create local_time_input_facet with the following: "%Y-%m-%d %H:%M:%S %Z"

The zone pointer of the local_date_time object local_date_time always not set. Reading the documentation is confused:

% Z *! The full name of the time zone (output only). This flag is ignored when using time_facet with ptime.

"EDT" // Eastern Daylight Saving Time

Has anyone done this before?

UPDATE: I updated the code to better understand the problem:

 using namespace std; using namespace boost::local_time; int main() { stringstream ss; // Set up the input datetime format. local_time_input_facet *input_facet = new local_time_input_facet("%Y-%m-%d %H:%M:%S %ZP"); ss.imbue(std::locale(ss.getloc(), input_facet)); local_date_time ldt(not_a_date_time),ldt1(not_a_date_time); // Read a time into ldt ss.str("2012-06-01 17:45:34 EDT"); ss >> ldt; ss.str("2012-06-01 17:45:34 CDT"); ss >> ldt1; std::cerr << (ldt - ldt1).total_seconds() << std::endl; // Write the time to stdout. cout << "Full Time:\t" << ldt.to_string() << endl; cout << "Local time:\t" << ldt.local_time() << endl; cout << "Time zone:\t" << ldt.zone_as_posix_string() << endl; cout << "Zone abbrev:\t" << ldt.zone_abbrev() << endl; cout << "Zone offset:\t" << ldt.zone_abbrev(true) << endl; cout << "Full Time:\t" << ldt1.to_string() << endl; cout << "Local time:\t" << ldt1.local_time() << endl; cout << "Time zone:\t" << ldt1.zone_as_posix_string() << endl; cout << "Zone abbrev:\t" << ldt1.zone_abbrev() << endl; cout << "Zone offset:\t" << ldt1.zone_abbrev(true) << endl; return 0; } 

OUTPUT:

 0 Full Time: 2012-Jun-01 17:45:34 EDT Local time: 2012-Jun-01 17:45:34 Time zone: EDT+00 Zone abbrev: EDT Zone offset: +0000 Full Time: 2012-Jun-01 17:45:34 CDT Local time: 2012-Jun-01 17:45:34 Time zone: CDT+00 Zone abbrev: CDT Zone offset: +0000 
+7
source share
1 answer

Mistake

According to additional documentation: http://www.boost.org/doc/libs/1_57_0/doc/html/date_time/date_time_io.html#date_time.format_flags

%Z :

The full name of the time zone ( output only ).

He also says %ZP :

Posix time zone string (available for both input and output).

So you need to change %Z to %ZP . Now your timestamps will be analyzed. However, you will notice that the zone offset will not be set.

Posix Time Zone Rows

For a Posix timezone line, you need to specify at least the zone abbreviation and the offset from UTC, for example. EST-5 .

The full Posix time string is formatted as:

 "std offset dst [offset],start[/time],end[/time]" 

no spaces, according to http://www.boost.org/doc/libs/1_57_0/doc/html/date_time/local_time.html#date_time.local_time.posix_time_zone

Here are some examples of complete Posix time strings for EST and PST:

 EST-5EDT,M3.2.0,M11.1.0 PST-8PDT,M4.1.0,M10.1.0 

It contains information about when daylight saving time is in effect.

However, you can leave with EDT-4 in your case, depending on what you do with it.

It should be noted that as simple as Posix time zones, they are limited in that they do not take into account historical changes in time zone rules. I find it best to just avoid working with time zones.

What if I cannot control the input format?

As the OP notes in the comments, offsets are not indicated in its input timestamps. One solution is to read the zone abbreviation from the end of the input timestamp (for example, "EDT" ) and check it on the abbreviation map of known zones:

 std::map<std::string, std::string> zone_map; zone_map["EST"] = "EST-5EDT,M4.1.0,M10.5.0"; // Eastern Standard Time zone_map["EDT"] = zone_map["EST"]; // Eastern Daylight Time zone_map["PST"] = "PST-8PDT,M4.1.0,M10.1.0"; // Pacific Standard Time zone_map["PDT"] = zone_map["PST"]; // Pacific Daylight Time // ... 

(Note that the DST zones above should be the same as standard time zones.)

You may also be able to get away by simply preserving simple UTC offsets:

 zone_map["EST"] = "EST-5"; // Eastern Standard Time zone_map["EDT"] = "EDT-4"; // Eastern Daylight Time // ... 

Working example

Here is an example that uses the built-in time zone database:

 #include <map> #include <string> #include <sstream> #include <iostream> #include <boost/date_time/local_time/local_time.hpp> using namespace boost::local_time; int main() { // A little database of time zones. std::map<std::string, std::string> zone_map; zone_map["EST"] = "EST-5EDT,M4.1.0,M10.5.0"; // Eastern Standard Time zone_map["EDT"] = zone_map["EST"]; // Eastern Daylight Time zone_map["PST"] = "PST-8PDT,M4.1.0,M10.1.0"; // Pacific Standard Time zone_map["PDT"] = zone_map["PST"]; // Pacific Daylight Time // ... // This is our input timestamp. std::string timestamp = "2012-06-01 16:45:34 EDT"; // Replace time zone abbrev with full Posix time zone. const size_t abbrev_pos = timestamp.find_last_of(' ') + 1; const std::string abbrev = timestamp.substr(abbrev_pos); timestamp.replace(abbrev_pos, std::string::npos, zone_map[abbrev]); std::cout << "Time stamp with full timezone: " << timestamp << std::endl; // Set up the input datetime format. local_time_input_facet *input_facet = new local_time_input_facet("%Y-%m-%d %H:%M:%S %ZP"); std::stringstream ss; ss.imbue(std::locale(ss.getloc(), input_facet)); // This is our output date time. local_date_time ldt(not_a_date_time); // Read the timestamp into ldt. ss.str(timestamp); ss >> ldt; // Write the time to stdout. std::cout << "Full Time:\t" << ldt.to_string() << std::endl << "Local time:\t" << ldt.local_time() << std::endl << "Time zone:\t" << ldt.zone_as_posix_string() << std::endl << "Zone abbrev:\t" << ldt.zone_abbrev() << std::endl << "Zone offset:\t" << ldt.zone_abbrev(true) << std::endl; return 0; } 

It is output:

 Time stamp with full timezone: 2012-06-01 16:45:34 EST-5EDT,M4.1.0,M10.5.0 Full Time: 2012-Jun-01 16:45:34 EDT Local time: 2012-Jun-01 16:45:34 Time zone: EST-05EDT+01,M4.1.0/02:00,M10.5.0/02:00 Zone abbrev: EDT Zone offset: -0400 

Although the solution here may not be ideal, this is the only way to see it.

+6
source

All Articles