O motivo é que TZ=UTC-8
é interpretado como um Fuso horário POSIX . No formato de fuso horário POSIX, as 3 letras são a abreviação do fuso horário (que é arbitrária) e o número é o número de horas que o fuso horário está atrás UTC. Portanto, UTC-8
significa um fuso horário abreviado como "UTC" que é −8 horas atrás do UTC real ou UTC + 8 horas.
(Funciona dessa forma porque o Unix foi desenvolvido nos EUA, que está por trás do UTC. Esse formato permite que os fusos horários dos EUA sejam representados como EST5, CST6, etc.)
Você pode ver o que está acontecendo nesses exemplos:
$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800
O formato do fuso horário ISO -0800
segue a abordagem oposta, com -
indicando que a zona está atrás de UTC e +
indicando que a zona está à frente do UTC.