I’m suffering a date time issue in the Plone’s MailHost, which send out a mail in a 16 hours offset out while my time zone is set to Etc/GMT+8.
A mail send out at 2012/01/10 5:39 PM, will received as send out at 2012/01/10 1:39 AM, it’s wild for me and most others.
Now, I’m trying to finger out what was happen.
In the Plone 4.x, all product source is located in the ‘buildout-cache/eggs/’ of your zope instance root dir.
Plone use MailHost to send out mail, which is at:
Products.MailHost-2.13.1-py2.6.egg/Products/MailHost/MailHost.py
396 def _mungeHeaders(messageText, mto=None, mfrom=None, subject=None,
397 charset=None, msg_type=None):
398 “”"Sets missing message headers, and deletes Bcc.
399 returns fixed message, fixed mto and fixed mfrom”"”
The _mungeHeaders() will check your headers, if there is no “Date” field, it will add one for you:
465 if not mo.get(‘Date’):
466 mo['Date'] = DateTime().rfc822()
The DateTime() comes from:
DateTime-2.12.6-py2.6.egg/DateTime/DateTime.py
and the rfc822() will format the date time as RFC822 required in the section ’5. DATE AND TIME SPECIFICATION’. more info.. in refs:
1506 def rfc822(self):
1507 “”"Return the date in RFC 822 format.”"”
1508 tzoffset = _tzoffset2rfc822zone(_tzoffset(self._tz, self._t))
1509 return ‘%s, %2.2d %s %d %2.2d:%2.2d:%2.2d %s’ % (
1510 self._aday,self._day,self._amon,self._year,
1511 self._hour,self._minute,self._nearsec,tzoffset)
While the time stamp of the standard content in the plone 4 is right after I set the TZ toEtc/GMT+8 in the base.cfg , I’ll investigate how the document by line use the DateTime to get right result.
The document by line is from:
plone.app.layout-2.1.12-py2.6.egg/plone/app/layout/viewlets/document_byline.pt
30 <span class=”documentModified”>
31 <span i18n:translate=”box_last_modified”>
32 last modified
33 </span>
34 <span tal:replace=”python:view.toLocalizedTime(context.ModificationDate(),long_format=1)”>
35 August 16, 2001 at 23:35:59
36 </span>
37 </span>
which from
plone.app.layout-2.1.12-py2.6.egg/plone/app/layout/viewlets/content.py
33 class DocumentBylineViewlet(ViewletBase):
34
35 index = ViewPageTemplateFile(“document_byline.pt”)
…
95 def toLocalizedTime(self, time, long_format=None, time_only = None):
96 “”"Convert time to localized time
97 “”"
98 util = getToolByName(self.context, ‘translation_service’)
99 return util.ulocalized_time(time, long_format, time_only, self.context,
100 domain=’plonelocales’)
101
where is ModificationDate is set:
Products.CMFDefault-2.2.2-py2.6.egg/Products/CMFDefault/DublinCore.py
108 security.declareProtected(ModifyPortalContent, ‘setModificationDate’)
109 def setModificationDate(self, modification_date=None):
110 “”" Set the date when the resource was last modified.
111
112 When called without an argument, sets the date to now.
113 “”"
114 if modification_date is None:
115 self.modification_date = DateTime()
116 else:
117 self.modification_date = self._datify(modification_date)
118
Products.CMFPlone-4.1.2-py2.6.egg/Products/CMFPlone/TranslationServiceTool.py
19 from i18nl10n import ulocalized_time
…
26 class TranslationServiceTool(PloneBaseTool, UniqueObject, SimpleItem):
27 “”" Utility methods to access the translation machinery “”"
28
…
84 security.declarePublic(‘ulocalized_time’)
85 def ulocalized_time(self, time, long_format=None, time_only = None, context=None,
86 domain=’plonelocales’, request=None):
87 # get some context if none is passed
88 if context is None:
89 context = self
90 return ulocalized_time(time, long_format, time_only, context, domain, request)
91
Products.CMFPlone-4.1.3-py2.6.egg/Products/CMFPlone/i18nl10n.py
96 # unicode aware localized time method (l10n)
97 def ulocalized_time(time, long_format=None, time_only=None, context=None,
98 domain=’plonelocales’, request=None):
which is very complicate…
date_format_long:
plone.app.locales-4.0.9-py2.6.egg/plone/app/locales/locales/en/LC_MESSAGES/plonelocales.po
16
17 #. The variables used here are the same as used in the strftime formating.
18 #. Supported are ${A}, ${a}, ${B}, ${b}, ${H}, ${I}, ${m}, ${d}, ${M}, ${p},
19 #. ${S}, ${Y}, ${y}, ${Z}, each used as variable in the msgstr.
20 #. For example: “${A} ${d}. ${B} ${Y}, ${H}:${M} ${Z}”
21 #. In english speaking countries default is:
22 #. ${b} ${d}, ${Y} ${I}:${M} ${p}
23 #: ./TranslationServiceTool.py
24 msgid “date_format_long”
25 msgstr “${b} ${d}, ${Y} ${I}:${M} ${p}”
26
We can use ‘long_format’ parameter to pass format what we want.
Reference:
Time in Python: http://docs.python.org/library/time.html
RFC2822: Date and Time spec http://tools.ietf.org/html/rfc2822.html#section-3.3
Mail date Issue 12458: https://dev.plone.org/ticket/12458