Build an analog clock [closed]

Write a program which displays the current system time as an analog clock, using ASCII graphics. The clock must show at least the hour and minute pointers, and must have enough resolution of at least 5 minutes.

The display can be as small and as ugly as you wish, but the shown time should be easily recognizable.

The program has to run continuously and update its status. If your system can clear the screen, use it, otherwise it's enough to repaint the clock when its state changes.

You get a -20% bonus on the character count if the clock has at least a 1 minute resolution.

• When you say analog clock do you mean the usual one or any form of analog rappresentation of time? Feb 25, 2013 at 19:08
• Extra bonus for 1 second resolution? Feb 25, 2013 at 20:10
• Is that "get a -20% bonus" for real? Shouldn't it be... positive? Nov 27, 2013 at 20:46
• @Timtech : if you really want it, I could add 20% to your character count...
– vsz
Nov 27, 2013 at 20:47
• @vsz What do you mean ;? Nov 27, 2013 at 21:13

Javascript 370 - 74 = 296

http://jsfiddle.net/wBKQ6/7/

(This only works in Chrome because I'm abusing the fact that element IDs are added to the global scope).

(function loop(){
M=Math;p=M.PI/2;z=M.pow;q=M.sqrt;d=new Date();h=(d.getHours()%12/3*p+p)%(p*4);m=(d.getMinutes()/15*p+p)%(p*4);s=(d.getSeconds()/15*p+p)%(p*4);e=49;o='';

for(r=0;r<99;r++){
for(c=0;c<99;c++){
d=q(z(r-e,2)+z(c-e,2));
a=(M.atan2(e-r,e-c)+p*4)%(p*4);
E=(d<e*.8&&M.abs(m-a)*d<.5) || (d<e*.5&&M.abs(h-a)*d<.5) || (d<e*1&&M.abs(s-a)*d<.5);
o+=d-e>0||d<1||E||(e-d<5&&a%p==0)?'●':'○';
//■□●○
}
o+='\n';
}
O.innerText=o
setTimeout(loop,1000);
})()


Golfed (370):

!function L(){p=M.PI/2;q=p*4;P=M.pow;d=new Date();s=(d.getSeconds(S=d.getMinutes(e=40))/15*p+p)%q;m=(S/15*p+p)%q;h=(d.getHours(A=M.abs)%12/3*p+S/180*p+p)%q;for(r=o='';r<81;r++,o+='\n')for(c=0;c<81;){d=M.sqrt(P(r-e,2)+P(c-e,2));a=(M.atan2(e-r,e-c++)+q)%q;o+='○●'[d-e>0|d<e*.8&A(m-a)*d<1|d<e/2&A(h-a)*d<1|d<e&A(s-a)*d<1|e-d<5&a%p==0]}O.innerText=o;setTimeout(L,9)}(M=Math)


Sample Output (much more condensed in demo):

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●○○○○○○●○○○○○○●●●●●●●●●●●●●●
●●●●●●●●●●●●○○○○○○○○●○○○○○○○○●●●●●●●●●●●●
●●●●●●●●●●○○○○○○○○○○●○○○○○○○○○○●●●●●●●●●●
●●●●●●●●○○○○○○○○○○○○●○○○○○○○○○○○○●●●●●●●●
●●●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●●●
●●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●●
●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●
●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●
●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●
●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●
●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●
●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●●○○○○○○○○○○○○○○○○○○○○○○○○○●○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○●●○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○○○○○●●○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○○○○●●○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○○○●●○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○○●○○○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○●○○○○○○○○○○○○○○○○○○●
●●●●●○○○○○○○○○○○○○○○●○○○○○○○○○○○○○○○●●●●●
●○○○○○○○○○○○○○○○○○○●○●○○○○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○●○○●○○○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○●○○○○●●○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○●○○○○○●●○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○●○○○○○○○●●○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○●●○○○○○○○○●●○○○○○○○○○○○○●
●●○○○○○○○○○○○○○○●○○○○○○○○○○○●○○○○○○○○○○●●
●●○○○○○○○○○○○○○●○○○○○○○○○○○○○●○○○○○○○○○●●
●●●○○○○○○○○○○○○●○○○○○○○○○○○○○○●○○○○○○○●●●
●●●○○○○○○○○○○○●○○○○○○○○○○○○○○○○●○○○○○○●●●
●●●●○○○○○○○○○○●○○○○○○○○○○○○○○○○○●○○○○●●●●
●●●●○○○○○○○○○●○○○○○○○○○○○○○○○○○○○●●○○●●●●
●●●●●○○○○○○○●●○○○○○○○○○○○○○○○○○○○○●●●●●●●
●●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●●
●●●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●●●
●●●●●●●●○○○○○○○○○○○○●○○○○○○○○○○○○●●●●●●●●
●●●●●●●●●●○○○○○○○○○○●○○○○○○○○○○●●●●●●●●●●
●●●●●●●●●●●●○○○○○○○○●○○○○○○○○●●●●●●●●●●●●
●●●●●●●●●●●●●●○○○○○○●○○○○○○●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

• I could probably bring the score below 263 if I remove the second hand, but I like it! Feb 26, 2013 at 0:31
• Smiley faces like to be clocks too: jsfiddle.net/wBKQ6/17/show/light Feb 26, 2013 at 17:25
• the fiddle isnt working... Oct 21, 2013 at 17:23
• @tryingToGetProgrammingStraight It's working for me in Chrome 30 Oct 21, 2013 at 18:21
• im running firefox 24.0, just tried it in chrome - it worked, i can only change my vote if you edit... Oct 21, 2013 at 19:33

Python, 328 - 65 = 263

Prints a new clock every second, with the minute hand updating every minute.

import math,time
def p(t,r):c[int(25-r*math.cos(t))][int(25+r*math.sin(t))]='*'
while 1:
time.sleep(1);c=[[' ']*50 for i in range(50)];t=time.localtime();h=t.tm_hour*6.283+t.tm_min/9.549
for i in range(999):
p(i/158.0,24);p(h,i*.02);p(h/12,i*.01)
for q in range(12):p(q/1.91,24-i*.005)
for y in range(50):print''.join(c[y])


The clocks it prints look like this (it's not as stretched in my terminal):

                  **************
****      *     ****
***         *        ***
***           *          ***
** **          *         ** **
**   *                    *   **
**    **                  **    **
*       *                  *      **
**                                  **
**                                    **
**                                      **
*                                        *
***                                      ***
* ***                                  *** *
**   **                                **   **
*                                            *
*                                            *
**                                            **
*                                              *
*   *                                          *
*   ******                                     *
*        ******                                *
*             ******                           *
*                  *****                       *
*****                   *                  ******
*                       **                     *
*                        **                    *
*                         *                    *
*                         **                   *
*                          **                  *
**                          **                **
*                           *                *
*                           *                *
**   **                                **   **
* ***                                  *** *
***                                      ***
*                                        *
**                                      **
**                                    **
**                                  **
*       *                  *       *
**    **                  **    **
**   *                    *   **
** **          *         ** **
***           *          ***
***         *        ***
****      *     ****
**************
*

• How does one read off the seconds? Feb 24, 2013 at 13:23
• One doesn't. It prints every second but only updates every minute. Feb 24, 2013 at 13:49

Mathematica 207 - 42 = 165

The ticks and hour labels are placed on the unit circle. H and M revolve around the clock center showing the whole number of completed hours and minutes, respectively. S updates its position several times each second.

Two versions are shown: a version that plots text in the Cartesian plane, and another that displays text characters in a grid.

This version plots the characters into the Cartesian plane.

d = Dynamic; t = Table; x = Text;i_~u~k_ := {Sin[2 \[Pi] i/k], Cos[2 \[Pi] i/k]};
d[{f = Date[], Clock[{1, 1}, 1]}]
Graphics[d@{t[x[".", u[i, 60]], {i, 60}],t[x[i, u[i, 12]], {i, 12}],
x["H", .7 u[f〚4〛, 12]],x["M", .8 u[f〚5〛, 60]],x["S", .9 u[f〚6〛, 60]]}]


The clock below shows the time 3:08:17.

Terminal or Grid Version: 430 316 chars (253 with bonus discount)

This version works much the same, but places the characters in a 61 x 61 cell grid rather than in the Cartesian plane. It could still be golfed a bit, but I merely wanted to show a (sloppier) terminal-like output in Mathematica.

d = Dynamic; i_~u~k_ := Round /@ (10 {Sin[2 \[Pi] (i + 3 k/4)/k],
Cos[2 \[Pi] (i + 3 k/4)/k]}); d[{f = Date[], Clock[]}]
z = Round /@ (# u[f[[#2]], #3] + 11) -> #4 &;
t = Table[( u[i, 12] + 11) -> i, {i, 12}];
d@Grid[ReplacePart[ConstantArray["", {21, 21}],
Join[z @@@ {{.9, 5, 60, "M"}, {.8, 4, 12, "H"}},
DeleteCases[Table[( u[i, 60] + 11) -> "*", {i, 60}], x_ /; MemberQ[t[[All, 1]], x[[1]]]], t]]]


The clock below displays 11:06.

Just for fun:

Here's a non-Ascii version of the analog clock. (60 chars) No external libraries were used.

Dynamic@Refresh[ClockGauge@AbsoluteTime[], UpdateInterval -> 1]


• Doesn't look like ASCII art to me. Feb 23, 2013 at 20:22
• I followed the definition given in Wikipedia: "ASCII art is a graphic design technique that uses computers for presentation and consists of pictures pieced together from the 95 printable (from a total of 128) characters defined by the ASCII Standard from 1963 and ASCII compliant character sets with proprietary extended characters (beyond the 128 characters of standard 7-bit ASCII). The term is also loosely used to refer to text based visual art in general." Feb 23, 2013 at 20:27
• Hmm. I suppose that works. I expect that vsz was expecting terminal art, though. Perhaps he can clarify. Feb 23, 2013 at 20:28

100% pure bash only! Without fork!

A finalized and upgraded version could be found there or on this page: ascii-clock for geeks. But don't use it! Read the note at end of this answer, you've been warned! Use this perl version instead!

First simple clock without second tick.

Scalable and editable:

time 2>&1 /tmp/asci-art.sh 10 10 10
. . . 12. . .
11.               . 1
.                       .
.                           .
.                               .
10                                  2
.     H                           M .
.                                       .
.                                       .
.                                       .
9                                       3
.                                       .
.                                       .
.                                       .
.                                   .
8                                   4
.                               .
.                           .
.                       .
7 .               . 5
. . . 6 . . .

real    0m0.356s
user    0m0.348s
sys     0m0.004s


Draw a 21x21 (10x2+1) clock at 10H10 in less than one second.

This accept 3 arguments: Usage: ascii-clock.sh [ray of clock] [Hour] [Min] where default ray is 12, clock drawing is 2 x ray + 1 lines height and double width because of space added to try to obtain a round shape.

If the script is called with 0 or 1 argument, it will loop to redraw each minute. Else if at least Hour (second param) is specified, It will draw only once and exit.

The H marker is located at 70% of ray and the M marker is located at 90% of ray.

No use of external binaries like date or bc for the draw!

(Thanks to @manatwork for the builtin read -t in place if /bin/sleep).

So all this is done by builtin shell commands.

It use ANSI sequence, but only for loop and to make markers bold.

#!/bin/bash
# Analog clock in Ascii-Art written in BASH V4.2 +=

RAY=${1:-12} NowH=$2 NowM=$3 sqrt() { local -a _xx=(600000 200000) local _x1=${_xx[$(($1&1))]} _x0=1
while [ $_x0 -ne$_x1 ] ;do
_x0=$_x1 [$_x0 -eq 0 ] && _x1=0000 ||
printf -v _x1 "%u" $(( (${_x0}000 + ${1}00000000000/${_x0} )/2 ))
printf -v _x1 "%.0f" ${_x1:0:${#_x1}-3}.${_x1:${#_x1}-3}
done
_x1=0000$_x1 printf${2+-v} $2 "%.3f"${_x1:0:${#_x1}-4}.${_x1:${#_x1}-4} } clksin() { #$1:moment [0-60], $2:path length,$3:variable name
local _csin=(0 104528 207912 309017 406737 500000 587785 669131
743145 809017 866025 913545 951057 978148 994522 1000000)
local xsign=1 x=$1 ysign=-1 y=$1
[ $x -gt 30 ] && xsign=-1 x=$((60-x))
[ $x -gt 15 ] && x=$((30-x))
x=00000$((RAY*1000000+xsign*${2:-10}*${_csin[$x]}))
[ $y -gt 30 ] && y=$((60-y))
[ $y -gt 15 ] && ysign=1 y=$((30-y))
y=00000$((RAY*1000000+ysign*${2:-10}*${_csin[15-$y]}))
printf ${3+-v}$3 "%.0f %.0f" \
${y:0:${#y}-6}.${y:${#y}-6} ${x:0:${#x}-6}.${x:${#x}-6}
};

MLEN=000$((900*RAY)) printf -v MLEN "%.0f"${MLEN:0:${#MLEN}-3}.${MLEN:${#MLEN}-3} HLEN=000$((700*RAY))
printf -v HLEN "%.0f" ${HLEN:0:${#HLEN}-3}.${HLEN:${#HLEN}-3}

declare -A ticks
for ((i=1;i<=12;i++));do
clksin $((5*(i%12)))$RAY tick
ticks[$tick]=$i
done

while :;do
[ "$NowM" ] || printf -v NowM "%(%M)T\n" -1 clksin${NowM#0} $MLEN NowM [ "$NowH" ] || printf -v NowH "%(%H)T\n" -1
clksin $((5*(${NowH#0}%12))) $HLEN NowH [ "$2" ] || echo -en \\e[H; # ANSI sequence for top left of console
for ((i=0;i<=2*RAY;i++));do
x=$((RAY-i)) sqrt$((RAY**2 - ${x#-}**2 )) y0 printf -v y0 "%.0f"$y0
for ((l=0;l<=2*RAY;l++));do
y=$((RAY-l)); sqrt$((RAY**2 - ${y#-}**2 )) x0 printf -v x0 "%.0f"$x0
if [ "${ticks["$i $l"]}" ] ;then printf "%-2s"${ticks["$i$l"]}
elif [ ${x#-} -eq$x0 ] || [ ${y#-} -eq$y0 ] ;then
echo -n .\
elif [ "$i$l" = "$NowM" ] ;then echo -en \\e[1mM\ \\e[0m elif [ "$i $l" = "$NowH" ] ;then
echo -en \\e[1mH\ \\e[0m
else
echo -n \ \
fi
done
echo -e \\e[K
done
echo -en \\e[J
[ "$2" ] && break # Exit if at least Hour was specified printf -v SleepS "%(%S)T" -1 read -t$((60-${SleepS#0})) foo unset NowH NowM done  This could by run as: for time in 10:10 15:00 12:30 06:00 09:15 16:40 ;do echo -$time -{,}{,}{,}
./ascii-clock.sh 5 ${time//:/ } echo -{,,,,,}{,} done | sed 's/\o033\[$$.m\|[JK]$$//g;/-$/!s/$/|/;s/-$/+/' |
column -c 80


This will produce something like:

+- 10:10 - - - - - - - + - 12:30 - - - - - - - + - 09:15 - - - - - - - +
|      . . 12. .       |       . . 12. .       |       . . 12. .       |
|    11          1     |     11    H     1     |     11          1     |
|  10              2   |   10              2   |   10              2   |
|.   H           M   . | .                   . | .                   . |
|.                   . | .                   . | .                   . |
|9                   3 | 9                   3 | 9 H               M 3 |
|.                   . | .                   . | .                   . |
|.                   . | .                   . | .                   . |
|  8               4   |   8               4   |   8               4   |
|    7           5     |     7     M     5     |     7           5     |
|      . . 6 . .       |       . . 6 . .       |       . . 6 . .       |
+- - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - +
+- 15:00 - - - - - - - + - 06:00 - - - - - - - + - 16:40 - - - - - - - +
|      . . 12. .       |       . . 12. .       |       . . 12. .       |
|    11    M     1     |     11    M     1     |     11          1     |
|  10              2   |   10              2   |   10              2   |
|.                   . | .                   . | .                   . |
|.                   . | .                   . | .                   . |
|9                 H 3 | 9                   3 | 9                   3 |
|.                   . | .                   . | .                   . |
|.                   . | .                   . | .   M           H   . |
|  8               4   |   8               4   |   8               4   |
|    7           5     |     7     H     5     |     7           5     |
|      . . 6 . .       |       . . 6 . .       |       . . 6 . .       |
+- - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - +


Or could be run as:

xterm -geom 86x44 -bg black -fg grey -e ./ascii-clock.sh 21 &

xterm -geom 103x52 -fn nil2 -bg black -fg grey -e ./ascii-clock.sh 25 &

gnome-terminal --geometry 103x52 --zoom .5 -e "./ascii-clock.sh 25" &


Alternative: With full path drawing:

#!/bin/bash
# Analog clock in Ascii-Art written in BASH V4.2 +=

RAY=${1:-12} NowH=$2 NowM=$3 sqrt() { local -a _xx=(600000 200000) local _x1=${_xx[$(($1&1))]} _x0=1
while [ $_x0 -ne$_x1 ] ;do
_x0=$_x1 [$_x0 -eq 0 ] && _x1=0000 ||
printf -v _x1 "%u" $(( (${_x0}000 + ${1}00000000000/${_x0} )/2 ))
printf -v _x1 "%.0f" ${_x1:0:${#_x1}-3}.${_x1:${#_x1}-3}
done
_x1=0000$_x1 printf${2+-v} $2 "%.3f"${_x1:0:${#_x1}-4}.${_x1:${#_x1}-4} } clksin() { #$1:moment [0-60], $2:path length,$3:variable name
local _csin=(0 104528 207912 309017 406737 500000 587785 669131
743145 809017 866025 913545 951057 978148 994522 1000000)
local xsign=1 x=$1 ysign=-1 y=$1
[ $x -gt 30 ] && xsign=-1 x=$((60-x))
[ $x -gt 15 ] && x=$((30-x))
x=00000$((RAY*1000000+xsign*${2:-10}*${_csin[$x]}))
[ $y -gt 30 ] && y=$((60-y))
[ $y -gt 15 ] && ysign=1 y=$((30-y))
y=00000$((RAY*1000000+ysign*${2:-10}*${_csin[15-$y]}))
printf ${3+-v}$3 "%.0f %.0f" \
${y:0:${#y}-6}.${y:${#y}-6} ${x:0:${#x}-6}.${x:${#x}-6}
};

MLEN=000$((900*RAY)) printf -v MLEN "%.0f"${MLEN:0:${#MLEN}-3}.${MLEN:${#MLEN}-3} HLEN=000$((700*RAY))
printf -v HLEN "%.0f" ${HLEN:0:${#HLEN}-3}.${HLEN:${#HLEN}-3}

declare -A ticks
for ((i=1;i<=12;i++));do
clksin $((5*(i%12)))$RAY tick
ticks[$tick]=$i
done

while :;do
[ "$NowM" ] || printf -v NowM "%(%M)T\n" -1 unset MPath declare -A MPath for ((i=1;i<=MLEN;i++));do clksin${NowM#0} $i tick MPath[$tick]=M
done
[ "$NowH" ] || printf -v NowH "%(%H)T\n" -1 unset HPath declare -A HPath for ((i=1;i<=HLEN;i++));do clksin$((5*(${NowH#0}%12)))$i tick
HPath[$tick]=H done [ "$2" ] || echo -en \\e[H; # ANSI sequence for top left of console
for ((i=0;i<=2*RAY;i++));do
x=$((RAY-i)) sqrt$((RAY**2 - ${x#-}**2 )) y0 printf -v y0 "%.0f"$y0
for ((l=0;l<=2*RAY;l++));do
y=$((RAY-l)); sqrt$((RAY**2 - ${y#-}**2 )) x0 printf -v x0 "%.0f"$x0
if [ "${MPath["$i $l"]}" ] ;then echo -en \\e[1m${MPath["$i$l"]}\ \\e[0m
elif [ "${HPath["$i $l"]}" ] ;then echo -en \\e[1m${HPath["$i$l"]}\ \\e[0m
elif [ "${ticks["$i $l"]}" ] ;then printf "%-2s"${ticks["$i$l"]}
elif [ ${x#-} -eq$x0 ] || [ ${y#-} -eq$y0 ] ;then
echo -n .\
else
echo -n \ \
fi
done
echo -e \\e[K
done
echo -en \\e[J
[ "$2" ] && break # Exit if at least Hour was specified printf -v SleepS "%(%S)T" -1 read -t$((60-${SleepS#0})) foo unset NowH NowM done  could produce: +- 10:10 - - - - - - - + - 12:30 - - - - - - - + - 09:15 - - - - - - - + | . . 12. . | . . 12. . | . . 12. . | | 11 1 | 11 H 1 | 11 1 | | 10 2 | 10 H 2 | 10 2 | |. H M . | . H . | . . | |. H H H M M M . | . H . | . . | |9 3 | 9 3 | 9 H H H H M M M M 3 | |. . | . M . | . . | |. . | . M . | . . | | 8 4 | 8 M 4 | 8 4 | | 7 5 | 7 M 5 | 7 5 | | . . 6 . . | . . 6 . . | . . 6 . . | +- - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - + +- 15:00 - - - - - - - + - 06:00 - - - - - - - + - 16:40 - - - - - - - + | . . 12. . | . . 12. . | . . 12. . | | 11 M 1 | 11 M 1 | 11 1 | | 10 M 2 | 10 M 2 | 10 2 | |. M . | . M . | . . | |. M . | . M . | . . | |9 H H H H 3 | 9 3 | 9 3 | |. . | . H . | . M M M H H H . | |. . | . H . | . M H . | | 8 4 | 8 H 4 | 8 4 | | 7 5 | 7 H 5 | 7 5 | | . . 6 . . | . . 6 . . | . . 6 . . | +- - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - +  or  . . . . 12. . . . . . . . . . . . . . . 11 1 . . . . . . . . . . . . . 10 2 . M . . M M M . . H M . . H H M M . . H M . . H H H M M M . . H M . . H H M M . . H M . 9 H M 3 . . . . . . . . . . . . . . . . . . 8 4 . . . . . . . . . . . . . 7 5 . . . . . . . . . . . . . . . 6 . . . .  Last version with Seconds ticks rendering and nanosleep to sync. This work only on recent Linux, as this use /proc/timer_list to compute fraction of second to sleep between each refresh. #!/bin/bash # Analog clock in Ascii-Art written in BASH V4.2 += RAY=${1:-12} NowH=$2 NowM=$3

# Hires Sleep Until
# there is a need to store offset in a static var

mapfile  </proc/timer_list _timer_list
for ((_i=0;_i<${#_timer_list[@]};_i++));do [[${_timer_list[_i]} =~ ^now ]] && TIMER_LIST_SKIP=$_i [[${_timer_list[_i]} =~ offset:.*[1-9] ]] && \
TIMER_LIST_OFFSET=${_timer_list[_i]//[a-z.: ]} && \ break done unset _i _timer_list readonly TIMER_LIST_OFFSET TIMER_LIST_SKIP sleepUntilHires() { local slp tzoff now quiet=false nsnow nsslp local hms=(${1//:/ })
mapfile -n 1 -s $TIMER_LIST_SKIP nsnow </proc/timer_list printf -v now '%(%s)T' -1 printf -v tzoff '%(%z)T\n'$now
nsnow=$((${nsnow//[a-z ]}+TIMER_LIST_OFFSET))
nsslp=$((2000000000-10#${nsnow:${#nsnow}-9})) tzoff=$((0${tzoff:0:1}(3600*${tzoff:1:2}+60*${tzoff:3:2}))) slp=$(( ( 86400 + ( now - now%86400 ) +
10#$hms*3600+10#${hms[1]}*60+10#${hms[2]} - tzoff - now - 1 ) % 86400)).${nsslp:1}
read -t $slp foo } sqrt() { local -a _xx=(600000 200000) local _x1=${_xx[$(($1&1))]} _x0=1
while [ $_x0 -ne$_x1 ] ;do
_x0=$_x1 [$_x0 -eq 0 ] && _x1=0000 ||
printf -v _x1 "%u" $(( (${_x0}000 + ${1}00000000000/${_x0} )/2 ))
printf -v _x1 "%.0f" ${_x1:0:${#_x1}-3}.${_x1:${#_x1}-3}
done
_x1=0000$_x1 printf${2+-v} $2 "%.3f"${_x1:0:${#_x1}-4}.${_x1:${#_x1}-4} } clksin() { #$1:moment [0-60], $2:path length,$3:variable name
local _csin=(0 104528 207912 309017 406737 500000 587785 669131
743145 809017 866025 913545 951057 978148 994522 1000000)
local xsign=1 x=$1 ysign=-1 y=$1
[ $x -gt 30 ] && xsign=-1 x=$((60-x))
[ $x -gt 15 ] && x=$((30-x))
x=00000$((RAY*1000000+xsign*${2:-10}*${_csin[$x]}))
[ $y -gt 30 ] && y=$((60-y))
[ $y -gt 15 ] && ysign=1 y=$((30-y))
y=00000$((RAY*1000000+ysign*${2:-10}*${_csin[15-$y]}))
printf ${3+-v}$3 "%.0f %.0f" \
${y:0:${#y}-6}.${y:${#y}-6} ${x:0:${#x}-6}.${x:${#x}-6}
};

SLEN=000$((870*RAY)) printf -v SLEN "%.0f"${SLEN:0:${#SLEN}-3}.${SLEN:${#SLEN}-3} MLEN=000$((780*RAY))
printf -v MLEN "%.0f" ${MLEN:0:${#MLEN}-3}.${MLEN:${#MLEN}-3}
HLEN=000$((650*RAY)) printf -v HLEN "%.0f"${HLEN:0:${#HLEN}-3}.${HLEN:${#HLEN}-3} declare -A ticks for ((i=1;i<=12;i++));do clksin$((5*(i%12))) $RAY tick ticks[$tick]=$i done while :;do [ "$NowM" ] || printf -v NowM "%(%M)T\n" -1
unset MPath
declare -A MPath
for ((i=1;i<=MLEN;i++));do
clksin ${NowM#0}$i tick
MPath[$tick]=M done [ "$NowH" ] || printf -v NowH "%(%H)T\n" -1
unset HPath
declare -A HPath
for ((i=1;i<=HLEN;i++));do
clksin $((5*(${NowH#0}%12))) $i tick HPath[$tick]=H
done
printf -v NowS "%(%S)T\n" -1
clksin ${NowS#0}$SLEN STick

[ "$2" ] || echo -en \\e[H; # ANSI sequence for top left of console for ((i=0;i<=2*RAY;i++));do x=$((RAY-i))
sqrt $((RAY**2 -${x#-}**2 )) y0
printf -v y0 "%.0f" $y0 for ((l=0;l<=2*RAY;l++));do y=$((RAY-l));
sqrt $((RAY**2 -${y#-}**2 )) x0
printf -v x0 "%.0f" $x0 if [ "$i $l" = "$STick" ] ;then
echo -en \\e[1ms\ \\e[0m
elif [ "${MPath["$i $l"]}" ] ;then echo -en \\e[1m${MPath["$i$l"]}\ \\e[0m
elif [ "${HPath["$i $l"]}" ] ;then echo -en \\e[1m${HPath["$i$l"]}\ \\e[0m
elif [ "${ticks["$i $l"]}" ] ;then printf "%-2s"${ticks["$i$l"]}
elif [ ${x#-} -eq$x0 ] || [ ${y#-} -eq$y0 ] ;then
echo -n .\
else
echo -n \ \
fi
done
echo -e \\e[K
done
echo -en \\e[J
[ "$2" ] && break # Exit if at least Hour was specified printf -v SleepS "%(%s)T" -1 printf -v SleepS "%(%T)T"$((1+SleepS))
sleepUntilHires $SleepS unset NowH NowM done  More obfuscated version (2702 bytes): As requested by @manatwork, there is a more golfed version. This version is colorized and present digital time on corners. #!/bin/bash W=/proc;J=${1:-12} B=$2 A=$3 LANG=C R=$W/timer_list;if [ -f$R ];then Q=10
mapfile <$R e;for ((P=0;P<${#e[@]};P++));do ((Q+=${#e[P]}));[[${e[P]} =~ ^now
]]&&U=$Q;[[${e[P]} =~ offset:.*[1-9] ]]&&a=${e[P]//[a-z.: ]}&&break;done;c(){ local q p;read -N$U q <$R;q=${q%% nse*};q=$[${q##* }+a];p=$[2000000000-10#${q:
${#q}-9}];read -t .${p:1} M;};else c(){ local H;read -d\  H < $W/upti*;H=$[200
-10#${H#*.}];read -t .${H:1} M;};fi;u(){ local E=({6,2}00000) F=${E[$1&1]} G=1
while [ $G -ne$F ];do G=$F;[$G -eq 0 ]&&F=0000||printf -v F "%u" $(((${G}000
+${1}00000000000/${G})/2));printf -v F "%.0f" ${F:0:${#F}-3}.${F:${#F}-3};done
F=0000$F;printf -v$2 "%.3f" ${F:0:${#F}-4}.${F:${#F}-4};};g(){ local t=($[7#0 ] 104528 207912 309017 406737 500000 587785 669131 743145 809017 866025 913545 951057 978148 994522 1000000) j=1 x=$1 h=-1 y=$1;[$x -gt 30 ]&&j=-1 x=$[60-x] ((x>15))&&x=$[30-x];x=00000$[J*1000000+j*${2:-10}*${t[$x]}];((y>30))&&y=$[60-y ];((y>15))&&h=1 y=$[30-y];y=00000$[J*1000000+h*${2:-10}*${t[15-y]}];printf -v\$3 "%.0f %.0f" ${y:0:${#y}-6}.${y:${#y}-6} ${x:0:${#x}-6}.${x:${#x}-6};};v=000
v+=$((870 *J));printf -v v "%.0f"${v:0:${#v}-3}.${v:${#v}-3};C=000$((780*J));
printf -v C "%.0f" ${C:0:${#C}-3}.${C:${#C}-3};D=000$[650*J];printf -v D %.f \${D:0:${#D}-3}.${D:${#D}-3};declare -A m;for ((i=1;i<=12;i++));do g$[5*(i%12)
] $J w;m[$w]=$i;done;printf -v T "\e[1m%s\e[0m " . + \* o O;T=(${T});m["${J: \ }$J"]=${T} ;printf "\e[?25l\e[H\e[J";trap "printf '\e[?12l\e[?25h\e[$((2*J +3
))H\e[J';exit" 0 1 2 3 6 9 15; printf -v S "\\e[1;%dH%%(%%H)T\\e[%dH%%(%%M${Z: })T\\e[%d;%dH%%(%%S)T"$[4*J] $[2*J+1]$[2*J+1] $[4*J];declare -A V;V["$[2 * J
] $[2*$J]"]="  ";while :;do [ "$A" ]||printf -v A "%(%M)T" -1;unset r;declare\ -A r;for ((i=1;i<=C;i++));do g${A#0} $i w;r[$w]=M;done;[ "$B" ]||printf -v \ B "%(%H)T" -1;unset s;declare -A s;for ((i=1;i<=D;i++));do g$((5*( ${B#0}%12) ))$i w;s[$w]=H;done;printf -v z "%(%S)T" -1;g${z#0} $v n;[ "$2" ]||echo -en\
\\e[H;for ((i=0;i<=2*J;i++));do x=$[J-i];u$[J*J-${x#-}**2] N;printf -v N${Z:
} %.f $N;for ((l=0;l<=2*J;l++));do y=$[J-l];u $[J*J-${y#-}**2] O;printf -v O \
%.f $O;c=" ";if [ "$i $l" = "$n" ];then c=$'\e[36;1ms \e[m';elif [ "${r["${i: }$l"]}" ] ;then c=$'\e[32;1m'${r["$i$l"]}$' \e[0m';elif [ "${s["$i$l"]}" ];
then c=$'\e[34;1m'${s["$i$l"]}$' \e[0m';elif [ "${m["$i$l"]}" ];then printf\
-v c "%-2s" "${m["$i $l"]}";elif [${x#-} -eq $O ] || [${y#-} -eq $N ] ;then c=.\ ;else c=" ";fi;[ "$c" != "${V["$i $l"]}" ]&& V["$i $l"]="$c" && printf \
"\e[%s;%sH%-2s" $((1+i))$[1+l*2] "$c";done;done;[ "$2" ] &&break;printf "${Z: }\e[H\e[7mS\e[0m";c;printf "\e[H$S" -1 -1 -1;m["$J$J"]=${T[$[10#$z%${#T[@]}]
]};unset B A;done


Note: Don't use this anyway!

As this is programm and as bash is not a programmation language, this is not well to use for a while.

There is a little demo of memory consumption in only 5 hours, with a drawing of 7 character length ray:

$ascii-clock.sh 7 After PMem PCpu Mem 0'30" 0.0% 21.6% 12.98M 10'30" 1.0% 20.9% 48.91M 1h 0'30" 5.6% 20.8% 228.63M 2h 0'31" 11.2% 20.8% 444.25M 3h 0'32" 16.8% 20.8% 659.91M 5h 0'00" 27.9% 20.8% 1.064G  The main advantage of this that when I need memory, I just have to kill the clock. ( Nota: I've merged this, the perl version and a version of same on ascii-clock for geeks ;-) • @manatwork Why? It's analog, run continuously and make the draw in less than 1 second... What do I mis readed? Oct 25, 2013 at 17:31 • Oops. My mistake. First I tried it on bash 4.1. On 4.2 indeed runs continuously and not requires the command line parameters. Oct 25, 2013 at 17:51 • There is no size limit on requirement. And doing this in pure bash is a real challenge! Doing this shorther without fork seem not simple (if even possible). Oct 25, 2013 at 17:54 • Right, there is no size limit and accomplishing it with pure bash is a demonstration of great skill. (/me takes of his hat and clicks the upvote link) But those 2529 characters could still be reduced in the spirit of code-golf challenges: “Code-golf is a competition to solve a particular problem in the fewest bytes of source code.” Oct 25, 2013 at 18:04 • @manatwork There is now a more golfed version, (not shorter: from 2529bytes, this version is now 2702 bytes, but has new features) Jan 4, 2016 at 23:07 Python 2 - 207 import time as T while 1:t=T.localtime();m=t.tm_min/5;l=[12]+range(1,12);l[m]='';l[t.tm_hour%12]='H';l[m]+='M';a=' %s\n';print(a+('%s'+a)*5+a)%tuple(str(l[x])for x in[0,11,1,10,2,9,3,8,4,7,5,6]);T.sleep(9)  It is very ugly, but readable. Prints every 9 sec (you can change to 1 sec if you prefer), updates every 5 min. I don't have much experience with code golfing in python so I expect it can be improved. Example output:  12 11 1 10 2 9 M 8 4 7 H 6  • Your clock appears to be a Dali. Bravo! Feb 24, 2013 at 21:40 Perl 5 x 65 = 325 - 65(20%) = 260 chars!! Clean, circular, with a second tick and updated every seconds. perl -E '$r=11;$p=atan2(1,1)/7.5;sub c{($A,$R,$C)=@_;$a[$r-$R*cos($A*$p)][$r+$R*sin($A*$p)]=$C." "x($C!~/../)};while(::){@a=map{[map{" "}( 0..$r*2)]}(0..$r*2);map{c$_*5,$r,$_}(1..12);@t=localtime;for$i(qw |H:6:5:2 M:8:1:1 s:9:1:0 |){($S,$P,$F,$T)=split":",$i;map{c$F*$t[
$T],$_,$S}(do{$T?1:$P}/10*$r..$P/10*$r)};map{say@{$_}}@a;sleep 1} '  On a 24 lines console look good (It's 00:12:56):  12 11 1 s 10 H 2 H H H M M H M M M M M M 9 3 8 4 7 5 6  And there is a colored, nicer and smarter version: #! /usr/bin/perl use Time::HiRes qw|sleep time| ;$h=11;$h=$ARGV[0]if$ARGV[0];$P=atan2
(1,1)/7.5;$V =4*$h; $v= 2*$h+ 1;@r=(0..2*$v) ;sub p{printf @_ }sub b{ return"\e[1m" .pop."\e[0m" };$              |=p"\e[?25".
"l\e[H\e[" ."J"            ;$SIG{ 'INT'}=sub {p"\e[?1" ."2l" ."\e" ."[?25h". "\e[%dH" ."\e" ."[J" ,$v+2;exit;
};@z=map                                                  {[map{" "
}@r] }(0                                                     ..2*$v); @Z=map{[@ {$z[$_]}]}@r ;sub c{($A,$r ,$s                                       )=@_;$z[$h-$r*cos ($A*$P) +.5 ][$h+$r*sin($A*$P)+.5]=$s;}
for$x( 0..$h) {$y= int(sqrt($h**2     -$x**2 )+.5);$         z[$h-$x][$h-$                  y]=".";$z[$h+$x ][$h-$y ]=".";$z[$h-$x][$h+$           y]=".";$z[$h+$x ][$h+$y]=".";$z[$h-$y][$h-$    x]=".";$z[$h+$y ][$h-$x ]=".";$z[$h-$y][$h+$x]=".";$z[$h+                    $y][$h
+$x]="."};map{ c$_*5,$h,b$_}(1..12);                @R=map{[@{$z[$_]}]}@r;while                (::){@t=localtime;                   p"\e[H\e[1;${V}H%0" ."2d\e[${v}H%02d\e"                        ."[${v };${ V                         }H%02d",$t[2],$t[                         1],$t[ 0];@z= map{[ @{$R[                         $_]}]}( 0..2*$                                                                 v);for
$i('H:' .'65:5:' .'2:4', "" x1 .'M:78:' ."1:1" .":2", "s:8". "7:1:" .'0:6'){($                                                  l,$p,$F,$u,$
c)=split                                                    ":",$i;map {c$F*$t [$u],$_ ,b("\e[" ."3${c}m$l")}(do{$u     ?1:$p} / 100*$h..$p /100*$h);}  $z[$            h][            $h]= b((".","+" ,"*","o","O") [$t             [0]%5]);for$x (@r){for$y(@r           ){$Z[$x][$y]ne$z
[$x][$y]?p"\e[%d;%dH".$z [$x] [$y],$x+1,2*$y+1:''};};@Z=map{[@{$z[$_]}]}@r;$n=1-$1 if time=~/(\..*)$/;p"\e[H\e[7m"
."S\e[0m";sleep$n}  This version is strongly linked to this other answer, with the main advantage: You could run this quietly, for a while! So you could find an upgraded version there or on this ascii-clock for geeks web page. As a demonstration that doing approx same in require less resources: $ ascii-clock.pl 7

After     PMem   PCpu      Mem
0' 0"  0.0%   0.0%    23.5M
10'30"  0.0%   0.0%    23.5M
1h 0' 0"  0.0%   0.0%    23.5M
2h 0' 0"  0.0%   0.0%    23.5M


for approx same features:

• wait for begin of each seconds for doing a refresh
• draw with color and bold attributes
• draw full circle with dots, hour tick, hour and minutes full path and a s dot for second handler.
• draw digital clock prompting hour at top right, minutes at bottom left and seconds at bottom right.
• prompt a S at top left, when sleeping (look for difference with version)

Plus

• The upgraded version authorize -a argument for drawing hour and minute path in fraction (11h59 place hour path approx at 12h).

One more another perl version!!!

Using the following (beautiful) picture:

You could simply:

curl https://i.stack.imgur.com/xvbHP.png |
perl -e 'use GD;GD::Image->trueColor(1);$i=GD::Image->newFromPng( STDIN);my($x,$y)=$i->getBounds();for my$k(0..$x-1){for my$l(0 ..$y-1){$_.=pack"UUU",$i->rgb($i->getPixel($k,$l))};};eval'  or, with arguments (You have to add -s switch to perl command): wget -O - http://fhauri.cartou.ch/ascii-clock/ascii-clock.png | perl -se 'use GD;GD::Image->trueColor(1);$i=GD::Image->newFromPng(
STDIN);my($x,$y)=$i->getBounds();for my$k(0..$x-1){for my$l(0
..$y-1){$_.=pack"UUU",$i->rgb($i->getPixel($k,$l))};};eval' -- -a 18


This require having gd2-perl installed! (You could replace curl by wget -O - ;-)

( Note: This picture is near 1.5Kb. I've built another same picture, but 900 bytes length. You may find this picture, well as a version of same at ascii-clock for geeks :-)

• In last sample, I (strongly recommend/) suggest to replace eval by print in order before running unknown downloaded code ;-) Nov 24, 2013 at 23:59

Tcl, 288

while 1 {scan [clock format [clock seconds] -format %k-%M] %d-%d h m
regsub -all \ +|. "oaosocowoeouooovoioxozom   r    n\n" \ {&} p
lset p [set h [expr $h%12*2]] h lset p [set m [expr$m/5*2]] [expr $h-$m?"m":"x"]
puts [string map /\ $p {rr/nrzmrann xrrr snnimrrrcnn vrrr wnnromrenrru}]}  Ok, here some explaination: • while 1 {...} - Ok, forget the explaination. • regsub -all \ +|. "oaosocowoeouooovoioxozom r n\n" \ {&} p replaces +|. with _{\0} and stores the result in p. p is actually a messed up dictionary where the first key is missing (or just a list with an odd number of elements). • lset p [set h [expr$h%12*2]] h sets the hour in the replacement list
• lset p [set m [expr $m/5*2]] [expr$h-$m?"m":"x"] sets the minute. if hour and minute is the same, use x instead. • string map /\$p {rr/nrzmrann xrrr snnimrrrcnn vrrr wnnromrenrru} /\ $p is equal to "/$p", so I add the first key (/). After that I replace every occurence of a key in rr/nrzmrann xrrr snnimrrrcnn vrrr wnnromrenrru with it's value.

The usual map is

/ o a o s o c o w o e o u o o o v o i o x o z o m {   } r {    } n {
}


(Read as "Replace / with o, replace a with o... replace m with ___ (that should be spaces))

I repace an o with h and an other with m, m, r and n are just to shoren the output string (I replaced several spaces with one of them, also \n with n). I add the first element later so I can use h*2 instead h*2+1 for the index that I replace. (saves 2 chars)

Some notes:

• A list in Tcl uses whitespace as delimiter, if an element contains whilespace, you have to enclose it with {}. Ok, it's a little bit more complex e.g. you could escape the whitespace with a \, but such details are documented somewhere else.
• A dict in Tcl is just a list with an even number of elements: key1 value1 key2 value2
• You can treat a list as string or a string as list. Will work if the string is a valid list. Free serialization!
• When it is 14:23, it displays wrongly the hour pointer on 13:00 instead of 14:00! — tutorialspoint.com/… Jun 20, 2017 at 13:30
• Well, Tcl knows about timezones. Setup your environment correctly. (looks like tutorialspoints uses UTC) Jun 21, 2017 at 0:51
• Oops, sorry. May be I am in a different time setup. Here it is Portugal, we use GMT, and being in the summer, hour is +1. So, get my upvote. Jun 21, 2017 at 9:32

Javascript 2169 - 434 = 1735

Ok, it's a lot, but they are fine and work same as my previous variant in previous posts (bash and perl).

This version is more obfuscated than the one you may find on my ascii-clock for geeks

var x='<div class="m">&nbsp;M</div>',v='<div class="s">&nbsp;s</div>',w='&nbsp;'
,r=10,q,w='&nbsp;',y='<div class="h">&nbsp;H</div>',f=new Object();function d(){
q=document.getElementById("asciiclock");var t=document.location.toString().match
(/[?]([0-9]+)/);if (t!=null) r=t[1]*1.0;a();b();}function m(e){r=e;a();}function
a(){f=[];for (var i=1;r>i;i++){var u=Math.round(Math.sqrt(Math.pow(r,2)-Math.pow
(r-i,2)));f[(2*r-i)+"x"+(r+u)]=w+".";f[(i)+"x"+(r+u)]=w+".";f[(2*r-i)+"x"+(r-u)]
=w+".";f[(i)+"x"+(r-u)]=w+".";f[(r+u)+"x"+(2*r-i)]=w+".";f[(r+u)+"x"+(i)]=w+".";
f[(r-u)+"x"+(2*r-i)]=w+".";f[(r-u)+"x"+(i)]=w+".";}for(var i=1;13>i;i++){f[Math.
round(r+r*Math.sin(Math.PI/6*i-Math.PI/2))+"x"+Math.round(r+r*Math.cos(Math.PI/6
*i-Math.PI/2))]='<div class="t">'+(i<10?w+i:i)+'</div>';}}function b(){var z='';
var s=new Date(), o=s.getMinutes()*1.0+1.0*s.getSeconds()/60,p=s.getHours()*1.0+
1.0*o/60,n=s.getSeconds()*1.0,k=s.getHours();if (k<10) k=w+k;var j=s.getMinutes(
);if (j<10) j=w+j;var h=s.getSeconds();if (h<10)h=w+h;var g=new Object();for(var
i=1;r*.78>=i;i++) {g[Math.round(r+i*Math.sin (Math.PI/30*o-Math.PI/2))+"x"+Math.
round(r+i*Math.cos(Math.PI/30*o-Math.PI/2))]=x;};for (var i=1;r*.62 >=i;i++) {g[
Math.round(r+i*Math.sin(Math.PI/6*p-Math.PI/2))+"x"+Math.round(r+i*Math.cos(Math
.PI/6*p-Math.PI/2))]=y;};g[Math.round(r+.87*r*Math.sin(Math.PI/30*n-Math.PI/2))+
"x"+Math.round(r+.87*r*Math.cos(Math.PI/30*n-Math.PI/2))]=v;for (var i=0;2*r>=i;
i++){for(var l=0;2*r>=l;l++){if((i==r)&&(l==i)){z+=w+'<div class="t">'+['.','+',
'*','o','O'][n%5]+'</div>';}else if(f[i+"x"+l]!=undefined){z+=f[i+"x"+l]}else if
(g[i+"x"+l]!=undefined){z+=g[i+"x"+l];}else if(l==2*r){if(i==0){z+=w+'<div clas'
+'s="t">'+k+'</div>';}else if(i==l){z+=w+'<div class="t">'+h+'</div>';}else{z+=w
+w;};}else if(l==0){if(i==2*r){z+='<div class="t">'+j+'</div>';}else if(i==0){z=
'<div class="r">S</div>'+w;}else{z+=w+w}}else{z+=w+w}};z+='<br />';};q.innerHTML
=z;window.setTimeout(b,1000-new Date().getMilliseconds());};function c(){window.
setTimeout(b,0);q.innerHTML=w+q.innerHTML.substring (22);q.setAttribute('style',
'display:none');q.setAttribute('style',null)};window.onload=d;
.asciiclock { margin: 3em 0px 0px 0px;padding: 2px 4px 2px 3px; font-size: .5em;
display:inline-block;font-family:mono,monospace,courier;background:rgba(0,0,0,.7
);color: #888;}.asciiclock div{ display:inline-block;font-weight:bold;}.h{color:
#46F;}.m{color:#0F0;}.s{color:#0FF;}.r{color:#000;background:#aaa;}.t{color:#aaa
;}pre{display:inline-block;}
<head><title>Ascii-clock</title><script type="text/javascript" src="ascii-clock.js"
</style></head><body><div id="asciiclock" class="asciiclock"></div></body>

Python, 259 - 52 = 207

from time import*
from math import*
g=[[' ']*61 for _ in[0]*31]
while 1:
t=localtime()
for x in range(60):a=pi*x/30-pi/2;g[15+int(15*sin(a))][30+int(30*cos(a))]='m'if x==t.tm_min else'h'if x==t.tm_hour%12*5 else'-'if x%5 else'#'
for r in g:print''.join(r)


Sample output:

                              #
-  -  -     -  -  -
-                       -
-  h                           #  -
-                                       -
-                                           -

m                                               -
#                                                 #
-                                                     -

-                                                       -
-                                                         -

-                                                         -
#                                                           #
-                                                         -

-                                                         -
-                                                       -

-                                                     -
#                                                 #
-                                               -

-                                           -
-                                       -
-  #                           #  -
-                       -
-  -  -     -  -  -
#


Ruby: 230 228 characters - 46 = 182

M=Math
P=M::PI
x=->n,m=60,r,c{$><<"^[[%d;%dH%s\n"%[M.sin(n*P*2/m-P/2)*r+12,M.cos(n*P*2/m-P/2)*r*2+24,c]} while t=Time.now$><<"^[[2J"
1.upto(12){|i|x[i,12,11,i]}
x[t.hour*5+t.min/12,8,?H]
x[t.min,9,?M]
x[t.sec,10,?S]
sleep 0.1
end


(Note: ^[ is a single character.)

Sample run (at 21:19:33):

                      12
11                     1

10                                     2

H
9                                           3

M

8                                      4

7   S                 5

6


“As ugly as you wish” version: 191 181 characters - 36 = 145

(Smaller size, lower precision, no seconds, identical radius, horrible flickering.)

x=->n,m=60,c{$><<"^[[%d;%dH%s\n"%[Math.sin(n*6.3/m-1.6)*8+9,Math.cos(n*6.3/m-1.6)*8+9,c]} while t=Time.now$><<"^[[2J"
1.upto(12){|i|x[i,12,i]}
x[t.hour*5+t.min/12,?H]
x[t.min,?M]
end


Sample run (at 21:19):

       12  1
11

2
10

H              3
9

M
8

5
7   6


Trigonometry-less version: 130 125 characters (no bonus)

(Inspired by Johannes Kuhn's Tcl solution. Not sure how much, as I still not deciphered his code.)

while t=Time.now
puts"^[[2J  k l a
j\tb
i\tc
h\td
g f e".tr((t.min/5+96).chr,?M).tr(((t.hour-1)%12+97).chr,?H).tr("a-l",?*)
end


Sample run (at 21:19):

  * * *
*       *
H       M
*       *
* * *

• I added an explanation to my solution. Just ask if something is not clear. Oct 24, 2013 at 20:21
• Thank you @JohannesKuhn, I already read it. For me the mystery is not the syntax, but the encoding of those string values. Oct 25, 2013 at 8:18
• On that last one I'm getting syntax errors. Nov 27, 2013 at 20:55
• @Timtech, is it “tr': can't convert Fixnum into String (TypeError)”? Now that you mentioned the error I dug for a version 1.8.7 and received the above error of that. Works fine on 1.9.2 and 1.9.3. Seems that ?M was interpreted as Fixnum in older versions and only later was changed to String. Nov 28, 2013 at 9:50

HTML & JS: 397 - 20% = 317.6 characters

My first iteration. I'm not very pleased with it, but it does work and it does show the time in a very clear way.

<canvas id=c width=198 height=198></canvas><script>c=document.getElementById("c")
.getContext("2d");c.r=c.rotate;c.c=c.clearRect;c.translate(99,99);for(i=0;i<60;i++)
{c.fillRect(89,-1,i%5?3:9,5);c.r(p=Math.PI/30);}setInterval(function(){n=new Date();
h=n.getHours()*5*p;c.beginPath();c.arc(0,0,86,0,7);c.fill();c.r(m=n.getMinutes()*p);
c.c(-2,-3,4,-80);c.r(h-m);c.c(-2,-3,4,-50);c.r(-h);},5);</script>

• Cute, but not exactly what we call ascii-art. Dec 3, 2013 at 8:03

Ti-Basic 84, 587 - 20% = 469.6

:Xmax/2→Xmax:Ymax/2→Ymax:-Xmax→Xmin:-Ymax→Ymin:Degree:15→H:20→M:18→S::Circle(0,0,30):For(X,1,12)::Text(28-int(cos(X*30)*25),46+int(sin(30*X)*25),X):End:{0,0,0}→LANG:While getKey=0::getTime→LTIME::If LTIME(3)≠LANG(3)/6:Line(0,0,sin(LANG(3))*S,cos(LANG(3))*S,0)::If LTIME(2)≠LANG(2)/6:Then:::Line(0,0,sin(LANG(2))*M,cos(LANG(2))*M,0):::Line(0,0,sin(LANG(1))*H,cos(LANG(1))*H,0)::End::"SET ANGS::LTIME(1)*30+LTIME(2)/2→LANG(1)::LTIME(2)*6→LANG(2)::LTIME(3)*6→LANG(3)::Line(0,0,sin(LANG(1))*H,cos(LANG(1))*H::Line(0,0,sin(LANG(2))*M,cos(LANG(2))*M::Line(0,0,sin(LANG(3))*S,cos(LANG(3))*S:End


Its output is very pretty and detailed.

C, 554 Bytes, Updates roughly once per second.

#include <time.h>
#include <math.h>
int r=25,i,q,c,i,q,b[999];void v(float a,int f,int m){b[(r/2+(int)(sin(a)*f))*r+r/2+(int)(cos(a)*f)]=m;}void main(){float a,p=6.28,z=1.57,h,m,s;for(;;){time_t u=time(0);struct tm*l=localtime(&u);s=l->tm_sec;m=l->tm_min+s/60.;h=l->tm_hour+m/60.;system("@cls||clear");q=r*r;c=r/2;memset(b,32,q*4);for(i=0,a=p;a>0;a-=0.52,i++)v(a,c,i%3?46:i%6?124:45);v(0,0,79);v(p*s/60.-z,c-4,83);v(p*m/60.-z,c-5,77);v(p*h/12.-z,c-6,72);for(i=0;i<q;i++){c=b[i];putchar(c);if(i%r==r-1)putchar(10);}for(c=0;c<2000000;c++)hypot(3,.4);}}


Result:

           |
.          .

.
S    .

H

-          O          -

M
.
.

.          .
|
`
• 449 bytes May 13, 2019 at 5:07