Formatting a Date/Time as a String
Formatting a Date Time as a String
Problem
You want to convert a date and/or time to a formatted string.
Solution
You can use the time_put template class from the header, as shown in Example 5-4.
Example 5-4. Formatting a datetime string
#include #include #include #include #include #include #include #include using namespace std; ostream& formatDateTime(ostream& out, const tm& t, const char* fmt) { const time_put& dateWriter = use_facet >(out.getloc( )); int n = strlen(fmt); if (dateWriter.put(out, out, ' ', &t, fmt, fmt + n).failed( )) { throw runtime_error("failure to format date time"); } return out; } string dateTimeToString(const tm& t, const char* format) { stringstream s; formatDateTime(s, t, format); return s.str( ); } tm now( ) { time_t now = time(0); return *localtime(&now); } int main( ) { try { string s = dateTimeToString(now( ), "%A %B, %d %Y %I:%M%p"); cout << s << endl; s = dateTimeToString(now( ), "%Y-%m-%d %H:%M:%S"); cout << s << endl; } catch(...) { cerr << "failed to format date time" << endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
Output of the program in Example 5-4 will resemble the following, depending on your local settings:
Sunday July, 24 2005 05:48PM 2005-07-24 17:48:11
Discussion
The time_put member function put uses a formatting string specifier like the C printf function format string. Characters are output to the buffer as they appear in the format string unless they are preceded by a % sign. A character preceded by a % sign is a format specifier and has the special meaning shown in Table 5-1. Format specifiers may also support modifiers, such as an integer to specify the field width, as in %4B.
Specifier |
Description |
---|---|
a |
Abbreviated weekday name (e.g., Mon) |
A |
Full weekday name (e.g., Monday) |
b |
Abbreviated month name (e.g., Dec) |
B |
Full month name (e.g., May) |
c |
Complete date and time |
d |
Day of the month (01-31) |
H |
Hour (00-23) |
I |
Hour (01-12) |
j |
Day of the year (001-366) |
m |
Month (01-12) |
M |
Minutes (00-59) |
p |
AM/PM designation |
S |
Second, including up to two leap seconds |
U |
Week number (00-53), with week 1 starting on the first Sunday |
w |
Weekday (0-6), where Sunday is 0 |
W |
Week number (00-53), with week 1 starting on the first Monday |
x |
Date in form MM/DD/YY |
X |
Time in form HH/MM/SS with 24-hour clock |
y |
Year within the current century (00-99) |
Y |
Year |
Z |
Time zone abbreviation, or empty if the system doesn't know the time zone |
The Boost date_time library discussed in later recipes does not have the formatting capabilities offered by time_put. For convenience Example 5-5 contains several routines to convert from the Boost date/time classes to a tm struct, so that you can use time_put routines.
Example 5-5. Converting from Boost date/time classes to a tm struct
using boost::gregorian; using boost::posix_time; void dateToTmAux(const date& src, tm& dest) { dest.tm_mday = src.day( ); dest.tm_year = src.year( ) - 1900; dest.tm_mon = src.month( ) - 1; } void ptimeToTmAux(const ptime& src, tm& dest) { dest.tm_sec = src.seconds( ); dest.tm_min = src.minutes( ); dest.tm_hour = src.hours( ); dateToTmAux(src.date( ), dest); } tm ptimeToTm(const ptime& t) { tm ret = tm( ); ptimeToTmAux(t, ret); return ret; }
See Also
Recipe 13.3