see below for the specific answer to the question in comments
Time is really complex. You need to use newInstanceGMT in the creation of your second time, or make sure all your dates and times are in 'local' time, which can be confusing since local time changes for users... so to make it easier, always use local or GMT, but never cross the streams... Don't even get me started about trigger contexts...
I also want to point out you created another potential issue by specifying dateGMT with your local date creation, which could lead to the issues you see below:
DateTime dt = Datetime.newInstanceGMT(2021, 11, 8, 4, 0, 0);
Time t = Time.newInstance(8, 0, 0, 0);
System.debug('dateTime '+dt );
System.debug('date '+dt.dateGMT());
System.debug('time '+t);
System.debug('new time '+DateTime.newInstance(dt.dateGMT(), t));
System.debug('new time '+DateTime.newInstance(dt.date(), t));
System.debug('new time '+DateTime.newInstanceGMT(dt.dateGMT(), t));
System.debug('new time '+DateTime.newInstanceGMT(dt.date(), t));
here is the resultant logs:
05:42:53.16 (17457343)|USER_DEBUG|[4]|DEBUG|dateTime 2021-11-08 04:00:00
05:42:53.16 (17524443)|USER_DEBUG|[5]|DEBUG|date 2021-11-08 00:00:00
05:42:53.16 (17584575)|USER_DEBUG|[6]|DEBUG|time 08:00:00.000Z
05:42:53.16 (17669288)|USER_DEBUG|[7]|DEBUG|new time 2021-11-08 15:00:00
05:42:53.16 (17728841)|USER_DEBUG|[8]|DEBUG|new time 2021-11-07 15:00:00 //local date is different from GMT date!
05:42:53.16 (17786827)|USER_DEBUG|[9]|DEBUG|new time 2021-11-08 08:00:00 //what you want!!!
05:42:53.16 (17833628)|USER_DEBUG|[10]|DEBUG|new time 2021-11-07 08:00:00
There is a lot going on here, but again... either use local or GMT. and I would always construct my newInstances of DateTime using integers... the Time t is introducing yet another Zulu time that is further screwing things up.
As a fun aside:
Greenwich Mean Time was designated as the "reference time", having an offset of zero hours. The phonetic radio alphabet for Z is ZULU- so when one says "ZULU time", it's short for "zero-offset time", meaning Greenwich Mean Time, or more properly, UTC - Coordinated Universal Time.
Specific question from comments
How would you set DateTime correctly in a local timezone?
First of all, I would try to use. Get the specific
DateTime dt = Datetime.newInstance(2021, 11, 8, 4, 0, 0);
This will almost always give you what you want.
If you need to follow the format you were suggesting above, you can use the following
DateTime dt = Datetime.newInstanceGMT(2021, 11, 8, 4, 0, 0);
Time t = Time.newInstance(8, 0, 0, 0);
TimeZone tz = UserInfo.getTimeZone(); // you can also specify a timezone, see the APEX TimeZone class
DateTime dt2 = Datetime.newInstanceGMT(dt.dateGMT(), t - tz.getOffset(dt));
this returns:
|DEBUG|dateTime 2021-11-08 11:00:00 //-7 == 4:00 in GMT
|DEBUG|time 08:00:00.000Z //GMT
|DEBUG|new time dt2 2021-11-08 15:00:00 //!!!! 15 is -7, or 14:00 in -6
Hope this helps!