Skip to content

Date and Time

[Most needed time and date methods] – [Measuring execution time] – [General infos] –

Most needed time and date methods

#include <chrono>
#include <iostream>
using namespace std::chrono;

void TestDateAndTime()
{
    std::cout << "Simply requesting (UTC) time:" << "\n";
    const auto utcTime = system_clock::now(); // std::chrono::time_point
    std::cout << "nowTime          : " << utcTime << "\n";

    std::cout << "\nUsing formaters, current time zone and local time:" << "\n";
    const auto time = current_zone()->to_local(utcTime); // std::chrono::time_point
    std::cout << "Time zone        : " << current_zone()->name() << "\n";
    std::cout << "Date             : " << std::format("{:%d.%m.%y}", time)
              << " or "                << std::format("{:%d.%m.%Y}", time) << "\n";
    std::cout << "Time             : " << std::format("{:%H:%M}", time)
              << " or "                << std::format("{:%X}", time) << "\n";
    std::cout << "TimeWithExactSec : " << std::format("{:%H:%M:%S}", time) << "\n";
    std::cout << "Calendar week    : " << std::format("{:%W}", time) << "\n";
    std::cout << "DayOfYear        : " << std::format("{:%j}", time) << "\n";
    std::cout << "Weekday          : " << std::format("{:%a}", time)
              << " or "                << std::format("{:%A}", time) << "\n";

    std::cout << "\nCalculations with time and date:" << "\n";
    const auto currentDate = year_month_day{ floor<days>(time) };
    const int thisYear = int(currentDate.year());
    const unsigned int thisMonth = static_cast<unsigned>(currentDate.month());
    // Calculate future time point
    const auto futureTimePointSomeDeltaLater = time + 20h + 10min + 5s;
    // Check for leap year
    const auto leapYearCheck{ year(currentDate.year())/2/29};
    const bool isLeapYear = leapYearCheck.ok(); // checks validity of leap day
    // Days since 1.1., days left until 31.12.
    const int dayOfYear = (floor<days>(utcTime)
        - sys_days(year(thisYear - 1) / 12 / 31)).count();
    const int daysLeftInYear = (sys_days(year(thisYear) / 12 / 31)
        - floor<days>(utcTime)).count();
    std::cout << "FutureTimePoint        : " << std::format("{:%d.%m.%Y %X}",
                                            futureTimePointSomeDeltaLater) << "\n";
    std::cout << "LeapYear               : " << thisYear << (isLeapYear 
                                            ? " is a leapYear" : " is no leapYear") << "\n";
    std::cout << "Last day of month      : " << year_month_day{ year(thisYear) 
                                            / month(thisMonth) / last } << "\n";
    std::cout << "Second Monday of month : " << year_month_day{ year(thisYear) 
                                            / month(thisMonth) / Monday[2]} << "\n";
    std::cout << "Last Friday of month   : " << year_month_day{ year(thisYear)
                                            / month(thisMonth) / Friday[last] } << "\n";
    std::cout << "DayOfYear              : " << dayOfYear << "\n";
    std::cout << "DaysLeftInYear         : " << daysLeftInYear << "\n";

    std::cout << "\nCalculations with Mozart:" << "\n";
    constexpr auto mozartBirthday{ day(27) / month(1) / year(1756) };
    constexpr auto mozartDeathday{ day(5) / month(12) / year(1791) };
    const auto daysLived = floor<days>(sys_days(mozartDeathday) - sys_days(mozartBirthday));
    const int daysLivedInt = daysLived.count(); // daysLived has type std::chrono::duration
    const int yearsLived = floor<years>(daysLived).count();
    const int yearsSinceBirth = floor<years>((sys_days(year_month_day{ floor<days>(time) })
                                      - sys_days(mozartBirthday))).count();
    std::cout << "Birthday          : " << mozartBirthday << "\n";
    std::cout << "Deathday          : " << mozartDeathday << "\n";
    std::cout << "Years lived       : " << yearsLived << "\n";
    std::cout << "Days lived        : " << daysLivedInt << "\n";
    std::cout << "Years since birth : " << yearsSinceBirth << "\n";
}

Output:

Simply requesting (UTC) time:
nowTime          : 2022-07-07 15:04:58.0997165

Using formaters, current time zone and local time:
Time zone        : Europe/Berlin
Date             : 07.07.22 or 07.07.2022
Time             : 17:04 or 17:04:58
TimeWithExactSec : 17:04:58.0997165
Calendar week    : 27
DayOfYear        : 188
Weekday          : Thu or Thursday

Calculations with time and date:
FutureTimePoint        : 08.07.2022 13:15:03
LeapYear               : 2022 is no leapYear
Last day of month      : 2022-07-31
Second Monday of month : 2022-07-11
Last Friday of month   : 2022-07-29
DayOfYear              : 188
DaysLeftInYear         : 177

Calculations with Mozart:
Birthday          : 1756-01-27
Deathday          : 1791-12-05
Years lived       : 35
Days lived        : 13096
Years since birth : 266

For format specifiers see: https://en.cppreference.com/w/cpp/chrono/system_clock/formatter#Format_specification

Measuring execution time

Method to watch the execution time of a given void function:

using milliseconds = std::chrono::duration<double, std::milli>;

milliseconds MeasureDuration(void(*func)())
{
    auto timeBefore{ std::chrono::system_clock::now() };
    // call given void function
    func();
    auto timeAfter{ std::chrono::system_clock::now() };
    return milliseconds{ timeAfter - timeBefore };
}

Dummy method which needs some time:

void DoSomething()
{
    std::this_thread::sleep_for(std::chrono::milliseconds(123));
}

Client code:

    auto neededMilliSec = MeasureDuration(DoSomething);
    std::cout << std::format("Needed execution time = {}", neededMilliSec);

Output:

Needed execution time = 133.112ms

General infos

std::chrono::system_clock:
for working with time and date, the wall clock time (see example above), it is not guaranteed to be monotonic (i.e. the time ticks may occure with some irregularity)

std::chrono::steady_clock:
provides more reliable monotonic ticks for timer events, cannot be used for calendar time

std::chrono::high_resolution_clock
not recommended for general purpose use, may be an alias for one of the above clocks

For more info about time and date see also http://www.gerald-fahrnholz.eu/sw/display_contents.php?file_name=c11.htm#headLine_26