To be clear it doesn't rotate at midnight. The trigger to rotate is not based off of the notion of wall clock time. The trigger to rotate happens when log records pass through the publish method. This means that rotation can be delayed based on the flow of log messages.
Per the Tomcat 9.x source code of org.apache.juli.FileHandler::publish
:
// Construct the timestamp we will use, if requested
Timestamp ts = new Timestamp(System.currentTimeMillis());
String tsDate = ts.toString().substring(0, 10);
In the case, Timestamp is java.sql.Timestamp and is an extension of java.util.Date.
Per How to set time zone of a java.util.Date? the default timezone of the JVM is applied only to the toString of a date which is being used here.
The only out of the box way you can make the rotation happen in GMT is to set the default timezone of the JVM. However, that is going to have a global impact on all of your dates and timestamps for your application. If you don't want the rotation to be delayed then you need to ensure that a log record gets published.
The better solution would be to create an issue against the Tomcat source code and patch the org.apache.juli.FileHandler to allow rotatable to accept a boolean or string accepted by java.time.OffsetTime::parse. This would allow for configurations of:
org.apache.juli.FileHandler.rotate=00:00:00+01:00
Even using java.text.SimpleDateFormat would allow configuration of the timezone in the org.apache.juli.FileHandler.