g | x | w | all
Bytes Lang Time Link
255Python 2250118T042709ZLucenapo
195JavaScript ES8250113T192321ZArnauld
119Ruby250113T210943ZLevel Ri
074Charcoal250113T230039ZNeil

Python 2, 255 bytes

from math import*
C=[32*[' ']for i in' '*15]
C[7][15:17]='##'
h,m=input()
for n,N in(m,5),(h,1):
 for d in[.36,.67,.967][:N/4+2]:a=(n/N-3)/1.9;x=int(15.5+cos(a)*d*(13+5%(n%6or 3)));y=int(7.5+sin(a)*d*7);C[y][x:x+2]=`n/10`,`n%10`
for x in C:print''.join(x)

Try it online!

JavaScript (ES8), 195 bytes

Expects ("HH")("MM") and returns a matrix of characters.

h=>m=>(C=[...(M=Math)+h].map(_=>[..."".padEnd(32)]),g=n=>[.36,2/3,z].map(d=>[z=0,1].map(k=>C[7.5+M.sin(a=(n-3)/1.9)*d*7|0][15.5+M.cos(a)*d*(13+5%(n%6||3))+k|0]=d?m[k]:"#")))(m/5,z=.967)&g(m=h)||C

Try it online!

Formulas

Given the index \$n\in[0\dots11]\$ of the hand position, the angle is given by:

$$a=(n - 3)\times 2\pi/12\approx(n-3)/1.9$$

We use \$a\$ to compute the integer position \$(x,y)\$ on the grid as follows:

$$x=\lfloor15.5+\cos(a)\times d\times r_x\rfloor\\ y=\lfloor7.5+\sin(a)\times d\times r_y\rfloor$$

where \$r_y\$ is always \$7\$ and \$r_x\$ depends on \$n\bmod 6\$:

$$\begin{array}{|c|c|c|c|c|c|c|} \hline n\bmod 6 & 0 & 1 & 2 & 3 & 4 & 5 \\ \hline r_x & 15 & 13 & 14 & 15 & 14 & 13 \\ \hline \end{array}$$

The value of \$r_x\$ is obtained with the JS code 13 + 5 % (n % 6 || 3).

The following values of \$d\$ are used to generate the different circles: \$0\$, \$0.36\$, \$2/3\$, \$0.967\$. We use the last 3 values for the minute hand and the first 3 for the hour hand.

Ungolfed

This ungolfed code draws the full clock, using the formulas described above.

let C = [...Array(15)].map(_ => [...Array(32).fill(" ")]);

for(let n = 0; n < 12; n++) {
  [ 0, 0.36, 2 / 3, 0.967 ].forEach(d => {
    let a = (n - 3) * Math.PI * 2 / 12,
        rx = 13 + 5 % (n % 6 || 3),
        x = 15.5 + Math.cos(a) * d * rx | 0,
        y = 7.5 + Math.sin(a) * d * 7 | 0;

    C[y][x] = d ? n >> 1 : "#";
    C[y][x + 1] = d ? n * 5 % 10 : "#";
  });
}
console.log(C.map(r => r.join("")).join("\n"));

Try it online!

Ruby, 137 129 123 121 119 bytes

->t{s="%40s"%$/*20
-3.upto(2){|i|j=t[h=i/3]
g=j/5**-h-3
s[420+"\5,RxN$"[g%6].ord*i*~0**h+=g/6,2]=i==0?"##":"%02d"%j}
s}

Try it online!

A function taking an argument in the form [12,00] and returning a newline separated string.

It forms a canvas of 20 lines of 39 spaces plus newline. . It then draws from the tip of the minute hand at iteration -3 to the centre 0 and then on to tip of the hour hand 2 by replacing characters.

The centre of the clock is at index 420 (I didn't plan it that way, it just happened!) There is an magic string with numbers for the (positive) offsets corresponding to half a revolution of the hand in the lower half of the clockface, encoded into ascii. the other half revolution is managed by negating these offsets by multiplying by -1 raised to the power h+g/6 (due to Ruby priority rules, -1 is represented by ~0.)

Commented code Based on 123 byte version

->t{s=("."*39+$/)*20     #Make a string s of 20 lines of 39 spaces plus newline
(-3..2).map{|i|          #Iterate from -3 (tip of minute hand) to 2 (tip of hour hand)
  j=t[h=i/3]             #h= -1 for minute, 0 for hour (rounding integer division down)
                         #Extract j from t[] (ruby wraps negative index -1 round to 1)
  g=(j/5**-h)-3          #If minute, divide j by 5 to make g correspond to hour value. 
                         #Subtract 3 so that g/6 is even in lower half 3..8 and odd in upper half 
  s[420+i*~0**(h+g/6)*   #Centre at 420. Offset by i, with signflip if minutes(h)+upperhalf(g/6) is odd.. 
  "\5,RxN$"[g%6].ord,2]= #...times offset for one of 6 values from magic string. Change 2 chars in s... 
  i==0?"##":"%02d"%j}    #...to ## if i==0 or the minute/hour contained in j if not.
s}                       #Return string s

Charcoal, 74 bytes

##F²«≔§⪪θ:¬ιη≔⎇ι﹪Iη¹²÷Iη⁵ζJ⁰∧¬﹪ζ⁶⊖÷ζ³F⁻³ι«M×∨‹ζ⁶±¹I§024542ζ⁻I§”)⊞↷ηk⦃”ζ²Pη

Try it online! Link is to verbose version of code. Explanation:

##

Output the clock's centre.

F²«

Loop over the minutes and hours.

≔§⪪θ:¬ιη

Extract the minutes or hours from the input time.

≔⎇ι﹪Iη¹²÷Iη⁵ζ

Get the direction index from 0 to 11.

J⁰∧¬﹪ζ⁶⊖÷ζ³

Jump to the centre of the clock, except for :00/:30/06:/12:, which are offset vertically.

F⁻³ι«

Loop thrice for the minutes or twice for the hours.

M×∨‹ζ⁶±¹I§024542ζ⁻I§”)⊞↷ηk⦃”ζ²

Move to the next minutes (or hours) position. The horizontal offsets are cyclically extracted from the 024542 string and then negated for the larger directions while the vertical offsets are extracted from a compressed string 001234443210 from which 2 is subtracted.

Pη

Output the minutes or hours without moving the cursor.