Customizing Date and Time Formats with strftime(3)

The string format of the date and time can vary considerably with the preference of each user. The strftime(3) function makes it easier for the C programmer to implement custom date and time formats. Its synopsis is as follows:

#include <time.h>

size_t strftime(char *buf, size_t maxsize,
    const char *format, const struct tm *timeptr);

The arguments buf and maxsize specify the receiving buffer and its maximum size, respectively. The argument format specifies a printf(3)-like format string. The last argument, timeptr, points to a struct tm structure that will supply all of the input date and time values. The final output string size is returned, excluding the null byte.

If the output buffer is not large enough, the value maxsize is returned, indicating that maxsize characters were placed into the buffer. However, since there is no room for the null byte when this happens, do not expect one to be there.

The strftime(3) Format Specifiers

The format specifiers are quite different from the sprintf(3) variety. Table 11.2 lists the format specifiers that are supported. Notice that each specifier starts with the percent character (%) and is followed by a letter. All other text in the format string is copied verbatim, in the same way that sprintf(3) does. To include a percent character, use two successive percent characters.

Table 11.2. Format Specifiers for strftime(3)
Specifier Description
%a The abbreviated weekday name is substituted according to the locale.
%A The full weekday name is substituted according to the locale.
%b The abbreviated month name is substituted according to the locale.
%B The full month name is substituted according to the locale.
%c The preferred date and time representation for the current locale.
%d The day of the month in decimal.
%H The hour of the day in 24-hour form (00 to 23).
%I The hour in 12-hour form (01 to 12).
%j The day of the year as a decimal number (001 to 365).
%m The month as a decimal number (01 to 12).
%M The minute as a decimal number.
%p The string AM or PM according to the time.
%S The second as a decimal value.
%U The week number of the current year, expressed as a decimal number. The first Sunday is considered the first day of the first week.
%W The week number of the current year, expressed as a decimal number. The first Monday is considered the first day of the first week.
%w The day of the week as a decimal number (0 to 6).
%x The preferred date representation without time, for the current locale.
%X The preferred time representation without date, for the current locale.
%y The year without a century (00 to 99).
%Y The year with the century.
%Z The time zone or zone abbreviation.
%% A single percent character (%).

Implementing the DTime::strftime() Method

To enable you to try out the strftime(3) C function, it has been included in the class DTime as the method DTime::strftime(). This is shown in Listing 11.7.

Code Listing 11.7. strftime.cc—The Implementation of the DTime::strftime() Method
1:   // strftime.cc
2:
3:   #include "dtime.h"
4:
5:   ////////////////////////////////////////////////////////////
6:   // Call strftime(3) to format a string, based upon the
7:   // current struct tm members. This method assumes that the
8:   // struct tm members contain valid values.
9:   ////////////////////////////////////////////////////////////
10:
11:  char *
12:  DTime::strftime(const char *format) {
13:      size_t n = ::strftime(buf,sizeof buf-1,format,this);
14:      buf[n] = 0;             // Enforce a null byte
15:      return buf;             // Return formatted string
16:  }
17:
18:  ////////////////////////////////////////////////////////////
19:  // Output operator for the DTime object :
20:  ////////////////////////////////////////////////////////////
21:
22:  ostream &
23:  operator<<(ostream &ostr,DTime &obj) {
24:
25:      if ( obj.time() == (time_t)(-1) )
26:          ostr << "[No current time]";
27:      else
28:          ostr << obj.ctime();
29:      return ostr;
30:  }
31:
32:  // End strftime.cc

A C++ function operator<<() was implemented in Listing 11.7 to make it possible to display this DTime class using the overloaded C++ << operator. Line 25 checks to see if there is a current time for the object and, if so, the DTime::ctime() method is called to format a date/time string (line 28). This string is then sent to the output stream.

Testing Class DTime

Listing 11.8 shows a main program that will instantiate a DTime class and then invoke some operations on it.

Code Listing 11.8. main.cc—The main() Program for Demonstrating the DTime Class
1:   // main.cc
2:
3:   #include "dtime.h"
4:
5:   int
6:   main(int argc,char **argv) {
7:       DTime obj;
8:
9:       (void) argc;
10:      (void) argv;
11:
12:      // Set and display epoch time in the local time zone :
13:      obj.putTime(0);         // Establish epoch time
14:      cout << "Local UNIX Epoch time is '" << obj << "'

";
15:
16:      // Get and display the current time and date :
17:      obj.getTime();          // Get current date/time
18:      cout << "Current time is '" << obj << "'

";
19:
20:      // Compute a date 30 days from today :
21:      obj += 30 * 24 * 60 * 60;
22:      cout << "30 days from now is '" << obj << "'
";
23:
24:      // Get UTC values :
25:      obj.gmtime();           // Set struct tm values from time_t
26:      cout << "That date is " << obj.tm_mon + 1 << "/" << obj.tm_mday
27:          << "/" << obj.tm_year + 1900 << " "
28:          << obj.tm_hour << ":" << obj.tm_min << ":" << obj.tm_sec
29:          << " UTC

";
30:
31:      // Reset to local time, and set to 1st of the month :
32:      obj.getTime();          // Get current time
33:      obj.localtime();        // In local time components
34:      obj.tm_mday = 1;        // Set to 1st of the month
35:      obj.tm_hour = obj.tm_min = obj.tm_sec = 0;
36:      obj.mktime();           // Now set the time_t value
37:      cout << "The 1st is '" << obj << "'in this month
";
38:
39:      cout << "which is the same as "
40:          << obj.strftime("%A %B %d, %Y at %I:%M %p") << "
";
41:
42:      return 0;
43:  }

Compiling and running this program yields output similar to the following:

$ make
cc -c -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -Wall gettime.cc
cc -c -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -Wall ctime.cc
cc -c -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -Wall asctime.cc
cc -c -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -Wall localtime.cc
cc -c -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -Wall mktime.cc
cc -c -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -Wall strftime.cc
cc -c -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -Wall main.cc
cc -o dtime gettime.o ctime.o asctime.o localtime.o mktime.o strftime.o main.o -lstdc++
$ ./dtime
Local UNIX Epoch time is 'Wed Dec 31 19:00:00 1969'

Current time is 'Sun May  7 22:05:54 2000'

30 days from now is 'Tue Jun  6 22:05:54 2000'
That date is 6/7/2000 2:5:54 UTC

The 1st is 'Mon May  1 00:00:00 2000'in this month
which is the same as Monday May 01, 2000 at 12:00 AM
$

The first line of program output states your local time for UNIX Epoch Time. The example output was produced in the EST zone. Yours will differ if you are in a different time zone. This is accomplished in lines 13 and 14 of main.cc, shown in Listing 11.8. Line 13 sets the UNIX Epoch Time, which is the value (time_t)(0).

The next line of output beginning with Current time is is produced by lines 17 and 18. Line 17 sets the current date and time by calling obj.getTime().

Line 21 adds 30 days to the current time in obj using the overloaded += operator. Then the object is directed to cout in line 22 to display the date.

Line 25 establishes UTC values in the struct tm members that DTime inherits. Lines 26–29 access the structure members to send a manually formatted UTC time to cout.

Line 32 obtains the current time again for object obj. Lines 33–35 establish the first of the current month at midnight. Method DTime::mktime() is invoked at line 36, and then the object is sent to cout in line 37, displaying what the first of the current month is.

The last test in lines 39 and 40 tests the strftime(3) function by calling on the method DTime::strftime().

Understanding the Effects of Locale

Some of the format specifiers that strftime(3) supports format according to a locale. An example of this is the %A specifier (the full weekday name).

In the UNIX context, the locale represents the language and cultural rules that are used on a particular host system. It defines the language used for certain messages and the lexicographic conventions for date and time. Locale also establishes the character set that is to be used.

The locale setting will determine whether, for example, your system uses the English names for the days of the week or French names. The names of the months are also affected by locale. Lexicographical conventions such as the %X specifier dictate whether the time should be shown in 12- or 24-hour format, for example.

For more information about locale, view the man(1) page for mklocale(1) under FreeBSD.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.174.195