Skip to content

Commit

Permalink
LocalDispatcher, LocalJobs : Fix timezone handling
Browse files Browse the repository at this point in the history
Before, the Properties tab was showing the correct time in the local timezone, and
the Start Time column was showing the wrong thing. The difference is that the Properties
tab was formatted directly in Python, whereas the column went through a conversion to
`IECore::DataTimeData` and then on to `QDateTime` for display. DateTimeData stores
a `boost::posix_time::ptime` instance internally, which store time in UTC. The wrapper
that constructs that from a Python `datetime` assumes that the Python value is also stored
in UTC, but that was not the case in our code - we were instead using "naive" objects
which didn't record timezone data, and which only we knew were in local time.

The solution is to store time in UTC in Python, by passing a timezone to `now()`. Using
UTC also has the benefit of insulating us from changes to the system timezone made
during a Job's runtime, which would otherwise be causing us to compare start and end
times from different timezones and return bogus results.

> Note : This isn't quite the whole story. Even when given a non-naive `datetime` object
  which records its timezone, the DataTimeData bindings still assume that it is stored in
  UTC. We should make the DateTimeData bindings convert to UTC appropriately using the
  timezone information, but that can wait for another day. Either way, we would still be
  wanting to store as UTC in Python.
  • Loading branch information
johnhaddon committed Dec 12, 2023
1 parent 552c06a commit eb97ba3
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 4 deletions.
6 changes: 3 additions & 3 deletions python/GafferDispatch/LocalDispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def __init__( self, batch, dispatcher ) :
)
self.__executeInBackground = dispatcher["executeInBackground"].getValue()

self.__startTime = datetime.datetime.now()
self.__startTime = datetime.datetime.now( datetime.timezone.utc )
self.__endTime = None

self.__messageHandler = _MessageHandler()
Expand Down Expand Up @@ -140,7 +140,7 @@ def runningTime( self ) :
if self.__endTime is not None :
return self.__endTime - self.__startTime
else :
return datetime.datetime.now() - self.__startTime
return datetime.datetime.now( datetime.timezone.utc ) - self.__startTime

def processID( self ) :

Expand Down Expand Up @@ -384,7 +384,7 @@ def __updateStatus( self, status ) :
self.__status = status

if status in ( self.Status.Complete, self.Status.Failed, self.Status.Killed ) :
self.__endTime = datetime.datetime.now()
self.__endTime = datetime.datetime.now( datetime.timezone.utc )

if threading.current_thread() is threading.main_thread() :
self.__emitStatusChanged()
Expand Down
2 changes: 1 addition & 1 deletion python/GafferDispatchUI/LocalJobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ def soleFormat( values ) :
value = sole( values )
if value is not None :
if isinstance( value, datetime.datetime ) :
return "{:%a %b %d %H:%M:%S}".format( value )
return "{:%a %b %d %H:%M:%S}".format( value.astimezone() )
else :
return str( value )
else :
Expand Down

0 comments on commit eb97ba3

Please sign in to comment.