def testTimezoneNaiveHandling(self): # checks that we assign timezone naivity correctly dt = DateTime('2007-10-04T08:00:00+00:00') self.assertFalse(dt.timezoneNaive(), 'error with naivity handling in __parse_iso8601') dt = DateTime('2007-10-04T08:00:00Z') self.assertFalse(dt.timezoneNaive(), 'error with naivity handling in __parse_iso8601') dt = DateTime('2007-10-04T08:00:00') self.assertTrue(dt.timezoneNaive(), 'error with naivity handling in __parse_iso8601') dt = DateTime('2007/10/04 15:12:33.487618 GMT+1') self.assertFalse(dt.timezoneNaive(), 'error with naivity handling in _parse') dt = DateTime('2007/10/04 15:12:33.487618') self.assertTrue(dt.timezoneNaive(), 'error with naivity handling in _parse') dt = DateTime() self.assertFalse(dt.timezoneNaive(), 'error with naivity for current time') s = '2007-10-04T08:00:00' dt = DateTime(s) self.assertEqual(s, dt.ISO8601()) s = '2007-10-04T08:00:00+00:00' dt = DateTime(s) self.assertEqual(s, dt.ISO8601())
def censys_ipv4_tls_extraction(s: dict) -> dict: """ Extracts TLS relevant data out ot service part of Censys IPv4 dict :param s: Service part of a censys dict :return: Dictionary with TLS data """ cert = s.get("certificate", {}).get("parsed", {}) subject = cert.get("subject", None) or dict() issuer = cert.get("issuer", None) or dict() validity = cert.get("validity", None) or dict() common_name = subject.get("common_name", []) common_name.extend(cert.get("names", [])) if len(common_name) == 0: common_name = None cert_issued = DateTime(validity.get("start", None)) cert_expires = DateTime(validity.get("end", None)) cert_length = validity.get("length", None) return { "certificate": { "issuer_dn": cert.get("issuer_dn", None), "subject_dn": cert.get("subject_dn", None), "issuer": { # Censys always uses lists for those kind of attributes "common_name": issuer.get("common_name", [None])[0], "country": issuer.get("country", [None])[0], "locality": issuer.get("locality", [None])[0], "province": issuer.get("province", [None])[0], "organization": issuer.get("organization", [None])[0], "organizational_unit": issuer.get("organizational_unit", [None])[0], "email_address": issuer.get("email_address", [None])[0], }, "subject": { # Censys always uses lists for those kind of attributes, multiple CNs are okay, though "common_name": common_name, "country": subject.get("country", [None])[0], "locality": subject.get("locality", [None])[0], "province": subject.get("province", [None])[0], "organization": subject.get("organization", [None])[0], "organizational_unit": subject.get("organizational_unit", [None])[0], "email_address": subject.get("email_address", [None])[0], }, "validity": { "start": int(cert_issued), "start_readable": cert_issued.ISO8601(), "end": int(cert_expires), "end_readable": cert_expires.ISO8601(), "length": cert_length } } }
def test_pub_date(self): request = self.app.REQUEST self.login('Alan') self.portal.invokeFactory('Document', 'd1') context = getattr(self.portal, 'd1') # configure our portal to enable publication date on pages globally on # the site properties = getToolByName(context, 'portal_properties') site_properties = getattr(properties, 'site_properties') site_properties.displayPublicationDateInByline = True self.login('Ano') viewlet = DocumentBylineViewlet(context, request, None, None) viewlet.update() # publication date should be None as there is not Effective date set for # our document yet self.assertEqual(viewlet.pub_date(), None) # now set effective date for our document effective = DateTime() context.setEffectiveDate(effective) self.assertEqual(viewlet.pub_date(), DateTime(effective.ISO8601())) # now switch off publication date globally on the site and see if # viewlet returns None for publication date site_properties.displayPublicationDateInByline = False self.assertEqual(viewlet.pub_date(), None)
def test_pub_date(self): # configure our portal to enable publication date on pages globally on # the site registry = getUtility(IRegistry) settings = registry.forInterface( ISiteSchema, prefix='plone') settings.display_publication_date_in_byline = True self.logout() viewlet = self._get_viewlet() # publication date should be None as there is not Effective date set # for our document yet self.assertEqual(viewlet.pub_date(), None) # now set effective date for our document effective = DateTime() self.context.setEffectiveDate(effective) self.assertEqual(viewlet.pub_date(), DateTime(effective.ISO8601())) # now switch off publication date globally on the site and see if # viewlet returns None for publication date settings.display_publication_date_in_byline = False self.assertEqual(viewlet.pub_date(), None)
def testISO8601(self): ''' iso 8601 dates ''' ref0 = DateTime('2002/5/2 8:00am GMT') ref1 = DateTime('2002/5/2 8:00am US/Eastern') isoDt = DateTime('2002-05-02T08:00:00') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002-05-02T08:00:00Z') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002-05-02T08:00:00-04:00') self.assertEqual(ref1, isoDt) # Bug 1386: the colon in the timezone offset is optional isoDt = DateTime('2002-05-02T08:00:00-0400') self.assertEqual(ref1, isoDt) dgood = '2002-05-02' tgood = 'T08:00:00-04:00' for dbad in '2002-5-2', '2002-10-2', '2002-2-10', '02-2-10': self.assertRaises(DateTime.SyntaxError, DateTime, dbad) self.assertRaises(DateTime.SyntaxError, DateTime, dbad + tgood) for tbad in '08:00', 'T8:00': #, 'T08:00Z-04:00': self.assertRaises(DateTime.SyntaxError, DateTime, dgood + tbad) iso8601_string = '2002-05-02T08:00:00-04:00' iso8601DT = DateTime(iso8601_string) self.assertEqual(iso8601_string, iso8601DT.ISO8601())
def testExpirationDate(self): obj = self.folder date = DateTime() + 365 # expire one year from today date = DateTime(date.ISO8601()) # but strip off milliseconds obj.setExpirationDate(date) notify(ObjectModifiedEvent(obj)) expired = obj.ExpirationDate() # the string representation... expired = DateTime(expired) # is usually parsed again in Plone self.assertTrue(date.equalTo(expired), (date, expired))
def testExpirationDate(self): obj = self.folder date = DateTime() + 365 # expire one year from today date = DateTime(date.ISO8601()) # but strip off milliseconds obj.setExpirationDate(date) obj.processForm(values=dict(Description='foo!')) expired = obj.ExpirationDate() # the string representation... expired = DateTime(expired) # is usually parsed again in Plone self.assertTrue(date.equalTo(expired), (date, expired))
def testEffectiveDate(self): obj = self.folder date = DateTime() + 365 # expire one year from today date = DateTime(date.ISO8601()) # but strip off milliseconds obj.setEffectiveDate(date) obj.processForm(values=dict(Description='foo!')) effective = obj.EffectiveDate() # the string representation... effective = DateTime(effective) # is usually parsed again in Plone self.failUnless(date.equalTo(effective), (date, effective))
def unarchive(self, context, custom_message=None, initiator=None, reason=None): """ Unarchive the object :param context: object which is going to be unarchived :param custom_message: Custom message explaining why the object was unarchived :param initiator: the user id or name which commissioned the archival :param reason: reason id for which the object was archived """ noLongerProvides(context, IObjectArchived) now = DateTime() context.setExpirationDate(None) date = DateTime() wftool = getToolByName(context, 'portal_workflow') has_workflow = wftool.getChainFor(context) mtool = getToolByName(context, 'portal_membership') if not has_workflow: # NOP return state = wftool.getInfoFor(context, 'review_state') actor = mtool.getAuthenticatedMember().getId() if custom_message: reason += u" (%s)" % custom_message comments = (u"Unarchived by %(actor)s on %(date)s by request " u"from %(initiator)s with reason: %(reason)s" % { 'actor': actor, 'initiator': initiator, 'reason': reason, 'date': date.ISO8601() }) for wfname in context.workflow_history.keys(): history = context.workflow_history[wfname] history += ({ 'action': 'UnArchive', 'review_state': state, 'actor': actor, 'comments': comments, 'time': now, }, ) context.workflow_history[wfname] = history context.workflow_history._p_changed = True context.reindexObject() notify(Purge(context))
def archive(self, context, initiator=None, reason=None, custom_message=None): """Archive the object""" now = DateTime() alsoProvides(context, IObjectArchived) context.setExpirationDate(now) self.archive_date = now self.initiator = initiator self.custom_message = custom_message self.reason = reason wftool = getToolByName(context, 'portal_workflow') mtool = getToolByName(context, 'portal_membership') state = wftool.getInfoFor(context, 'review_state') actor = mtool.getAuthenticatedMember().getId() rv = NamedVocabulary('eea.workflow.reasons') vocab = rv.getVocabularyDict(context) reason = vocab.get('reason', "Other") if custom_message: reason += u" (%s)" % custom_message comments = (u"Archived by %(actor)s on %(date)s by request " u"from %(initiator)s with reason: %(reason)s" % { 'actor': actor, 'initiator': initiator, 'reason': reason, 'date': now.ISO8601(), }) for wfname in context.workflow_history.keys(): history = context.workflow_history[wfname] history += ({ 'action': 'Archive', 'review_state': state, 'actor': actor, 'comments': comments, 'time': now, }, ) context.workflow_history[wfname] = history context.workflow_history._p_changed = True context.reindexObject()
def test_display_pub_date_in_byline(self): from DateTime import DateTime from plone.app.layout.viewlets import content # Definimos a data de publicacao de um conteudo effective = DateTime() doc = self.doc doc.effective_date = effective viewlet = content.DocumentBylineViewlet(doc, self.request, None, None) viewlet.update() # Por padrao exibimos a data de publicacao self.assertEqual(viewlet.pub_date(), DateTime(effective.ISO8601())) adapter = self.adapter # Desativamos a exibicao da data de publicacao adapter.display_pub_date_in_byline = False # Viewlet nao exibe a data self.assertEqual(viewlet.pub_date(), None)
def update(self, uid, id, value, select_variable=None): """Updates an existing property. """ facade = self._getFacade() if select_variable: facade.updateCustomProperty( uid, id, select_variable=select_variable ) # Transform date value from milliseconds into DateTime object. prop = facade.getZenProperty(uid, id) if prop.get("type") == "date": userfacade = Zuul.getFacade('properties', self.context) usersettings = userfacade._dmd.ZenUsers.getUserSettings() tz = usersettings.timezone dt = DateTime(value, tz) if tz else DateTime(value) value = dt.ISO8601() facade.setZenProperty(uid, id, value) return DirectResponse.succeed( msg="Property %s successfully updated." % (id,) )
def test_pub_date(self): # configure our portal to enable publication date on pages globally on # the site properties = getToolByName(self.portal, 'portal_properties') site_properties = getattr(properties, 'site_properties') site_properties.displayPublicationDateInByline = True self.logout() viewlet = self._get_viewlet() # publication date should be None as there is not Effective date set # for our document yet self.assertEqual(viewlet.pub_date(), None) # now set effective date for our document effective = DateTime() self.context.setEffectiveDate(effective) self.assertEqual(viewlet.pub_date(), DateTime(effective.ISO8601())) # now switch off publication date globally on the site and see if # viewlet returns None for publication date site_properties.displayPublicationDateInByline = False self.assertEqual(viewlet.pub_date(), None)
def test_patch_feed_event_with_get_contents(self): start_date = DateTime(datetime.datetime.today() + datetime.timedelta(days=1)).ISO8601() end_date = DateTime(datetime.datetime.today() + datetime.timedelta(days=1, hours=1)).ISO8601() response = self.api_session.post( '/', json={ "title": "An Event", "@type": "Event", "start": start_date, "end": end_date, "timezone": "Europe/Vienna" }, ) self.assertEqual(201, response.status_code) response = response.json() event_id = response['id'] two_days_ahead = DateTime(datetime.datetime.today() + datetime.timedelta(days=2)) response = self.api_session.patch('/{}'.format(event_id), json={ "start": response['start'], "end": two_days_ahead.ISO8601() }) self.assertEqual(204, response.status_code) response = self.api_session.get('/{}'.format(event_id)) response = response.json() self.assertEquals( DateTime(response['end']).day(), two_days_ahead.day()) self.assertEquals( DateTime(response['end']).hour(), two_days_ahead.hour())
def iso_date(self, date): if not date: return '' if isinstance(date, basestring): date = DateTime(date) return date.ISO8601()
def dict_from_item(item): if hasPloneAppEvent and (IEvent.providedBy(item) or IOccurrence.providedBy(item)): # plone.app.event DX or AT Event is_occurrence = IOccurrence.providedBy(item) acc = IEventAccessor(item) return { "status": "ok", "id": "UID_%s" % (acc.uid), "title": acc.title, "description": acc.description, "start": acc.start.isoformat(), "end": acc.end.isoformat(), "url": acc.url, "editable": editable, "allDay": acc.whole_day, "className": "contextualContentMenuEnabled %s %s %s %s" % ( state and "state-%s" % str(state) or "", editable and "editable" or "", css and css or "", is_occurrence and "occurrence" or ""), "color": color} elif IATEvent.providedBy(item): # Products.ATContentTypes ATEvent allday = (item.end() - item.start()) > 1.0 adapted = interfaces.ISFBaseEventFields(item, None) if adapted: allday = adapted.allDay return { "status": "ok", "id": "UID_%s" % (item.UID()), "title": item.Title(), "description": item.Description(), "start": item.start().ISO8601(), "end": item.end().ISO8601(), "url": item.absolute_url(), "editable": editable, "allDay": allday, "className": "contextualContentMenuEnabled %s %s %s" % ( state and "state-%s" % str(state) or "", editable and "editable" or "", css and css or ""), "color": color} elif ICatalogBrain.providedBy(item): # Event catalog brain if type(item.end) != DateTime: brainend = DateTime(item.end) brainstart = DateTime(item.start) else: brainend = item.end brainstart = item.start allday = (brainend - brainstart) > 1.0 if getattr(item, 'SFAllDay', None) in [False, True]: allday = item.SFAllDay return { "status": "ok", "id": "UID_%s" % (item.UID), "title": item.Title, "description": item.Description, "start": brainstart.ISO8601(), "end": brainend.ISO8601(), "url": item.getURL(), "editable": editable, "allDay": allday, "className": "contextualContentMenuEnabled %s %s %s" % ( state and "state-%s" % str(state) or "", editable and "editable" or "", css and css or ""), "color": color} else: raise ValueError('item type not supported for: %s' % repr(item))
def check_site(site): # XXX will store when last check was so we always only look back # to previous check time setSite(site) catalog = api.portal.get_tool('portal_catalog') es = ElasticSearchCatalog(catalog) if not es.enabled: return index_name = audit.get_index_name() es = ESConnectionFactoryFactory()() sannotations = IAnnotations(site) last_checked = sannotations.get(LAST_CHECKED_KEY) if last_checked is None: last_checked = DateTime() - 30 filters = [{ 'term': { 'type': 'workflow' } }, { 'range': { 'date': { 'gt': last_checked.ISO8601() } } }] if len(filters) > 1: qfilter = {'and': filters} else: qfilter = filters[0] query = { "query": { 'filtered': { 'filter': qfilter, 'query': { 'match_all': {} } } } } results = es.search(index=index_name, doc_type=audit.es_doc_type, body=query, sort='date:desc', size=1000) hits = results['hits']['hits'] workflow = api.portal.get_tool('portal_workflow') forced = [] checked = [] for hit in hits: hit = hit['_source'] if hit['object'] in checked: continue try: ob = uuidToObject(hit['object']) checked.append(hit['object']) except: continue try: review_history = workflow.getInfoFor(ob, 'review_history') if not review_history: continue for r in reversed(review_history): if (not r['action'] or r['review_state'] != 'published' or not r.get('comments', '').startswith('OVERRIDE:')): continue if r['time'] < last_checked: # just quit now, we're getting to older history that we don't care about break forced.append({'ob': ob, 'history_entry': r}) except WorkflowException: continue if len(forced) > 0: # sent out email to admins site_url = site.absolute_url() registry = getUtility(IRegistry) public_url = registry.get('plone.public_url') if not public_url: public_url = site_url email_html = EMAIL_BODY + '<ul>' for item in forced: ob = item['ob'] wf_entry = item['history_entry'] try: user = api.user.get(wf_entry['actor']) user_name = user.getProperty('fullname') or user.getId() except: user_name = wf_entry['actor'] email_html += EMAIL_BODY_ITEM.format( content_url=ob.absolute_url().replace(site_url, public_url), content_title=ob.Title(), user_name=user_name, comments=wf_entry.get('comments', '')) email_html += '</ul>' email_subject = "Forced content publication update(Site: %s)" % ( api.portal.get_registry_record('plone.site_title')) for user in api.user.get_users(): user_roles = api.user.get_roles(user=user) email = user.getProperty('email') if (('Manager' not in user_roles and 'Site Administrator' not in user_roles) or not email): continue utils.send_email(email, email_subject, html=email_html) site._p_jar.sync() sannotations[LAST_CHECKED_KEY] = DateTime() transaction.commit()
def test_EffectiveDate(self): dummy = self._dummy self.assertTrue(dummy.EffectiveDate() == 'None') now = DateTime() dummy.setEffectiveDate(now) self.assertTrue(dummy.EffectiveDate() == now.ISO8601())
def ulocalized_time(time, long_format=None, time_only=None, context=None, domain='plonelocales', request=None): # get msgid msgid = long_format and 'date_format_long' or 'date_format_short' if time_only is not None: msgid = 'time_format' # NOTE: this requires the presence of three msgids inside the translation catalog # date_format_long, date_format_short, and time_format # These msgids are translated using interpolation. # The variables used here are the same as used in the strftime formating. # Supported are %A, %a, %B, %b, %H, %I, %m, %d, %M, %p, %S, %Y, %y, %Z, each used as # variable in the msgstr without the %. # For example: "${A} ${d}. ${B} ${Y}, ${H}:${M} ${Z}" # Each language dependend part is translated itself as well. # From http://docs.python.org/lib/module-time.html # # %a Locale's abbreviated weekday name. # %A Locale's full weekday name. # %b Locale's abbreviated month name. # %B Locale's full month name. # %d Day of the month as a decimal number [01,31]. # %H Hour (24-hour clock) as a decimal number [00,23]. # %I Hour (12-hour clock) as a decimal number [01,12]. # %m Month as a decimal number [01,12]. # %M Minute as a decimal number [00,59]. # %p Locale's equivalent of either AM or PM. # %S Second as a decimal number [00,61]. # %y Year without century as a decimal number [00,99]. # %Y Year with century as a decimal number. # %Z Time zone name (no characters if no time zone exists). mapping = {} # convert to DateTime instances. Either a date string or # a DateTime instance needs to be passed. if not IDateTime.providedBy(time): try: time = DateTime(time) except: log('Failed to convert %s to a DateTime object' % time, severity=logging.DEBUG) return None if context is None: # when without context, we cannot do very much. return time.ISO8601() if request is None: request = aq_acquire(context, 'REQUEST') # get the formatstring formatstring = translate(msgid, domain, mapping, request) if formatstring is None or formatstring.startswith( 'date_') or formatstring.startswith('time_'): # msg catalog was not able to translate this msgids # use default setting properties = getToolByName(context, 'portal_properties').site_properties if long_format: format = properties.localLongTimeFormat else: if time_only: format = properties.localTimeOnlyFormat else: format = properties.localTimeFormat return time.strftime(format) # get the format elements used in the formatstring formatelements = _interp_regex.findall(formatstring) # reformat the ${foo} to foo formatelements = [el[2:-1] for el in formatelements] # add used elements to mapping elements = [e for e in formatelements if e in datetime_formatvariables] # add weekday name, abbr. weekday name, month name, abbr month name week_included = True month_included = True name_elements = [e for e in formatelements if e in name_formatvariables] if not ('a' in name_elements or 'A' in name_elements): week_included = False if not ('b' in name_elements or 'B' in name_elements): month_included = False for key in elements: mapping[key] = time.strftime('%' + key) if week_included: weekday = int(time.strftime('%w')) # weekday, sunday = 0 if 'a' in name_elements: mapping['a'] = weekdayname_msgid_abbr(weekday) if 'A' in name_elements: mapping['A'] = weekdayname_msgid(weekday) if month_included: monthday = int(time.strftime('%m')) # month, january = 1 if 'b' in name_elements: mapping['b'] = monthname_msgid_abbr(monthday) if 'B' in name_elements: mapping['B'] = monthname_msgid(monthday) # translate translateable elements for key in name_elements: mapping[key] = translate(mapping[key], domain, context=request, default=mapping[key]) # translate the time string return translate(msgid, domain, mapping, request)
def testISO8601(self): # ISO8601 reference dates ref0 = DateTime('2002/5/2 8:00am GMT') ref1 = DateTime('2002/5/2 8:00am US/Eastern') ref2 = DateTime('2006/11/6 10:30 GMT') ref3 = DateTime('2004/06/14 14:30:15 GMT-3') ref4 = DateTime('2006/01/01 GMT') # Basic tests # Though this is timezone naive and according to specification should # be interpreted in the local timezone, to preserve backwards # compatibility with previously expected behaviour. isoDt = DateTime('2002-05-02T08:00:00') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002-05-02T08:00:00Z') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002-05-02T08:00:00+00:00') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002-05-02T08:00:00-04:00') self.assertEqual(ref1, isoDt) isoDt = DateTime('2002-05-02 08:00:00-04:00') self.assertEqual(ref1, isoDt) # Bug 1386: the colon in the timezone offset is optional isoDt = DateTime('2002-05-02T08:00:00-0400') self.assertEqual(ref1, isoDt) # Bug 2191: date reduced formats isoDt = DateTime('2006-01-01') self.assertEqual(ref4, isoDt) isoDt = DateTime('200601-01') self.assertEqual(ref4, isoDt) isoDt = DateTime('20060101') self.assertEqual(ref4, isoDt) isoDt = DateTime('2006-01') self.assertEqual(ref4, isoDt) isoDt = DateTime('200601') self.assertEqual(ref4, isoDt) isoDt = DateTime('2006') self.assertEqual(ref4, isoDt) # Bug 2191: date/time separators are also optional isoDt = DateTime('20020502T08:00:00') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002-05-02T080000') self.assertEqual(ref0, isoDt) isoDt = DateTime('20020502T080000') self.assertEqual(ref0, isoDt) # Bug 2191: timezones with only one digit for hour isoDt = DateTime('20020502T080000+0') self.assertEqual(ref0, isoDt) isoDt = DateTime('20020502 080000-4') self.assertEqual(ref1, isoDt) isoDt = DateTime('20020502T080000-400') self.assertEqual(ref1, isoDt) isoDt = DateTime('20020502T080000-4:00') self.assertEqual(ref1, isoDt) # Bug 2191: optional seconds/minutes isoDt = DateTime('2002-05-02T0800') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002-05-02T08') self.assertEqual(ref0, isoDt) # Bug 2191: week format isoDt = DateTime('2002-W18-4T0800') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002-W184T0800') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002W18-4T0800') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002W184T08') self.assertEqual(ref0, isoDt) isoDt = DateTime('2004-W25-1T14:30:15-03:00') self.assertEqual(ref3, isoDt) isoDt = DateTime('2004-W25T14:30:15-03:00') self.assertEqual(ref3, isoDt) # Bug 2191: day of year format isoDt = DateTime('2002-122T0800') self.assertEqual(ref0, isoDt) isoDt = DateTime('2002122T0800') self.assertEqual(ref0, isoDt) # Bug 2191: hours/minutes fractions isoDt = DateTime('2006-11-06T10.5') self.assertEqual(ref2, isoDt) isoDt = DateTime('2006-11-06T10,5') self.assertEqual(ref2, isoDt) isoDt = DateTime('20040614T1430.25-3') self.assertEqual(ref3, isoDt) isoDt = DateTime('2004-06-14T1430,25-3') self.assertEqual(ref3, isoDt) isoDt = DateTime('2004-06-14T14:30.25-3') self.assertEqual(ref3, isoDt) isoDt = DateTime('20040614T14:30,25-3') self.assertEqual(ref3, isoDt) # ISO8601 standard format iso8601_string = '2002-05-02T08:00:00-04:00' iso8601DT = DateTime(iso8601_string) self.assertEqual(iso8601_string, iso8601DT.ISO8601()) # ISO format with no timezone isoDt = DateTime('2006-01-01 00:00:00') self.assertEqual(ref4, isoDt)
def ulocalized_time(time, long_format=None, time_only=False, context=None, domain='plonelocales', formatstring_domain='plonelocales', request=None, target_language=None): """Unicode aware localized time method (l10n), extended from CMFPlone The ONLY change versus CMFPlone is the extra parameter `formatstring_domain`. This allows us to define a different date_format_long in ploneintranet, while still being able to use the default translations provided by plonelocales, e.g. for the month names. """ if time_only: msgid = 'time_format' elif long_format: msgid = 'date_format_long' else: msgid = 'date_format_short' # NOTE: this requires the presence of three msgids inside the translation # catalog date_format_long, date_format_short, and time_format # These msgids are translated using interpolation. # The variables used here are the same as used in the strftime # formating. # Supported are: # %A, %a, %B, %b, %H, %I, %m, %d, %M, %p, %S, %Y, %y, %Z # Each used as variable in the msgstr without the %. # For example: "${A} ${d}. ${B} ${Y}, ${H}:${M} ${Z}" # Each language dependend part is translated itself as well. # From http://docs.python.org/lib/module-time.html # # %a Locale's abbreviated weekday name. # %A Locale's full weekday name. # %b Locale's abbreviated month name. # %B Locale's full month name. # %d Day of the month as a decimal number [01,31]. # %H Hour (24-hour clock) as a decimal number [00,23]. # %I Hour (12-hour clock) as a decimal number [01,12]. # %m Month as a decimal number [01,12]. # %M Minute as a decimal number [00,59]. # %p Locale's equivalent of either AM or PM. # %S Second as a decimal number [00,61]. # %y Year without century as a decimal number [00,99]. # %Y Year with century as a decimal number. # %Z Time zone name (no characters if no time zone exists). mapping = {} # convert to DateTime instances. Either a date string or # a DateTime instance needs to be passed. if not IDateTime.providedBy(time): try: time = DateTime(time) except: log('Failed to convert %s to a DateTime object' % time, severity=logging.DEBUG) return None if context is None: # when without context, we cannot do very much. return time.ISO8601() if request is None: request = aq_acquire(context, 'REQUEST') # 1. if our Enabled flag in the configuration registry is set, # the format string there should override the translation machinery formatstring = get_formatstring_from_registry(msgid) if formatstring is not None: return time.strftime(formatstring) # 2. the normal case: translation machinery, # that is the ".../LC_MESSAGES/plonelocales.po" files # XXX: here, we pass `formatstring_domain` instead of `domain` formatstring = translate(msgid, formatstring_domain, mapping, request, target_language=target_language) # 3. if both failed, fall back to hardcoded ISO style if formatstring == msgid: if msgid == 'date_format_long': formatstring = '%Y-%m-%d %H:%M' # 2038-01-19 03:14 elif msgid == 'date_format_short': formatstring = '%Y-%m-%d' # 2038-01-19 elif msgid == 'time_format': formatstring = '%H:%M' # 03:14 else: formatstring = '[INTERNAL ERROR]' return time.strftime(formatstring) # get the format elements used in the formatstring formatelements = _interp_regex.findall(formatstring) # reformat the ${foo} to foo formatelements = [el[2:-1] for el in formatelements] # add used elements to mapping elements = [e for e in formatelements if e in datetime_formatvariables] # add weekday name, abbr. weekday name, month name, abbr month name week_included = True month_included = True name_elements = [e for e in formatelements if e in name_formatvariables] if not ('a' in name_elements or 'A' in name_elements): week_included = False if not ('b' in name_elements or 'B' in name_elements): month_included = False for key in elements: mapping[key] = time.strftime('%' + key) if week_included: weekday = int(time.strftime('%w')) # weekday, sunday = 0 if 'a' in name_elements: mapping['a'] = weekdayname_msgid_abbr(weekday) if 'A' in name_elements: mapping['A'] = weekdayname_msgid(weekday) if month_included: monthday = int(time.strftime('%m')) # month, january = 1 if 'b' in name_elements: mapping['b'] = monthname_msgid_abbr(monthday) if 'B' in name_elements: mapping['B'] = monthname_msgid(monthday) # translate translateable elements # Note: Here, the normal `domain` is used for key in name_elements: mapping[key] = translate(mapping[key], domain, context=request, default=mapping[key], target_language=target_language) # translate the time string # XXX: here, we pass `formatstring_domain` instead of `domain` return translate(msgid, formatstring_domain, mapping, request, target_language=target_language)
def test_ExpiresDate(self): dummy = self._dummy self.assertTrue(dummy.ExpirationDate() == 'None') now = DateTime() dummy.setExpirationDate(now) self.assertTrue(dummy.ExpirationDate() == now.ISO8601())