This took a long time to track down.
Moodle always corrects everything to be in user profile time, which defaults to the "Server timezone" (which is actually the one set in site administration), which itself defaults to "Australia/Perth"
All of our CI servers therefore end up with a timezone of Australia/Perth, despite the fact that they're in Germany.
However, the true System timezone (the one selected on the actual server) is "Europe/Berlin".
When we open the dialogue, and we set a time of 10pm...
We create a new timezone with:
The values in the various fields are in the User timezone (i.e. "Australia/Perth")
This creates a new Date Object with the values provided. It does so assuming that they are values in the timezone of the browser - "Europe/Berlin".
As a result our 10pm AWST (Australian Western Standard Time) is assumed to actually be 10pm EST (European Summer Time).
In the following line we get the unix timestamp of that value, which is modified for UTC.
As a result we end up with a unix timestamp relating to 10pm EST => 8pm UTC.
We then store that date in the database as being 8pm UTC.
Next time that we open the dialogue, the time is read as being 8pm UTC, and then converted to a value for Moodle in AWST which is 4am AWST the following day.
This happens because the JS Date object always assumes that the Browser timezone matches the content. Essentially it is not safe to use the JS Date object in Moodle to fetch a unix timestamp.