Se você chamar a função os.date sem nenhum parâmetro, ela chama automaticamente a função os.time, que retorna o horário em tempo UTC, como você mesmo percebeu.
that’s not a bug, because in the document of os.date here. It states os.date " Returns how many seconds have passed since the Unix epoch (1 January 1970, 00:00:00), under current UTC time. If provided a table formatted similarly to that returned by os.date(), it will return the number of seconds since that time instead." instead of UTC-4 due it to using the current server time.
In Roblox Studio, your computer handles the server you’re playtesting in. So when you use os.date(), it uses your device as the Local Time. If you use the Roblox App however, it will return the Local Time of the server’s location. So if the server were to be in the US, it would return a date and time in that location.
Using a Local Script to get os.date() only uses your device.