C++ Digital Clock Project
A live console clock that redraws itself every second.
What you will build
A clock that prints the current time and refreshes in place, one tick per second. Under the hood you're learning how C++ represents time — the single most useful library skill for anything involving timers, logs, or scheduling.
What you will learn
- Getting the current time with std::chrono
- Converting time_point to a readable string
- Redrawing console output with carriage returns
- Sleeping a thread for precise intervals
Feature checklist
- Displays HH:MM:SS, updating every second
- Shows the current date alongside the time
- Optional 12-hour format with AM/PM
- Clean single-line redraw (no scrolling spam)
- Graceful exit on Ctrl+C
Starter code
#include <iostream>
#include <chrono>
#include <ctime>
#include <thread>
int main() {
while (true) {
auto now = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(now);
std::tm local{};
localtime_s(&local, &t); // use localtime_r on Linux/macOS
std::cout << "\rTime: "
<< (local.tm_hour < 10 ? "0" : "") << local.tm_hour << ":"
<< (local.tm_min < 10 ? "0" : "") << local.tm_min << ":"
<< (local.tm_sec < 10 ? "0" : "") << local.tm_sec
<< std::flush;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}Full walkthrough
Step 1: Include the time toolkit
This program needs four headers: <iostream> to print, <chrono> for the clock itself, <ctime> for the calendar types (std::time_t, std::tm), and <thread> so you can sleep between redraws. Forgetting <thread> is the most common first compile error here.
Step 2: Get the current time as a time_point
std::chrono::system_clock::now() returns a time_point — an abstract instant, not something printable. Convert it with system_clock::to_time_t(now) to get a std::time_t, the C-style seconds-since-1970 value that the formatting functions understand.
Step 3: Turn time_t into broken-down local time
A std::tm struct holds hour, minute, second as separate fields. Fill it with localtime_s(&local, &t) on Windows (or localtime_r(&t, &local) on Linux/macOS) — these are the thread-safe versions that write into YOUR struct instead of a shared hidden one.
std::tm local{};
localtime_s(&local, &t); // localtime_r on Linux/macOS
int h = local.tm_hour, m = local.tm_min, s = local.tm_sec;Step 4: Format with leading zeros
A clock that prints 9:5:3 looks broken, so each field gets a zero check: (local.tm_hour < 10 ? "0" : "") in front of the number. This little ternary is the whole formatting engine of the starter code — later you can swap it for std::put_time from <iomanip>, but the ternary teaches you what put_time is doing for you.
Step 5: Redraw in place with a carriage return
Print "\r" (carriage return) instead of "\n" at the start of the line: the cursor jumps back to column zero and the new time overwrites the old one. Pair it with std::flush — without the flush, the text can sit in the output buffer and the clock appears frozen even though the loop is running.
Step 6: Sleep for one second, then loop forever
std::this_thread::sleep_for(std::chrono::seconds(1)) pauses the thread so you are not redrawing thousands of times per second and cooking the CPU. The while (true) loop never ends on its own; Ctrl+C is the intended exit, which the checklist calls graceful enough for a clock.
while (true) {
// ... get time, format, print with \r ...
std::this_thread::sleep_for(std::chrono::seconds(1));
}Step 7: Add the date and the 12-hour option
For the checklist extras: std::tm also carries tm_mday, tm_mon (+1 — months are 0-based!) and tm_year (+1900), so the date is free once you have the struct. The 12-hour format is h % 12 with 0 shown as 12, plus 'AM' when h < 12 else 'PM'.
Common mistakes
- Printing with \n instead of \r, so the terminal fills with hundreds of scrolling time lines.
- Forgetting std::flush, concluding the loop is broken when the output is really just buffered.
- Reading tm_mon and tm_year raw — October prints as month 9 and the year as 126 unless you add 1 and 1900.
Compile and run
g++ -std=c++17 -o digital_clock digital_clock.cppOn Linux with an older GCC, std::this_thread may need -pthread added to the compile command. localtime_s is the Windows spelling; on Linux/macOS use localtime_r — the starter code comments mark the spot.
Sample run
$ ./digital_clock
Time: 09:41:07
Time: 09:41:08
Time: 09:41:09
Time: 09:41:10
Time: 09:41:11
(the same line keeps redrawing itself once per second)
(press Ctrl+C to stop the clock)
Time: 09:41:12
Time: 09:41:13
^CTry it in your browser
No browser demo is included for this project. Build the C++ version below — that is the real program.