DateTime values are represented by an epoch time in GMT, and converted to the appropriate date/time when requested via the appropriate methods. System.debug, coincidentally, always displays GMT. Try this:
DateTime now = DateTime.now();
Integer hours = now.hour(), minutes = now.minute(), seconds = now.second();
System.debug(now);
System.debug(hours+':'+minutes+':'+seconds);
In my org, I ran it just a few seconds ago, and came up with the following values:
17:21:03.1 (1425986)|USER_DEBUG|[3]|DEBUG|2017-08-03 23:21:03
17:21:03.1 (1452095)|USER_DEBUG|[4]|DEBUG|17:21:3
As you can see, it's 21 minutes past 5 PM in my local time zone. System.debug shows the GMT value, and by calling hour(), minute(), and second(), I received the local time.
Per my original comment, whatever you think is going on isn't what's going on. DateTime values are always in GMT, and accommodate themselves for you as necessary. I recommend that you consider asking about whatever was originally stopping you before, because it's most likely a misunderstanding about how DateTime works.
If you need to adjust to another time zone, do feel free to use the TimeZone class, but be aware that using a time altered by addSeconds(tz.getOffset()/1000) may return incorrect results if you're querying the database, etc. The TimeZone class is typically used to convert a user's input from a local time zone into GMT, since the entire platform runs on GMT.