20
\$\begingroup\$

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!

Example

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:

14:44:31

Updating every 100ms until terminated.

Disallowed Examples

The following are not allowed:

1:

14:44:3114:44:32

2:

14:44:31 14:44:32

3:

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ do we have to wait 100ms or can we just update constantly forever? \$\endgroup\$ – Blue Dec 5 '16 at 21:42
  • 1
    \$\begingroup\$ you don't have to wait, the wait is just what the example does. \$\endgroup\$ – redstarcoder Dec 5 '16 at 21:43
  • 2
    \$\begingroup\$ The challenge requirements seem too strict to me. \$\endgroup\$ – mbomb007 Dec 5 '16 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\$ – redstarcoder Dec 5 '16 at 22:05
  • 1
    \$\begingroup\$ Can the program rely on a specific local setting of the OS? \$\endgroup\$ – raznagul Dec 6 '16 at 17:01

35 Answers 35

5
\$\begingroup\$

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)

\$\endgroup\$
  • \$\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\$ – redstarcoder Dec 5 '16 at 21:48
  • \$\begingroup\$ I don't see that in the spec? \$\endgroup\$ – Blue Dec 5 '16 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\$ – redstarcoder Dec 5 '16 at 21:51
  • \$\begingroup\$ So you want it to replace the old time shown? \$\endgroup\$ – Blue Dec 5 '16 at 21:52
  • \$\begingroup\$ Yes exactly! Your current code seems perfect. \$\endgroup\$ – redstarcoder Dec 5 '16 at 21:56
10
\$\begingroup\$

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)

\$\endgroup\$
  • 2
    \$\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\$ – Carcigenicate Dec 5 '16 at 23:22
  • 1
    \$\begingroup\$ Working for me in Inox (Chromium) \$\endgroup\$ – redstarcoder Dec 5 '16 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 '16 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\$ – Carcigenicate Dec 5 '16 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\$ – ETHproductions Dec 6 '16 at 1:02
6
\$\begingroup\$

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.

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

Mathematica, 48 41 37 28 bytes

Do[s=Now[[2]],∞]~Monitor~s

The output will be a TimeObject, refreshing continuously.

Looks like this: enter image description here

Alternative versions

48 bytes:

Dynamic@Refresh[TimeObject[],UpdateInterval->.1]

53 bytes:

Dynamic@Refresh[DateString@"Time",UpdateInterval->.1]
\$\endgroup\$
  • 1
    \$\begingroup\$ With it updating every second, did you ensure that it never skips seconds? (Ex: 11:11:11 -> 11:11:13) \$\endgroup\$ – redstarcoder Dec 5 '16 at 23:19
  • \$\begingroup\$ Dynamic@{DateString@TimeObject[], Clock[]}[[1]] \$\endgroup\$ – DavidC Dec 5 '16 at 23:20
  • 1
    \$\begingroup\$ @redstarcoder it updates every ~1.002s, so I changed to updating every 100ms \$\endgroup\$ – JungHwan Min Dec 5 '16 at 23:24
  • \$\begingroup\$ Welp, I just realized I don't actually need Pause. \$\endgroup\$ – JungHwan Min Dec 5 '16 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\$ – Kelly Lowder Dec 12 '16 at 21:50
5
\$\begingroup\$

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
done
\$\endgroup\$
  • \$\begingroup\$ Updating every second is fine, as long as it doesn't ever skip seconds (IE: 12-> 14). \$\endgroup\$ – redstarcoder Dec 5 '16 at 22:11
  • \$\begingroup\$ I'll allow your newline! I never expected this case to happen heh. \$\endgroup\$ – redstarcoder Dec 6 '16 at 1:14
  • \$\begingroup\$ Is this allowed? date +$'\e[2J'%T;$0 \$\endgroup\$ – Evan Chen Dec 8 '16 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\$ – Digital Trauma Dec 8 '16 at 6:34
4
\$\begingroup\$

QBIC, 6 bytes

{_C?_d

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

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

\$\endgroup\$
3
\$\begingroup\$

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.

Ungolfed:

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

Bash + watch, 19 bytes

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

Golfed

watch -tn1 date +%T

Try it online !

\$\endgroup\$
2
\$\begingroup\$

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
14:10:12.329
\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

MATL, 11 bytes

`XxZ'13XODT

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.

\$\endgroup\$
2
\$\begingroup\$

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"));
        };

        a();
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Is it allowed not to import System? Some people do it, and some people don't :/ \$\endgroup\$ – Yytsi Dec 6 '16 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 '16 at 13:55
2
\$\begingroup\$

C#, 65 bytes

()=>{for(;;)Console.Write("\r"+DateTime.Now.ToLongTimeString());};

Works by overwriting the same line within an endless loop

\$\endgroup\$
2
\$\begingroup\$

SmileBASIC 3.3.2, 38 bytes

@L?TIME$;" ";
GOTO@L

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.

\$\endgroup\$
  • \$\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\$ – redstarcoder Jan 5 '17 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\$ – redstarcoder Jan 5 '17 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 '17 at 20:00
  • \$\begingroup\$ Yeah, sadly this solution is invalid without it. Good news though! SmileBASIC is scored as UTF-8. \$\endgroup\$ – redstarcoder Jan 7 '17 at 21:17
2
\$\begingroup\$

C, 134 116 89 80 76 75 73 bytes

main(n){for(;time(&n);)printf("\r%02d:%02d:%02d",n/3600%24,n/60%60,n%60);}

---- Old versions:
main(n){for(;;)n=time(0),printf("\r%02d:%02d:%02d",n/3600%24,n/60%60,n%60);}

n;main(){for(;;)n=time(0),printf("\r%02d:%02d:%02d",n/3600%24,n/60%60,n%60);}

---- 

n;main(){for(;;)n=time(0),printf("\r%02d:%02d:%02d",n/3600%24,n/60%60,n%60);}

----

Saved 9 more bytes thanks to @nmjcman101 again:
n;main(){for(;;)n=time(0),printf("\r%02d:%02d:%02d",(n/3600)%24,(n/60)%60,n%60);}

----

Saved 27 bytes thanks to @nmjcman101
n,b[9];main(){for(;;){n=time(0);strftime(b,9,"%H:%M:%S",localtime(&n));printf("\r%s",b);}}

----

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

----

#include<time.h>
#include<stdio.h>
main(){for(;;){time_t n=time(0);char b[9];strftime(b,9,"%H:%M:%S",localtime(&n));printf("\r%s",b);}}
\$\endgroup\$
  • \$\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 '16 at 13:01
  • \$\begingroup\$ Wow, thanks a lot, I didn't know this would work. Thank you \$\endgroup\$ – Stefan Dec 6 '16 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 '16 at 13:24
  • 1
    \$\begingroup\$ These parentheses are annoying. (n/60)%60, seriously? \$\endgroup\$ – anatolyg Dec 7 '16 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 '16 at 9:52
2
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

Pascal, 61 bytes

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

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

uses
  sysutils;
begin
  while 1=1 do
    write(#13, timetostr(now));
end.
\$\endgroup\$
2
\$\begingroup\$

C 65 (prev 64) bytes

Guaranteed to work on Linux machine. :)

@Marco Thanks!

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

Vim, 26 bytes

qqS<C-r>=strftime("%T")<CR><esc>@qq@q

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.

\$\endgroup\$
1
\$\begingroup\$

Pyth - 28 bytes

Kinda longish, because pyth has no strftime.

#p+"\r"j\:m.[`02`dP>4.d2.d.1
\$\endgroup\$
1
\$\begingroup\$

Groovy, 45 characters

for(;;)print(new Date().format("\rHH:mm:ss"))
\$\endgroup\$
1
\$\begingroup\$

Jelly, 8 bytes

13Ọ7ŒTȮß

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.

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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}
\$\endgroup\$
1
\$\begingroup\$

tcl, 69 bytes

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

Try it here!

\$\endgroup\$
0
\$\begingroup\$

Batch, 36 bytes

@set/p.=␈␈␈␈␈␈␈␈%time:~0,8%<nul
@%0

Where represents the ASCII BS character (code 8).

\$\endgroup\$
0
\$\begingroup\$

Racket, 71 bytes

(require srfi/19)(let l()(display(date->string(current-date)"↵~3"))(l))

Where the is actually a CR (hex 0d). Hex dump of the program for further clarification (notice byte at position hex 4d):

00000000  28 72 65 71 75 69 72 65  20 73 72 66 69 2f 31 39  |(require srfi/19|
00000010  29 28 6c 65 74 20 6c 28  29 28 64 69 73 70 6c 61  |)(let l()(displa|
00000020  79 28 64 61 74 65 2d 3e  73 74 72 69 6e 67 28 63  |y(date->string(c|
00000030  75 72 72 65 6e 74 2d 64  61 74 65 29 22 0d 7e 33  |urrent-date)".~3|
00000040  22 29 29 28 6c 29 29                              |"))(l))|
00000047

Uses SRFI/19 included with the Racket distribution. (current-date) gets the current local date & time. The date->string format ~3 is ISO-8601 hour-minute-second format. (let l () ... (l)) in an idiomatic infinite loop. (require srfi/19) loads the srfi/19 module.

\$\endgroup\$
0
\$\begingroup\$

C, 156 bytes

#include<stdio.h>
#include<time.h>
int main(){time_t a;struct tm *b;char c[9];for(;;){time(&a);b=localtime(&a);strftime(c,9,"%H:%M:%S",b);printf("%s\r",c);}}
\$\endgroup\$
0
\$\begingroup\$

TI-Basic, 40 Bytes

(In TI-BASIC, many characters are 2 byte tokens, and colons at the beginning of a line are 0 extra bytes)

:ClrHome
:Output(1,6,":
:setTmFmt(24
:While 1
:Output(1,1,getTmSrr(0
:getTime
:Output(1,7,Ans(3
:End
\$\endgroup\$
0
\$\begingroup\$

R, 41 bytes

repeat{cat(format(Sys.time(),"%T"),"\r")}

Has one trailing space (because of cat default separator being a space).
Because of the refresh rate of the R GUI, running this in the GUI will occasionally skip some seconds, but if you save it to a file and run it on the command line it will display correctly every single seconds.
Will run forever until user interrupt.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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