Let's clean it up a bit and make it more portable. In general, it's best to use tput to generate the control sequences instead of hard coding them, as described in Bash FAQ 53. This way it is much easier to find your missing \].
red=$(tput setaf 1)
green=$(tput setaf 2)
yellow=$(tput setaf 3)
white=$(tput setaf 7)
reset=$(tput sgr0)
PS1="\[$red\][\[$yellow\]\A\[$red\]] \u:\[$green\]\W\[$white\]\$\[$reset\] "
Note that I replaced your date invocation with the built-in prompt escape \A that displays the same thing (24-hour time in HH:MM format).
There is one caveat with this approach as described in the linked Bash FAQ, where the output would be garbled if any of the tput control sequences output something that happened to contain a prompt escape. I have never run into that issue so I generally ignore it.