Video Coming Soon...

Created by Zed A. Shaw Updated 2026-04-30 02:05:52

36: date

The date command seems simple at first. It prints the current date and time. You can easily do that with std::chrono. In my example below it's 2 lines of code to get a basic date/time output.

Where date gets complicated is when you try to replicate the output formatting. Some languages handle this fine, but others would require you to create an entire date/time parser. It's actually easier to implement date using the old school C functio strftime because date is quite literally a wrapper around strftime() in C.

The Challenge

Once again, the linux man page for date may be better as a reference. You'll also need the man page for strftime to complete the exercise. Many times there's a C library that's easier to use than C++, but it'll be less safe. Actually, just about everything in C is way less safe, and in this exercise you'll learn about that.

The challenge is to read that man page, and study the example at the bottom of the page, then implement a date utility that can mimic the original as much as possible. To do your first run of date use this:

./builddir/date "%a, %d %b %Y %T %z"

Which should print out a date like this:

Wed, 22 Apr 2026 00:22:39 -0400

The Code

Here's my quick little implementation of a basic date that can output a format. It doesn't have anything but enough to get you unstuck if you can't figure it out.

See my first version of dateView Source file date.cpp Only

#include <iostream>
#include <ctime>
#include <cassert>
#include <fmt/core.h>

int main(int argc, char* argv[]) {
  std::string format{argv[1]};
  char buffer[1024] = {0};
  time_t t;
  struct tm *tmp = nullptr;

  t = time(NULL);
  tmp = localtime(&t);
  assert(tmp != NULL && "Invalid time.");

  strftime(buffer, sizeof(buffer), format.c_str(), tmp);
  fmt::println("{}", buffer);
}

The Discussion

When you study the strftime function you should notice a few important differences compared to a similar C++ API:

  1. You have to create your own buffer and exactly specify the size.
  2. Even when you do this, many C function will just say, "Haha whatever bro, I'm ignoring your size."
  3. You also have to work with pointers, which is the struct tm *tmp = nullptr part in my code. You have covered pointers quite yet, but just assume it's a way to get a result from localtime().
  4. I also use assert() in this code to check for an error, but if you read the strftime() documentation you'll be able to do better. One thing you'll learn with C is you always have to check the return values. Always. ALWAYS! C doesn't have exceptions so that's the only way to tell if there's an error.
  5. However, every function has random weird ways to report an error like this. Some functions return a nullptr (NULL in C). Others return an integer with -1 meaning an error and 0 being valid. Others return anything not 0 as an error.

Further Study

If you're on Linux get a tool called Valgrind and run your date under it. Try doing this to cause your code to anger Valgrind:

  1. Set buffer to buffer[10] instead of buffer[1024].
  2. Change the sizeof(buffer) to 1024.

What this does is "lie" to `strftime() that your buffer is 1024 characters in size, but it's actually 10 characters in size. Depending on your platform valgrind may or may not catch this.

ADVANCED: Some people hate this so much that they'll do anything to remake this in C++. Can you?

Previous Lesson Next Lesson

Register for Learn C++ the Hard Way

Register to gain access to additional videos which demonstrate each exercise. Videos are priced to cover the cost of hosting.