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.

Table 5-1. Date/time format specifiers

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

Категории