105

How do I get a uint unix timestamp in C++? I've googled a bit and it seems that most methods are looking for more convoluted ways to represent time. Can't I just get it as a uint?

2rs2ts
  • 10,662
  • 10
  • 51
  • 95

8 Answers8

141

C++20 introduced a guarantee that time_since_epoch is relative to the UNIX epoch, and cppreference.com gives an example that I've distilled to the relevant code, and changed to units of seconds rather than hours:

#include <iostream>
#include <chrono>
 
int main()
{
    const auto p1 = std::chrono::system_clock::now();
 
    std::cout << "seconds since epoch: "
              << std::chrono::duration_cast<std::chrono::seconds>(
                   p1.time_since_epoch()).count() << '\n';
}

Using C++17 or earlier, time() is the simplest function - seconds since Epoch, which for Linux and UNIX at least would be the UNIX epoch. Linux manpage here.

The cppreference page linked above gives this example:

#include <ctime>
#include <iostream>
 
int main()
{
    std::time_t result = std::time(nullptr);
    std::cout << std::asctime(std::localtime(&result))
              << result << " seconds since the Epoch\n";
}
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
54
#include <iostream>
#include <ctime>

int main()
{
    std::time_t t = std::time(0);  // t is an integer type
    std::cout << t << " seconds since 01-Jan-1970\n";
    return 0;
}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
wilhelmtell
  • 57,473
  • 20
  • 96
  • 131
  • 4
    This assumes that `std::time()` gives you seconds since 1970. That's true on a lot of systems (POSIX and Windows, I believe), but it's not guaranteed by the language standard. – Keith Thompson Jun 24 '16 at 02:44
19

The most common advice is wrong, you can't just rely on time(). That's used for relative timing: ISO C++ doesn't specify that 1970-01-01T00:00Z is time_t(0)

What's worse is that you can't easily figure it out, either. Sure, you can find the calendar date of time_t(0) with gmtime, but what are you going to do if that's 2000-01-01T00:00Z ? How many seconds were there between 1970-01-01T00:00Z and 2000-01-01T00:00Z? It's certainly no multiple of 60, due to leap seconds.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • 1
    "How do I get a uint unix timestamp in C++?" - given - as you've said - you can call `gmtime()` later to get a readable representation of whatever that timestamp encodes, what functionality requested in the question isn't satisfied by `time()`, regardless of the reference date or suitability for interval calculations? – Tony Delroy Aug 23 '12 at 06:58
  • 3
    To get a **UNIX** timestamp on a non-UNIX system, you have to know the difference (in seconds) between the local epoch and `1970-01-01T00:00Z`. There's just no method which does that. – MSalters Aug 23 '12 at 07:48
  • For some reason I got the impression the question was for code on a UNIX (or Linux etc) machine, but now I see where you're coming from. Curious: have you found any actual system where time_t(0) wasn't 1970-01-01T00:00Z? Would be but a couple minutes work to work out an offset on any given system (take the non-UNIX time_t(0) and get a time_t for it on a UNIX system), but thanks for explaining your concern. – Tony Delroy Aug 23 '12 at 23:35
  • 7
    For VS its UNIX time; MSDN states: The time function returns the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Coordinated Universal Time (UTC), according to the system clock. http://msdn.microsoft.com/en-us/library/1f4c8f33.aspx – Oliver Zendel Mar 08 '14 at 08:15
  • 2
    @TonyD: IBM systems apparently are an exception. Not really a surprise since they were in the computer business well before 1-1-1970. – MSalters May 08 '15 at 12:02
13

As this is the first result on google and there's no C++20 answer yet, here's how to use std::chrono to do this:

#include <chrono>

//...

using namespace std::chrono;
int64_t timestamp = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();

In versions of C++ before 20, system_clock's epoch being Unix epoch is a de-facto convention, but it's not standardized. If you're not on C++20, use at your own risk.

Brent
  • 4,153
  • 4
  • 30
  • 63
Tharwen
  • 3,057
  • 2
  • 24
  • 36
9

I created a global define with more information:

#include <iostream>
#include <ctime>
#include <iomanip>
    
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)    // only show filename and not it's path (less clutter)
#define INFO std::cout << std::put_time(std::localtime(&time_now), "%y-%m-%d %OH:%OM:%OS") << " [INFO] " << __FILENAME__ << "(" << __FUNCTION__ << ":" << __LINE__ << ") >> "
#define ERROR std::cout << std::put_time(std::localtime(&time_now), "%y-%m-%d %OH:%OM:%OS") << " [ERROR] " << __FILENAME__ << "(" << __FUNCTION__ << ":" << __LINE__ << ") >> "
    
static std::time_t time_now = std::time(nullptr);

Use it like this:

INFO << "Hello world" << std::endl;
ERROR << "Goodbye world" << std::endl;

Sample output:

16-06-23 21:33:19 [INFO] main.cpp(main:6) >> Hello world
16-06-23 21:33:19 [ERROR] main.cpp(main:7) >> Goodbye world

Put these lines in your header file. I find this very useful for debugging, etc.

xinthose
  • 3,213
  • 3
  • 40
  • 59
9
#include <iostream>
#include <sys/time.h>

using namespace std;

int main ()
{
  unsigned long int sec= time(NULL);
  cout<<sec<<endl;
}
anijhaw
  • 8,954
  • 7
  • 35
  • 36
  • `time()` returns a result of type `time_t`, which can in principle be either signed, unsigned, or even floating-point. Why store the result in a `long int`? And why use `` rather than the standard ``? – Keith Thompson Jun 24 '16 at 02:43
  • I understand but I think in any posix compliant OS both time.h & sys/time.h are present. Also you are completely correct that time_t can be negative value too as it is represented as seconds elapsed from 1970-01-01T00:00Z. – anijhaw Jun 27 '16 at 20:20
5

Windows uses a different epoch and time units: see Convert Windows Filetime to second in Unix/Linux

What std::time() returns on Windows is (as yet) unknown to me (;-))

Community
  • 1
  • 1
davecb
  • 284
  • 3
  • 7
0

This works for me, just convert nanoseconds to whatever you like, and convert uint64_t to whatever you like.

#include <chrono>
uint64_t unix_time()
{
    return std::chrono::duration_cast<std::chrono::nanoseconds>
    (
        std::chrono::system_clock::now().time_since_epoch()
    ).count();
}