tested with the Debian package version 2.2.1-1 and Redmine 3.3.1-4+deb9u2, PostgreSQL backend
Here is the workaround I'm using in my code:
# FIXME - why doesn't this already have tzinfo from the API?
last_modified = issue['updated_on']
if last_modified.tzinfo is None:
app.logger.debug("ticket #%s: Redmine API updated_on value has no timezone, assuming UTC" % (issue['id'],))
last_modified = last_modified.replace(tzinfo=datetime.timezone.utc)
todo['last-modified'] = icalendar.vDatetime(last_modified)