have tried this but this will cause other problems, e.g
plone.app.layout.viewlets.content.isExpired
if base_hasattr(self.context, 'expires'):
return self.context.expires().isPast()
will fail.
My guess that is fails is because timedelta is part of datetime in the Python standard library and effective, expired etc. all need to be Zope DateTime's. (camel case). See this chapter in the Plone documentation at https://docs.plone.org/develop/plone/misc/datetime.html for more information.
If you want to use timedelta you will have to convert the DateTime to datetime, add the timedelta and then convert back to DateTime.
The IPublication interface works only with datetime (Python standard library module) types. This is one of the reasons I recommend dealing with effective and expiration dates only through this interface, and forget about the other methods.
This should work:
from datetime import datetime
from datetime import timedelta
mydatetime = datetime.now()
publication = IPublication(obj, None)
if publication is not None:
publication.expires = mydatetime
publication.effective = mydatetime + timedelta(days=3)
obj.reindexObject()
As pointed by @cekk you can pass the parameter idxs to reindexObject() in order to restrict which indexes will be affected. Do this if performance is important. I recommend checking in portal_catalog through ZMI to see which indexes may be relevant. I think there were changes in this area in the latest Plone versions.