Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / C++
Tip/Trick

Fancy Time from std::chrono namespace

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
19 Aug 2019CPOL3 min read 9.6K   6   4
How to become a fancy guy who uses C++ time library instead of old and famous time.h

Introduction

I tried to be a fancy guy who uses modern C++ standard library features, but I failed. This tip is written for me and for you. You're welcome to ask for changes and I will provide the details you asked for if I think that you will have a proper relation to this tip. This wheel is re-invented to have a possibility to print date and time in logger class. The main design approach was to have no dependencies except STD C++.

Background

You may often need to measure a period of time and/or print a time stamp into logs. Before C++11, you have to wrap a C-code into C++ or use it directly. It works, but your code became a mess of conditional compiling statements (in the case of system portable code). And you, definitely need a portable C++ library which covers all your requirements. And you've got it.

Using the Code

Copy, paste and adopt the code below. It is free.

To make the code below compilable, you have to include the files below:

C++
#include <ctime>
#include <chrono>

At first, I'll give all my regards to Microsoft who make me write such annoying things like this, to make my core fully portable:

C++
#if defined(_MSC_VER) || defined(__BORLANDC__)
#include <winerror.h>
struct tm *localtime_r(const time_t *timep, struct tm *result)
{
    if (timep != NULL && result != NULL)
    {
        errno_t    err = localtime_s(result, timep);
        if (err != NOERROR)
        {
            return result;
        }
    }
    return NULL;
}
#endif

Let's begin with the time. You think you need this to print high resolution logs:

C++
std::chrono::time_point<std::chrono::steady_clock> 
     logClock = std::chrono::high_resolution_clock::now();

And you're wrong. The row below does not provide anything except itself. You cannot extract parts that you need except stupid constexpr (tested in G++/MSVC). Instead of that useless row, you need this:

C++
std::chrono::system_clock::duration
    zero = std::chrono::system_clock::now().time_since_epoch();

I didn't find a proper conversion from the fancy data types into human readable strings which contain date and time, so I have to call for undead C-style conversion. At first, we have to convert our fancy time into seconds:

C++
time_t ll = std::chrono::duration_cast<std::chrono::seconds>(zero).count();

At the second step, I use localtime_r() to split monolite into parts (the code below is not perfect, protect yourself from the invalid data and corruption):

C++
struct tm lt;
localtime_r(&ll, &lt);

Call strftime() to get the string representation:

C++
char buf[100];
std::strftime(buf, sizeof(buf), "%d/%m/%y %H:%M:%S", &lt);

or ctime( ) if you need just a string and don't care about the format.

And you may also need a fraction. As you might have seen, you've got them already. But you need a way to be sure that you extract them properly in a system independent way.

And you think - you can use a row like this:

C++
std::chrono::duration<std::chrono::milliseconds> mils = 
     std::chrono::duration_cast<std::chrono::milliseconds>(zero).count();

And you're wrong again. Because you don't get the logic, neither do I. All you need in this case is:

C++
long long mils = std::chrono::duration_cast<std::chrono::microseconds>(zero).count();

After that row, you will have a time in milliseconds. If you need milliseconds inside the second, just get them with % operator:

C++
mils %= 1000;

Now you are ready to be a fancy guy and you can create your own datetime class as it was in old and good times. :-)

Points of Interest

Before writing this tip, I tried to find a proper solution of this issue at one page, but I failed. So I tried to combine all that I found out in my place.

History

  • 12th August, 2019: First edition. I found a new tip and am full of positive emotions about it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) NetCracker
Russian Federation Russian Federation
I came to the industry at the end of that times when the computer program executes as it was written. I saw a quite big machines, occupied more than 100 square meters for its central processor, but I started my professional activity as a programmer on IBM PC clones. There were different CPU architectures (68k, PowerPC, 386/486, SPARC...) when I began, but Intel defeated them all with Pentium CPU (marketing) family.
I saw the knowledge and technology fragmentation. I saw many technologies started, developed and retired. However, I have not seen many things yet.
I have some experience, but my experience is not perfectly comprehensive. I still have many things to learn and I still cannot make a poker face when I find out some aspects about how the things were designed and works. My experience does not make me an absolute expert in some areas, because these areas are changing. I know some things, but I also understand that some things I know could be useless for nowadays.

Comments and Discussions

 
QuestionDon't reinvent the wheel Pin
joaopires13-Aug-19 4:00
joaopires13-Aug-19 4:00 
AnswerRe: Don't reinvent the wheel Pin
Alexey Shtykov18-Aug-19 23:00
professionalAlexey Shtykov18-Aug-19 23:00 
QuestionWhy so complex? Pin
Philipp Schaber13-Aug-19 1:42
Philipp Schaber13-Aug-19 1:42 
AnswerRe: Why so complex? Pin
Alexey Shtykov18-Aug-19 22:56
professionalAlexey Shtykov18-Aug-19 22:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.