Convert the Time to a String

LaTeX, 466 bytes

\usepackage{fmtcount,etoolbox}\def\x{\the\numexpr}\def\n[#1]{\numberstringnum{#1}}\def\h[#1]{\ifnumequal{#1}{0}{twelve night}{\ifnumequal{#1}{12}{twelve noon}{\ifnumless{#1}{13}{\n[#1] o'clock AM}{\n[\x#1-12\relax] o'clock PM}}}}\def\m[#1]{\ifnumequal{#1}{15}{quarter}{\ifnumequal{#1}{30}{half}{\n[#1] minutes}}}\newcounter{c}\def\f[#1]#2{\ifnumequal{#2}{0}{\h[#1]}{\ifnumless{#2}{31}{\m[#2] past \h[#1]}{\setcounter{c}{\x60-#2\relax}\m[\thec] to \h[\x#1+1\relax]}}}

Just call the macro \f as \f[hour]{minutes}, here some tests:

\begin{document}

\noindent
\textbf{Test cases:} \\ \\
00:00 = \f[00]{00} \\
12:00 = \f[12]{00} \\
06:00 = \f[6]{00} \\
18:00 = \f[18]{00} \\
06:15 = \f[6]{15} \\
18:45 = \f[18]{45} \\
11:30 = \f[11]{30} \\
13:22 = \f[13]{22} \\
17:43 = \f[17]{43} \\

\noindent
\textbf{More test cases:} \\ \\
00:13 = \f[00]{13} \\
12:12 = \f[12]{12} \\
12:15 = \f[12]{15} \\
11:45 = \f[11]{45} \\
11:41 = \f[11]{41} \\

\end{document}

Python 2, 498 bytes

Input comes as function argument. First hour and then minute, both as integer. Result gets printed to the screen.

def g(h,m):
 a=lambda x:"twelve one two three four five six seven eigth nine ten eleven".split()[x%12];b=lambda x:a(x)+" o'clock "+["AM","PM"][x>=12]
 if m:
    z=m if m<30else 60-m;print(a(z)if z<13else("twenty"+(a(z-20)if z-20else"")if z>19else"thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split()[z-13])if m%15else"quarter"if m-30else"half")+(" minutes"if m-30and m%15else"")+[" past "+b(h)," to "+b(h+1)][m>30]
 else:print"twelve "+("noon"if h else "night")if h in[0,12]else b(h)

Try it online! (with slightly extended testcases)

That was a pretty fun golf. Although all those nested ternaries drove me a little bit crazy ^^
I was planning on doing this in Pyth after this, but I don't think that I am mentally able to do this at the moment (or ever).

Ungolfed:

def ungolfed(h,m):
    toStr=lambda x:"twelve one two three four five six seven eigth nine ten eleven".split()[x%12]
    hour=lambda x:toStr(x)+" o'clock "+["AM","PM"][x>=12]
    minute=lambda x:"twenty"+(toStr(x-20)if x-20else"")if x>19else"thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split()[x-13]
    
    if m:
        s=""
        if m==30:
            s+="half"
        else:
            if m%15==0:
                s+="quarter"
            else:
                z=m if m<30 else 60-m
                if z<13:
                    s+=toStr(z)
                else:
                    s+=minute(z)
        print s+(" minutes"if m-30and m%15else "")+[" past "+hour(h)," to "+hour(h+1)][m>30]
    else:
        if h in[0,12]:
            print"twelve "+("noon"if h else "night")
        else:
            print hour(h)

Javascript, 384 381 bytes

(h,m)=>(o='one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,'.split`,`,o=o.map((x,i)=>i>11?(x||o[i-10])+'teen':x),(a=m>30,t=12,m?(m-30?m%15?((m=a?59-m:m)>=(b=a?19:20)?'twenty'+((m%=b)?o[a?m:m-1]:''):o[a?m:m-1])+' minutes':'quarter':'half')+(a?' to ':' past '):'')+(h%t|m?o[(a?h:(h?h-1:11))%t]+` o'clock ${h>t?'P':'A'}M`:o[11]+(h-t?' night':' noon')))

f=
(h,m)=>(
    o='one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,'.split`,`,
    o=o.map((x,i)=>i>11?(x||o[i-10])+'teen':x),
    (a=m>30,t=12,
    m?
        (m-30?
            m%15?
                ((m=a?59-m:m)>=(b=a?19:20)?
                    'twenty'+((m%=b)?o[a?m:m-1]:'')
                :o[a?m:m-1])+' minutes'
            :'quarter'
        :'half')+(a?' to ':' past ')
    :'')
    +(h%t|m?
        o[(a?h:(h?h-1:11))%t]+` o'clock ${h>t?'P':'A'}M`
    :o[11]+(h-t?' night':' noon'))
)

document.body.innerHTML = '<pre>' +
'f(00,00) = ' + f(00,00) + '\n' +
'f(12,00) = ' + f(12,00) + '\n' +
'f(06,00) = ' + f(06,00) + '\n' +
'f(18,00) = ' + f(18,00) + '\n' +
'f(06,15) = ' + f(06,15) + '\n' +
'f(18,45) = ' + f(18,45) + '\n' +
'f(11,30) = ' + f(11,30) + '\n' +
'f(13,22) = ' + f(13,22) + '\n' +
'f(17,43) = ' + f(17,43) + '\n' +
'f(00,09) = ' + f(00,09) + '\n' +
'f(23,59) = ' + f(23,59) + '\n' +
'</pre>'