def migrate_deserialized_datetime(data, conversion): """Deserialize datetime strings from export archives, meaning to reattach the UTC timezone information.""" from aiida.tools.importexport.common.exceptions import ArchiveMigrationError if isinstance(data, dict): ret_data = {} for key, value in data.items(): if conversion is not None: ret_data[key] = migrate_deserialized_datetime( value, conversion[key]) else: ret_data[key] = migrate_deserialized_datetime(value, None) elif isinstance(data, (list, tuple)): ret_data = [] if conversion is not None: for value, sub_conversion in zip(data, conversion): ret_data.append( migrate_deserialized_datetime(value, sub_conversion)) else: for value in data: ret_data.append(migrate_deserialized_datetime(value, None)) else: if conversion is None: ret_data = data else: if conversion == 'date': # Node attributes that were datetime objects were converted to a string since datetimes cannot be stored # in JSON. The function used to serialize was: # `data.astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%S.%f') # Note that this first converted the datetime to UTC but then dropped the information from the string. # Since we know that all strings will be UTC, here we are simply reattaching that information. ret_data = data + '+00:00' else: raise ArchiveMigrationError( "Unknown convert_type '{}'".format(conversion)) return ret_data