Display a Digital Clock

(I see there are many clock challenges, I have tried to read them all, I'm pretty sure this is unique)

Write some code that continuously updates a digital clock displayed in the format h:m:s where h, m, and s can occupy 1 or 2 characters each. The restrictions in simple terms as @BlueEyedBeast put it, I basically want it to replace the time shown.

  • Newlines are not allowed
  • Trailing spaces are allowed
  • Other trailing characters are not allowed
  • No seconds should be missed (57 -> 59 is not allowed)
  • Numbers beginning with "0" are allowed, as long as they don't occupy more than 2 characters
  • The code must not accept any input
  • If your language can't get the current time without input, you may use for input up to 8 bytes in a standardly allowed way
  • Output must be to stdout
  • This is codegolf so the shortest answer wins!


I'm working on a language named *><> (starfish) because programs like this aren't possible in ><> (just wait for file i/o) . Here's a working digital clock program in it (ungolfed). This program is written in *><>:

s":"m":"hnonon"   "ooo88888888888ooooooooooo1S

Note: Everything is identical to ><> in this except, s = second, m = minute, h = hour, S = sleep(100ms*x)

This outputs:


Updating every 100ms until terminated.

Disallowed Examples

The following are not allowed:




14:44:31 14:44:32



The time must remain on the first line it was outputted with no visible trailing characters. Clearing the terminal though, would be allowed as that still wouldn't have any trailing characters.

  • 1
    \$\begingroup\$ do we have to wait 100ms or can we just update constantly forever? \$\endgroup\$
    – Blue
    Dec 5, 2016 at 21:42
  • 1
    \$\begingroup\$ you don't have to wait, the wait is just what the example does. \$\endgroup\$ Dec 5, 2016 at 21:43
  • 2
    \$\begingroup\$ The challenge requirements seem too strict to me. \$\endgroup\$
    – mbomb007
    Dec 5, 2016 at 21:50
  • 1
    \$\begingroup\$ @mbomb007 I removed "The program must be able to exit on user input that isn't a signal/interrupt" as the current answers didn't seem to follow it anyways. \$\endgroup\$ Dec 5, 2016 at 22:05
  • 1
    \$\begingroup\$ Can the program rely on a specific local setting of the OS? \$\endgroup\$
    – raznagul
    Dec 6, 2016 at 17:01

39 Answers 39


HTML + JS (ES6), 8 + 60 = 68 bytes

Tested in Chrome.

setInterval`a.innerHTML=new Date().toLocaleTimeString('fr')`
<a id=a>

-1 byte (@ETHProductions): Use French time format instead of .toTimeString().slice(0,8)

HTML + JS (ES6), 8 + 62 = 70 bytes

This will work in FireFox.

setInterval('a.innerHTML=new Date().toLocaleTimeString`fr`',0)
<a id=a>

-3 bytes (@ETHProductions): Use French time format instead of .toTimeString().slice(0,8)

  • 3
    \$\begingroup\$ How does this work? I've never seen the backtick syntax before. I can't find anything on it either after some quick searching. \$\endgroup\$ Dec 5, 2016 at 23:22
  • 1
    \$\begingroup\$ Working for me in Inox (Chromium) \$\endgroup\$ Dec 5, 2016 at 23:22
  • 1
    \$\begingroup\$ @Carcigenicate It's part of the latest JavaScript spec, ECMAScript6. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… \$\endgroup\$
    – darrylyeo
    Dec 5, 2016 at 23:26
  • \$\begingroup\$ @darrylyeo Thanks. I could find things on the literal syntax, but I couldn't see how it was applied here. I need to read the spec again. I still don't understand how the function that precedes the backtick is used. \$\endgroup\$ Dec 5, 2016 at 23:28
  • 2
    \$\begingroup\$ You can save 3 bytes in the Firefox one with new Date().toLocaleTimeString`fr` (1 byte in the Chrome one with ...TimeString('fr')) \$\endgroup\$ Dec 6, 2016 at 1:02

Python 2, 50 bytes

(Python 2.1+ for ctime with no argument)

import time
while 1:print'\r'+time.ctime()[11:19],

time.ctime() yields a formatted string, from which the hh:mm:ss may be sliced using [11:19] (it remains in the same location whatever the date and time).

printing the carriage return '\r' before the text and making the text the first item of a tuple with , effectively suppresses the implicit trailing '\n' and overwrites the previously written output.

while 1 loops forever.

  • 3
    \$\begingroup\$ I think this needs a , at the end to supress the newline otherwise in Python 2.7.12 I get newlines. \$\endgroup\$ Dec 5, 2016 at 23:46
  • \$\begingroup\$ Oops, yes you are correct... updated \$\endgroup\$ Dec 5, 2016 at 23:46

Mathematica, 48 41 37 28 bytes


The output will be a TimeObject, refreshing continuously.

Looks like this: enter image description here

Alternative versions

48 bytes:


53 bytes:

  • 1
    \$\begingroup\$ With it updating every second, did you ensure that it never skips seconds? (Ex: 11:11:11 -> 11:11:13) \$\endgroup\$ Dec 5, 2016 at 23:19
  • \$\begingroup\$ Dynamic@{DateString@TimeObject[], Clock[]}[[1]] \$\endgroup\$
    – DavidC
    Dec 5, 2016 at 23:20
  • 1
    \$\begingroup\$ @redstarcoder it updates every ~1.002s, so I changed to updating every 100ms \$\endgroup\$ Dec 5, 2016 at 23:24
  • \$\begingroup\$ Welp, I just realized I don't actually need Pause. \$\endgroup\$ Dec 5, 2016 at 23:32
  • \$\begingroup\$ Dynamic@{Now,Clock[]}[[1]] is 26 bytes and shows a datetime object. Dynamic@{DateString@"Time",Clock[]}[[1]] is 40 bytes and outputs only hh:mm:ss \$\endgroup\$ Dec 12, 2016 at 21:50

Pyke, 6 bytes

Ctr\ J

Try it here!

I think this is valid. Replace the space character with carriage return for valid output (does not work online)

  • \$\begingroup\$ Sorry it's not. No newlines are allowed or trailing characters after the time. I'll put 2 examples to be more explicit. \$\endgroup\$ Dec 5, 2016 at 21:48
  • \$\begingroup\$ I don't see that in the spec? \$\endgroup\$
    – Blue
    Dec 5, 2016 at 21:49
  • 1
    \$\begingroup\$ The first line says newlines are not allowed, the third says no trailing characters. I'm sorry if that's unclear, I'd appreciate advice on fixing it. \$\endgroup\$ Dec 5, 2016 at 21:51
  • \$\begingroup\$ So you want it to replace the old time shown? \$\endgroup\$
    – Blue
    Dec 5, 2016 at 21:52
  • \$\begingroup\$ Yes exactly! Your current code seems perfect. \$\endgroup\$ Dec 5, 2016 at 21:56

I see that the requirement for a non-signal UI input to stop the program has been removed. So now we can do:

Bash + coreutils, 28

yes now|date -f- +$'\e[2J'%T

yes continuously outputs the string "now", once per line, into a pipe.

date -f- reads interprets each "now" as the current time, then outputs in the required format. The format string includes the ANSI escape sequence to clear the screen. date does output a newline after the date - I'm not sure if this disqualifies, since the screen is cleared every time anyway.

If it disqualifies, then we can use tr instead:

Bash + coreutils, 31

yes now|date -f- +%T|tr \\n \\r

Previous Answers:

Bash + X, 32

xclock -d -update 1 -strftime %T

Unfortunately this can only update every second. If that disqualifies, then we can do this instead:

Bash + coreutils, 43

until read -t0
do printf `date +%T`\\r
  • \$\begingroup\$ Updating every second is fine, as long as it doesn't ever skip seconds (IE: 12-> 14). \$\endgroup\$ Dec 5, 2016 at 22:11
  • \$\begingroup\$ I'll allow your newline! I never expected this case to happen heh. \$\endgroup\$ Dec 6, 2016 at 1:14
  • \$\begingroup\$ Is this allowed? date +$'\e[2J'%T;$0 \$\endgroup\$
    – Evan Chen
    Dec 8, 2016 at 5:57
  • \$\begingroup\$ @EvanChen no, because each iteration recursively spawns a new process and will eventually use up available memory or PID space, analogous to a stack overflow. However you could do date +$'\e[2J'%T;exec $0 for 24 bytes... \$\endgroup\$ Dec 8, 2016 at 6:34

QBIC, 6 bytes


{      Starts a DO-loop
 _C    CLS
   ?   PRINT
    _d TIME$

Constantly clears the screen and prints the system time in the format 22:03:41.


PHP, 28 bytes

for(;;)echo date("\rH:i:s");

The date function prints everything literally that it doesn´t recognize.

\r is the carriage return, sets the cursor to the first column.

Run with -r.


Clojure, 150 136 141 bytes

V3: 141 bytes :(

+5 bytes to fix a bug. Since the times aren't zero padded, the clock can "shrink" and expand when the time changes. It was "smearing" when it shrunk because the last digit was no longer being cleared. Fixed it by adding some spaces at the end to ensure everything is being overwritten.

#(while true(flush)(print(str(apply str(repeat 9"\b"))(.format(java.text.SimpleDateFormat."H:m:s")(java.util.Date.))"   "))(Thread/sleep 99))

V2: 136 bytes

#(while true(flush)(print(str(apply str(repeat 9"\b"))(.format(java.text.SimpleDateFormat."H:m:s")(java.util.Date.))))(Thread/sleep 99))

-14 bytes by switching to using SimpleDateFormat to format the date. Still huge.

V1: 150 bytes

#(while true(let[d(java.util.Date.)](flush)(print(str(apply str(repeat 9 "\b"))(.getHours d)":"(.getMinutes d)":"(.getSeconds d)))(Thread/sleep 100)))

I realized I'm probably using the worst way possible to get the date. Definitely room for improvement here.


(defn -main []
  (while true
    (let [d (java.util.Date.)]
          (apply str (repeat 9 "\b"))
          (.getHours d)":"(.getMinutes d)":"(.getSeconds d)))
      (Thread/sleep 100))))

SmileBASIC 3.3.2, 38 bytes

@L?TIME$;" ";

UTF-16 sucks :(

Anyway, this repeatedly prints the local time in HH:MM:SS with a space after it, no newline afterward. It doesn't update every second though, it just repeatedly prints forever.

  • \$\begingroup\$ Sorry this isn't valid, it needs to replace the output, this doesn't. Setting the first line to @L?TIME$ and appending a line after (for a total of 3 lines) that reads LOCATE 0, 0 does the trick (does SmileBASIC support carriage return?). \$\endgroup\$ Jan 5, 2017 at 15:20
  • \$\begingroup\$ Also you forgot to score the newline, making this 40 bytes (UTF-16 is brutal for code golf). You can get the character length very easilly via Python REPL len(""" YOUR CODE HERE """), then just do *2 for UTF-16. \$\endgroup\$ Jan 5, 2017 at 15:34
  • \$\begingroup\$ No SB doesn't do CR actually, I would have to drop a LOCATE statement into there which would absolutely destroy my score :P Or a CLS:VSYNC which is just as bad. \$\endgroup\$
    – snail_
    Jan 7, 2017 at 20:00
  • \$\begingroup\$ Yeah, sadly this solution is invalid without it. Good news though! SmileBASIC is scored as UTF-8. \$\endgroup\$ Jan 7, 2017 at 21:17

C, 134 116 89 80 76 75 73 bytes


---- Old versions:





Saved 9 more bytes thanks to @nmjcman101 again:


Saved 27 bytes thanks to @nmjcman101


I figured out I don't need to put `#include<stdio.h>` into the file :)
main(){for(;;){time_t n=time(0);char b[9];strftime(b,9,"%H:%M:%S",localtime(&n));printf("\r%s",b);}}


main(){for(;;){time_t n=time(0);char b[9];strftime(b,9,"%H:%M:%S",localtime(&n));printf("\r%s",b);}}
  • \$\begingroup\$ It looks like (for me) you can remove time.h as well. This removes the time_t type, so you need to make n an int instead. This can be done by declaring it outside of main (like n;main...), which removes the need for the int. You can also get rid of the char with the same trick: b[9];main.... They're both int type now, but it's flexible enough. \$\endgroup\$
    – nmjcman101
    Dec 6, 2016 at 13:01
  • \$\begingroup\$ Wow, thanks a lot, I didn't know this would work. Thank you \$\endgroup\$
    – Stefan
    Dec 6, 2016 at 13:23
  • \$\begingroup\$ Please stop me if you'd like to golf it yourself, but I also took out the strftime... and the b[9] and just made print into this: printf("\r%d:%d:%d",(n/3600)%60-29,(n/60)%60,n%60); I'm not sure if the parens are needed or not. Also you can take out a set of {} by putting commas between your statements so it's for(;;)a,b,c; \$\endgroup\$
    – nmjcman101
    Dec 6, 2016 at 13:24
  • 1
    \$\begingroup\$ These parentheses are annoying. (n/60)%60, seriously? \$\endgroup\$
    – anatolyg
    Dec 7, 2016 at 10:39
  • 1
    \$\begingroup\$ You can save 1 byte by declaring n as parameter of main, say main(n) instead of n;main() \$\endgroup\$
    – Karl Napf
    Dec 8, 2016 at 9:52

Bash + watch, 19 bytes

watch is not a part of coreutils, but is available out of the box on virtually every Linux distro.


watch -tn1 date +%T

Try it online !


MATL, 11 bytes


Infinite loop that clears the screen and prints the time in the specified format.

You can try it at MATL Online!. This compiler is experimental; if it doesn't work refresh the page and press "Run" again.


WinDbg, 73 bytes

.do{r$t0=0;.foreach(p {.echotime}){r$t0=@$t0+1;j8==@$t0'.printf"p \r"'}}1

It continually updates a line with the current time until the user presses Ctrl+Break.

How it works:

.do                          * Start do-while loop
    r$t0 = 0;                * Set $t0 = 0
    .foreach(p {.echotime})  * Foreach space-delimited word in a sentence like "Debugger (not 
    {                        * debuggee) time: Mon Dec  5 14:08:10.138 2016 (UTC - 8:00)"
        r$t0 = @$t0+1;       * Increment $t0
        j 8==@$t0            * If $t0 is 8 (ie- p is the current time)
            .printf"p \r"    * Print p (current time) and \r so the next print overwrites
} 1                          * Do-while condition: 1, loop forever

Sample output (well, you get the idea):

0:000> .do{r$t0=0;.foreach(p {.echotime}){r$t0=@$t0+1;j8==@$t0'.printf"p \r"'}}1

C#, 82 bytes

()=>{for(;;)Console.Write(new string('\b',8)+DateTime.Now.ToString("HH:mm:ss"));};

Anonymous method which constantly overwrites 8 characters with new output. Can be made 1 byte shorter if modifying to accept a dummy parameter (z=>...).

Full program:

using System;

public class Program
    public static void Main()
        Action a =
        () =>
            for (;;)
                Console.Write(new string('\b', 8) + DateTime.Now.ToString("HH:mm:ss"));

  • 1
    \$\begingroup\$ Is it allowed not to import System? Some people do it, and some people don't :/ \$\endgroup\$
    – Yytsi
    Dec 6, 2016 at 13:48
  • \$\begingroup\$ He didn't in his actual solution, just in the demo program, so yes, it is ok \$\endgroup\$
    – Stefan
    Dec 6, 2016 at 13:55

C#, 65 bytes


Works by overwriting the same line within an endless loop


Powershell, 39 bytes

for(){write-host -n(date -F h:m:s`0`r)}

Because I dislike using cls in Powershell. From briantist's post @https://codegolf.stackexchange.com/a/102450/63383


Pascal, 61 bytes

uses sysutils;begin while 1=1do write(#13,timetostr(now))end.

Free pascal has nice time routines in SysUtils unit. Ungolfed:

  while 1=1 do
    write(#13, timetostr(now));

Commodore BASIC (CBM/PET, C64, C128, VIC-20, C16/+4), 64 ~62 BASIC bytes (tokens), 64 62 PETSCII characters with keyword abbreviations


Edit I realised that this is what I would call a zero liner, or in other words, it does not require a line number to run, so I've taken this out. Once you break it though, you need to type it in again.

Changes Line numbers in Commodore BASIC take up I think at least two bytes (though I need to check), so by actual byte count is an estimation, however, removing the line number and using the LEFT$ command for the first two digits, rather than the MID$ command, has shaved off two whole characters from this.

Some notes: if you are entering this on a Commodore C64 then you will need to use keyword abbreviations (see the screen shot below). Some other Commodore 8-bits, like the C128 and VIC-20, accept more than 80 characters entered per line, but to be sure, use the keyword abbreviations anyway.

To set the time first, use TI$="112233" as HHMMSS format as 24 hours (000000 being midnight).

How it works

TI$ is a system variable which fairly accurately keeps time. 8 BIT Show and Tell explores this in some depth in this YouTube video and is well worth a watch if you are interested.

An unbroken loop is set with resetting the I variable per iteration by setting it to 0. We then use the MID$ and RIGHT$ function to print out each relevant time segment, being HH:MM:SS. A list of BASIC keywords can be found here.

Display a Digital Clock, Commodore C64

  • \$\begingroup\$ I can save a few bytes by using the LEFT$ command in place of the first MID$ command, because of the way that Commodore BASIC tokenises each keyword. \$\endgroup\$ Jun 7, 2023 at 10:03

Vim, 26 bytes


This creates a recursive macro (e.g. an eternal loop) that deletes all the text on the current line and replaces it with the current time.


Pyth - 28 bytes

Kinda longish, because pyth has no strftime.


Groovy, 45 characters

for(;;)print(new Date().format("\rHH:mm:ss"))

Jelly, 8 bytes


13Ọ        chr(13), carriage return
   7ŒT     time string, which extends the previous character
      Ȯ    print
       ß   call the whole link again

Try it online!

The carriage return doesn't work online, and I can't get the interpreter to work, so its kinda untested, but it works as expected when I use printable characters in place of the CR.


ForceLang, 123 bytes

def s set
s d datetime
s z string.char 8
s z z.repeat 16
label 1
io.write z
io.write d.toTimeString d.now()
d.wait 9
goto 1

datetime.toTimeString is backed in the reference implementation by Java's DateFormat.getTimeInstance(), which is locale-dependent, so you can set your default system locale to one that uses 24-hour time.


PowerShell, 30 28 24 20 bytes

Changed my computer's region to Germany based on raznagul's comment to save 4 bytes. :)

for(){date -F T;cls}

Previous version that works in all locales.

for(){date -F h:m:s;cls}

Java, 67 bytes


We loop infinitely, grabbing the current time and outputting to screen. The quad backspace is for easy formatting, because otherwise we'd have to do something like this:

for(;;)System.out.print("\r" + java.time.LocalTime.now().truncatedTo(java.time.temporal.ChronoUnit.SECONDS));

tcl, 69 bytes

while 1 {puts -nonewline \r[clock format [clock seconds] -format %T]}

Try it here!


C 65 (prev 64) bytes

Guaranteed to work on Linux machine. :)

@Marco Thanks!

f(){while(1){system("date +%T");usleep(100000);system("clear");}}

SmileBASIC, 14 bytes


CLS clears the screen, ? TIME$ prints the current time, and EXEC 0 runs the code that's in slot 0. It's a bit flickery, but there's nothing in the reqirements about that, so it should be fine.

Format is HH:MM:SS 24 hour time :(


x86-16 machine code, IBM PC DOS, 71 69 bytes


00000000: b81c 35cd 2153 06ba 1901 e806 00b4 08cd  ..5.!S..........
00000010: 211f 5ab8 1c25 cd21 c3b4 2ccd 218a c5e8  !.Z..%.!..,.!...
00000020: 0800 91e8 0400 8ac6 b2ff d40a 0d30 3086  .............00.
00000030: e0cd 2986 e0cd 2984 d27c 05b0 3acd 29c3  ..)...)..|..:.).
00000040: b00d cd29 cf                             ...).


B8 351C         MOV  AX, 0351CH             ; AL = 1CH, AH = 35H 
CD 21           INT  21H                    ; get interrupt vector for 1CH into ES:BX
53              PUSH BX                     ; save old vector
06              PUSH ES                     ; save old segment
BA 011D R       MOV  DX, OFFSET GET_TIME    ; DX = interrupt vector of time proc 
E8 0117 R       CALL SET_VECT               ; setup new vector
B4 08           MOV  AH, 8                  ; DOS read char from stdin without echo
CD 21           INT  21H                    ; wait for user to press the "any key"
1F              POP  DS                     ; restore old segment
5A              POP  DX                     ; restore old vector
B8 251C         MOV  AX, 0251CH             ; AL = 1CH, AH = 25H 
CD 21           INT  21H                    ; set interrupt vector from DS:DX
C3              RET                         ; return to DOS 
B4 2C           MOV  AH, 2CH                ; get DOS time 
CD 21           INT  21H                    ; CH = hour CL = minute DH = second 
8A C5           MOV  AL, CH                 ; display hour: AL = CH 
E8 012E R       CALL OUT_TIME               ; write time
91              XCHG AX, CX                 ; display minute: AL = CL 
E8 012E R       CALL OUT_TIME               ; write time
8A C6           MOV  AL, DH                 ; display second: AL = DH 
B2 FF           MOV  DL, -1                 ; set DL to -1 so doesn't display ':' 
D4 0A           AAM                         ; BCD convert: AL = AL % 10, AH = AL / 10 
0D 3030         OR   AX, '00'               ; ASCII convert 
86 E0           XCHG AH, AL                 ; endian convert 
CD 29           INT  29H                    ; write tens 
86 E0           XCHG AH, AL                 ; swap digits 
CD 29           INT  29H                    ; write ones 
84 D2           TEST DL, DL                 ; when DL = -1, it is seconds digit 
7C 05           JL   DONE_TIME              ; if last number, write CR not ':'
B0 3A           MOV  AL, ':'                ; write ':'
CD 29           INT  29H 
C3              RET                         ; return from near call
B0 0D           MOV  AL, 0DH                ; carriage return 
CD 29           INT  29H                    ; move cursor back to beginning of line
CF              IRET                        ; return from interrupt 

A standalone PC DOS executable COM program. Uses DOS to hook the hardware timer interrupt which calls the program every 18.2ms to update the clock on the screen. Exits when any key is pressed.


enter image description here

(A key was hit after 5 seconds, exiting the program)


Japt, 8 bytes


Test it

i            :Every 0 milliseconds
 @           :Run the following function
  Oq         :Replace the output with
    K        :Date object
     ¤       :Convert to time string
      ¯8     :Slice to the 8th character

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.