Time Formatting Parsing in C++

C++ supports time formatting and parsing, but it requires more manual work compared to some other languages. We’ll use the C++11 <chrono> and <iomanip> libraries for time manipulation and formatting.

#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>

int main() {
    auto p = [](const auto& x) { std::cout << x << std::endl; };

    // Get current time
    auto now = std::chrono::system_clock::now();
    auto time_t = std::chrono::system_clock::to_time_t(now);

    // Format time according to RFC3339
    std::stringstream ss;
    ss << std::put_time(std::gmtime(&time_t), "%FT%TZ");
    p(ss.str());

    // Time parsing
    std::tm tm = {};
    std::istringstream iss("2012-11-01T22:08:41+00:00");
    iss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S%z");
    p(std::put_time(&tm, "%c"));

    // Custom time formatting
    p(std::put_time(std::localtime(&time_t), "%I:%M%p"));
    p(std::put_time(std::localtime(&time_t), "%a %b %d %H:%M:%S %Y"));
    
    // For more precise formatting including microseconds, we need to use custom code
    auto micros = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count() % 1000000;
    std::stringstream precise_ss;
    precise_ss << std::put_time(std::localtime(&time_t), "%FT%T") << '.' << std::setfill('0') << std::setw(6) << micros << std::put_time(std::localtime(&time_t), "%z");
    p(precise_ss.str());

    // Parsing a custom format
    std::istringstream custom_iss("8 41 PM");
    custom_iss >> std::get_time(&tm, "%I %M %p");
    p(std::put_time(&tm, "%I:%M %p"));

    // For purely numeric representations, you can use strftime
    char buffer[80];
    std::strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S-00:00", std::localtime(&time_t));
    p(buffer);

    // Error handling for parsing
    std::istringstream error_iss("8:41PM");
    if (!(error_iss >> std::get_time(&tm, "%I:%M:%S %p"))) {
        p("Parsing failed");
    }
}

In C++, time formatting and parsing are more verbose compared to some other languages. The <chrono> library provides tools for time manipulation, while <iomanip> offers utilities for formatting.

The std::put_time function is used for formatting time, and std::get_time is used for parsing. These functions use format specifiers similar to the C strftime function.

For RFC3339 formatting and parsing, we need to manually construct the format string. C++ doesn’t provide built-in constants for standard time formats like RFC3339.

Error handling in time parsing is done by checking the state of the stream after the parsing operation. If the parsing fails, the stream will be in a failed state.

C++ doesn’t have a direct equivalent to Go’s example-based layouts. Instead, it uses format specifiers (like %F for ISO 8601 date, %T for time, etc.) which need to be explicitly specified.

For high-precision time formatting including microseconds, we need to manually extract the microseconds and format them separately.

Remember to compile this code with C++11 or later standard, for example:

$ g++ -std=c++11 time_formatting_parsing.cpp -o time_formatting_parsing
$ ./time_formatting_parsing

The output will vary based on the current time when you run the program.