setEffectiveDate() in PLONE4 vs PLONE5

We want to reset the Effective Date of some Dexterity Types, which are derived from NewsItems, as we often use the Effective Date as sort criterum.
We used to have python scipts for that, which worked fine in our PLONE 4 Instanzes but don't work in our PLONE 5 sites.
In one case it looks like this and should set the Eff.Date to the Creation Date:

dateorg=context.ZopeTime()
dateString = dateorg.strftime('%Y/%m/%d %T')
date = context.CreationDate()
oldeff = context.EffectiveDate()
context.setEffectiveDate(date)
neweff = context.EffectiveDate()
context.reindexObject()
return "Date now %s. Creat = %s . New Eff = %s . Old Eff = %s ." % (dateString,date,neweff,oldeff )

The output of the script shows the old and the new Eff.Date as expected, but when I edit the context object in PLONE it still shows the old Eff.Date. That means, even if context.EffectiveDate() gives the new Date after having it changed, it does not store that in the object itself.

Under PLONE 4 it works as expected.

PLONE 5 Docus tell me that setEffectiveDate(date) still should work as before.

Any hints, were that problem is? Did I miss something?

Plone source does it like this:

context.effective_date = DateTime(date)

Dexterities Dublic-Core compatibility method setEffectiveDate does not work that much different.

It calls datify before, maybe here something wents wrong?

It looks like the field is called 'effective' https://github.com/plone/plone.app.dexterity/blob/master/plone/app/dexterity/behaviors/metadata.py#L149 and 'effective_date' is just a getter of that value and not a setter: https://github.com/plone/plone.app.dexterity/blob/master/plone/app/dexterity/behaviors/metadata.py#L397

Could that be the problem?

Great. This needs a major cleanup. But at least it is a bug, may you write a report?

Reported: https://github.com/plone/Products.CMFPlone/issues/2863

Mikel, thanks for creating the report.

When I replace
context.setEffectiveDate(date)
by
context.effective_date = DateTime(date)
it is still the same problem. The script runs without throwing an exception and gives me the right return values as expected, but editing the context DT Object in PLONE shows still the old Effective Date.

And have you tried to set effective instead of effective_date? I mean:

context.effective = DateTime(date)

Because the field name is 'effective' and not 'effective_date'

Yes, I had also tried context.effective = DateTime(date). Still the same Problem.

Ah, interestering. I created an import script to import/sync content out of another system using xml and remember having issues with 'presetting' dates as well, but I had more issues with setting the creation date (to set the date in Plone to the the item was created in the external system).

@PeterB Do you also reindex the object after modifiying the effective date? Because you might see the old effective date coming from the catalog metadata. [edit: I now see the full reindexobject call in the initial code, but am not sure if you did this also after setting .effective directly, just checking]

Another caveat, specify a time zone, otherwise you can see weird 1 hour differences with Zope's older DateTime that is required.

            # some BA's don't have initial date set
            if new_ba['initial_date']:
                # Add timezone hardcoded, otherwise we get a 1 hour offset if we
                # create from date without time
                creation_date = DateTime.DateTime(
                    str(new_ba['initial_date']) + " GMT+1"
                )
                new_obj.creation_date = creation_date
                new_obj.modification_date = creation_date

            new_obj.reindexObject(idxs=['modified', 'created'])
1 Like

@PeterB How are you executing that script? Another guess have you tried doing a transaction?

import transaction
transaction.commit()

@fredvd related to the timezone I also encountered a problem with DST. I.e: for my timezone some dates are GMT+1 and some are GMT+2
So what I do it is create a DateTime from datetime instance:

>>> first_january = datetime.strptime('01-01-2019', '%d-%m-%Y')
>>> DateTime(first_january)
DateTime('2019/01/01 00:00:00 GMT+1')
>>> first_july = datetime.strptime('01-07-2019', '%d-%m-%Y')
>>> DateTime(first_july)
DateTime('2019/07/01 00:00:00 GMT+2')

Related to the name of the field. Correct me if I am wrong guys @erral @jensens, but I have understood that behaviors are adapters and that they factories can store the value anywhere (Anotations, attributes, ...). So the name of the field in the behavior definition may be diferent from the real one. I learnt this when in some script I wanted to call the plone api to create content passing as argument the effective_date. The same applies to behavior field subjects which is stored in subject.

So in this case field name appears is effective_date and the adapter factory it is defining a DCFieldProperty specifying the real field name

If not getter specified the code does this:

        if self._set_name:
            getattr(inst.context, self._set_name)(value)
        elif inst.context.hasProperty(self._get_name):
            inst.context._updateProperty(self._get_name, value)
        else:
            setattr(inst.context, self._get_name, value)

Yes, as shown in the code in my first posting ich have
context.reindexObject()
after having modfied the effective date.

Plone Foundation Code of Conduct