Obtaining the Current Date and Time
Problem
You want to retrieve the current date and time from the user's computer, either as a local time or as a Coordinated Universal Time (UTC).
Solution
Call the time function from the header, passing a value of 0 as the parameter. The result will be a time_t value. You can use the gmtime function to convert the time_t value to a tm structure representing the current UTC time (a.k.a. Greenwich Mean Time or GMT); or, you can use the localtime function to convert the time_t value to a tm structure representing the local time. The program in Example 5-1 obtains the current date/time, and then converts it to local time and outputs it. Next, the program converts the current date/time to a UTC date/time and outputs that.
Example 5-1. Getting the local and UTC times
#include #include #include using namespace std; int main( ) { // Current date/time based on current system time_t now = time(0); // Convert now to tm struct for local timezone tm* localtm = localtime(&now); cout << "The local date and time is: " << asctime(localtm) << endl; // Convert now to tm struct for UTC tm* gmtm = gmtime(&now); if (gmtm != NULL) { cout << "The UTC date and time is: " << asctime(gmtm) << endl; } else { cerr << "Failed to get the UTC date and time" << endl; return EXIT_FAILURE; } }
Discussion
The time function returns a time_t type, which is an implementation-defined arithmetic type for representing a time period (a.k.a. a time interval) with at least a resolution of one second. The largest time interval that can be portably represented using a time_t is 2,147,483,648 seconds, or approximately 68 years.
A call to time(0) returns a time_t representing the time interval from an implementation defined base time (commonly 0:00:00 January 1, 1970) to the current moment.
A more workable representation of the current date and time is achieved by converting to a tm struct using the localtime or gmtime functions. A tm struct has the integer fields shown in Example 5-2.
Example 5-2. Layout of a tm struct
struct tm { int tm_sec; // seconds of minutes from 0 to 61 (60 and 61 are leap seconds) int tm_min; // minutes of hour from 0 to 59 int tm_hour; // hours of day from 0 to 24 int tm_mday; // day of month from 0 to 23 int tm_mon; // month of year from 0 to 11 int tm_year; // year since 1900 int tm_wday; // days since sunday int tm_yday; // days since January 1st int tm_isdst; // hours of daylight savings time }
When using the gmtime function, be sure to check its return value. If the computer running the code doesn't have a local time zone defined, the gmtime function will be unable to compute the UTC time, and will return 0. If you pass 0 to the asctime function, undefined behavior will result.
The localtime, gmtime, and asctime functions all return pointers to statically allocated objects. This is more efficient for the library, but it means that subsequent calls will change the value of those objects. The code in Example 5-3 shows how this can have surprising effects.
Example 5-3. Pitfalls of using asctime
void f( ) { char* x = asctime(localtime(time(0))); wait_for_15_seconds( ); // do some long processing task asctime(localtime(time(0))); cout << x << endl; // prints out the current time, not fifteen seconds ago . }