Back to C++
2026-02-106 min read

Format Time using struct tm (C++)

Learn Format Time using struct tm (C++) step by step with clear examples and exercises.

Why This Matters

Understanding how to work with dates and times is crucial in C++ programming as it enables you to create applications that require time-stamping, logging events, or even developing a calendar system. The struct tm is an essential built-in structure in the C++ Standard Library for representing date and time data. By learning how to use struct tm, you can build more robust and flexible programs.

Prerequisites

To follow this lesson, you should have a basic understanding of:

  1. C++ programming fundamentals (variables, functions, loops, control structures)
  2. Basic data types in C++ (int, char, float, etc.)
  3. I/O operations in C++ (std::cin, std::cout)
  4. Understanding of pointers in C++ (optional but helpful for understanding the struct tm structure)
  5. Familiarity with the concept of time_t and its relationship with struct tm
  6. Knowledge of date arithmetic, including leap years and daylight saving time

Core Concept

The struct tm is a predefined structure that holds date and time information. The structure consists of 6 members:

  1. tm_sec - seconds after the minute (0-59)
  2. tm_min - minutes after the hour (0-59)
  3. tm_hour - hours since midnight (0-23)
  4. tm_mday - day of the month (1-31)
  5. tm_mon - months since January (0-11)
  6. tm_year - years since 1900

Here's an example of how to use the struct tm structure:

#include <iostream>
#include <ctime>

int main() {
// Get current time
std::time_t now = std::time(nullptr);

// Convert current time to struct tm
std::tm *tm_now = std::localtime(&now);

// Print date and time
std::cout << "Current date and time: ";
std::cout << tm_now->tm_mday << "/"
<< tm_now->tm_mon + 1 << "/"
<< tm_now->tm_year + 1900 << " "
<< tm_now->tm_hour << ":"
<< tm_now->tm_min << ":"
<< tm_now->tm_sec << std::endl;

return 0;
}

In the above example, we first get the current time using std::time(). The function returns a std::time_t object representing the number of seconds since January 1st, 1970. We then convert this value to a struct tm using std::localtime(&now), which adjusts the date and time for the local timezone. Finally, we print the current date and time using the members of the struct tm.

Date Arithmetic with struct tm

You can perform arithmetic operations on the members of struct tm to manipulate dates and times. For example, you can add or subtract days, hours, minutes, or seconds from a given date and time:

std::tm new_time = *tm_now; // Copy current time to new_time
new_time.tm_hour += 2; // Add 2 hours

Time Differences with struct tm

To calculate the difference between two dates and times, you can subtract one struct tm from another:

std::tm time_diff = *tm1 - *tm2;

The resulting struct tm will contain the difference in days (tm_mday), hours (tm_hour), minutes (tm_min), and seconds (tm_sec).

Worked Example

Let's create a simple program that takes user input for date and time, stores it in a struct tm, and then prints the resulting date and time:

#include <iostream>
#include <ctime>

// Define custom function to set struct tm members from user input
void set_tm(std::tm &tm) {
std::cout << "Enter the date (dd/mm/yyyy): ";
std::cin >> tm.tm_mday;
std::cout << "Enter the month (1-12): ";
std::cin >> tm.tm_mon + 1; // Add 1 because months are numbered from 0 to 11
std::cout << "Enter the year (4 digits): ";
std::cin >> tm.tm_year;
tm.tm_year -= 1900; // Convert to years since 1900

std::cout << "Enter the hour (0-23): ";
std::cin >> tm.tm_hour;
std::cout << "Enter the minute (0-59): ";
std::cin >> tm.tm_min;
std::cout << "Enter the second (0-59): ";
std::cin >> tm.tm_sec;
}

int main() {
// Initialize an empty struct tm
std::tm user_input = {};

// Get user input for date and time
set_tm(user_input);

// Print the resulting date and time
std::cout << "You entered: ";
std::cout << user_input.tm_mday << "/"
<< user_input.tm_mon + 1 << "/"
<< user_input.tm_year + 1900 << " "
<< user_input.tm_hour << ":"
<< user_input.tm_min << ":"
<< user_input.tm_sec << std::endl;

return 0;
}

Common Mistakes

  1. Incorrectly setting the year: Remember to subtract 1900 from the input year when initializing the struct tm.
  2. Not adjusting for the local timezone: If you're working with dates and times that are not the current date and time, make sure to use gmtime() instead of localtime() to avoid incorrect results due to timezone differences.
  3. Forgetting to increment the month: The tm_mon member is numbered from 0 to 11, so don't forget to add 1 when getting user input for the month.
  4. Not handling invalid date or time inputs: Make sure your program can handle invalid inputs (e.g., negative days, months over 12, etc.) and provide appropriate error messages.
  5. Ignoring leap years: When performing arithmetic operations or calculations with dates, remember to account for leap years if necessary.
  6. Not considering daylight saving time: If your application needs to work with specific times, ensure it takes into account daylight saving time adjustments.

Subheadings under Common Mistakes:

  • Handling Leap Years
  • Accounting for Daylight Saving Time

Practice Questions

  1. Write a program that calculates the number of seconds elapsed since a given date and time (user input).
  2. Create a program that prints a calendar for a given month and year (user input).
  3. Modify the example above to handle leap years correctly.
  4. Write a function that converts a std::time_t value to a formatted string representing date and time in the format "YYYY-MM-DD HH:MM:SS".
  5. Create a program that calculates the number of days between two given dates (user input).
  6. Write a function that checks if a given year is a leap year.
  7. Modify the example above to handle daylight saving time adjustments.

FAQ

Q: Why is the year subtracted by 1900 when initializing the struct tm?

A: The tm_year member of the struct tm stores the number of years since 1900, not 1970 like std::time_t. So, we need to adjust the user input year accordingly.

Q: How can I handle invalid date or time inputs in my program?

A: You can validate user input by checking if the entered values are within valid ranges (e.g., days in a month, hours in a day, etc.). If an invalid input is detected, display an error message and ask the user to re-enter the data.

Q: What's the difference between std::time() and std::time_t?

A: std::time() is a function that returns the current time as a std::time_t object, which represents the number of seconds since January 1st, 1970. In other words, std::time_t is just a type used to store the time value returned by std::time().

Q: Why do we need to use gmtime() instead of localtime() when working with dates and times that are not the current date and time?

A: When using localtime(), the resulting struct tm is adjusted for the local timezone, which can lead to incorrect results if the provided date and time are not in the same timezone as your computer. On the other hand, gmtime() returns a struct tm representing Greenwich Mean Time (GMT), which does not account for local timezone differences. This makes it suitable for working with dates and times that are not the current date and time.

Q: How can I convert a struct tm to a std::time_t value?

A: You can convert a struct tm to a std::time_t value using the mktime() function:

std::time_t time_value = mktime(&tm);

Q: What's the best way to store dates and times in C++?

A: The most common ways to store dates and times in C++ are using std::chrono library, which provides high-resolution time measurements, or working with struct tm for simple date and time manipulation. If you need more advanced functionality, consider using third-party libraries such as Boost.DateTime or POCO C++ Libraries.

Format Time using struct tm (C++) | C++ | XQA Learn