Exemplo n.º 1
0
def as_date(date):
    """Convert a either date (or datetime) or a DateTime object to an
    xs.date object.

    """

    if IDateTime.providedBy(date):
        return xs.date(date.year(), date.month(), date.day())
    return xs.date(date.year, date.month, date.day)
Exemplo n.º 2
0
    def toLocalizedTime(self, time, *args, **kwds):
        """ Localized time
        """
        if not time:
            return None

        if IDateTime.providedBy(time):
            return time.Date()

        return time.date()
Exemplo n.º 3
0
    def toLocalizedTime(self, time, *args, **kwds):
        """ Localized time
        """
        if not time:
            return None

        if IDateTime.providedBy(time):
            return time.Date()

        return time.date()
Exemplo n.º 4
0
def run(self):
    """
    * Move existing messages from messageboxes in IUser objects, messageboxes
      in IConversation objects.
    * Rename all old messages' ids to remove the previx "message."
    * Change all old messages' time attr to python's datetime.
    """
    services = []
    for o in self.objectValues():
        if IChatService.providedBy(o):
            services.append(o)

    for service in services:

        if not hasattr(service, 'conversations'):
            manage_addBTreeFolder(service, 'conversations', 'Conversations')
        convs = service._getOb('conversations')

        for user in getattr(service, 'users').objectValues():
            for oldmbox in user.objectValues():

                conv = service._getConversation(user.id, oldmbox.id)
                newmbox = Conversation._getMessageBox(conv, oldmbox.id)
                for message in oldmbox.objectValues():
                    if message.author != oldmbox.id:
                        # We now only store one author's messages per mbox. So
                        # we ignore the other messages. They will be deleted.
                        continue

                    if IDateTime.providedBy(message.time):
                        message.time = message.time.asdatetime().replace(tzinfo=utc)
                    elif type(message.time) == str:
                        message.time = dateutil.parser.parse(message.time)

                    newid = '%f' % time.mktime(message.time.timetuple())
                    message.time = message.time.isoformat()

                    newmsg= Message(message.text, message.author)
                    newmsg.time = message.time
                    newmsg.id = newid
                    try:
                        newmbox._setObject(newid, message)
                    except BadRequest:
                        continue

                transaction.commit()

    return "Succesfully migrated the messages"
Exemplo n.º 5
0
def ulocalized_time(
    time, long_format=None, time_only=False, context=None, domain="plonelocales", request=None, target_language=None
):
    """unicode aware localized time method (l10n)"""

    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
    formatstring = translate(msgid, 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
    for key in name_elements:
        mapping[key] = translate(
            mapping[key], domain, context=request, default=mapping[key], target_language=target_language
        )

    # translate the time string
    return translate(msgid, domain, mapping, request, target_language=target_language)
Exemplo n.º 6
0
    def items(self):
        """Use the item brains"""
        # Mostly copied from plone.app.content.browser.foldercontents,
        # modified to use catalog brains
        context = aq_inner(self.context)
        plone_utils = getToolByName(context, 'plone_utils')
        plone_view = getMultiAdapter((context, self.request), name=u'plone')
        portal_workflow = getToolByName(context, 'portal_workflow')
        portal_properties = getToolByName(context, 'portal_properties')
        portal_types = getToolByName(context, 'portal_types')
        site_properties = portal_properties.site_properties
        portal = getToolByName(context, 'portal_url').getPortalObject()

        use_view_action = site_properties.getProperty(
            'typesUseViewActionInListings', ())
        browser_default = context.browserDefault()

        econtext = Expression.getExprContext(context)

        results = []
        for i, obj in enumerate(self.batch):
            if (i + 1) % 2 == 0:
                table_row_class = "draggable even"
            else:
                table_row_class = "draggable odd"

            url = obj.getURL()
            path = obj.getPath or "/".join(obj.getPhysicalPath())
            icon = plone_view.getIcon(obj)

            type_class = 'contenttype-' + plone_utils.normalizeString(
                obj.portal_type)

            review_state = obj.review_state
            state_class = 'state-' + plone_utils.normalizeString(review_state)
            relative_url = obj.getURL(relative=True)

            type_title_msgid = portal_types[obj.portal_type].Title()
            url_href_title = u'%s: %s' % (translate(type_title_msgid,
                                                    context=self.request),
                                          safe_unicode(obj.Description))

            modified = plone_view.toLocalizedTime(
                obj.ModificationDate, long_format=1)

            obj_type = obj.Type
            if obj_type in use_view_action:
                view_url = url + '/view'
            elif obj.is_folderish:
                view_url = url + "/folder_contents"
            else:
                view_url = url

            is_browser_default = len(browser_default[1]) == 1 and (
                obj.id == browser_default[1][0])

            columns = {}
            for column in self.columns.ordered:
                value = getattr(obj, column['field'], MV)

                # Calculate the sums before using any expression
                if value is not MV:
                    if column['has_sum']:
                        if 'sum' in column:
                            column['sum'] += value
                        else:
                            column['sum'] = value

                expr = column.get('expr')
                if expr:
                    econtext.vars.update(item=obj, value=value)
                    value = econtext.evaluate(expr)
                    del econtext.vars['value']
                    del econtext.vars['item']

                if IDateTime.providedBy(value):
                    value = plone_view.toLocalizedTime(value, long_format=1)

                columns[column['field']] = value

            results.append(dict(
                url=url,
                url_href_title=url_href_title,
                id=obj.getId,
                quoted_id=urllib.quote_plus(obj.getId),
                path=path,
                title_or_id=obj.pretty_title_or_id(),
                obj_type=obj_type,
                size=obj.getObjSize,
                modified=modified,
                icon=icon.html_tag(),
                type_class=type_class,
                wf_state=review_state,
                state_title=portal_workflow.getTitleForStateOnType(
                    review_state, obj_type),
                state_class=state_class,
                is_browser_default=is_browser_default,
                folderish=obj.is_folderish,
                relative_url=relative_url,
                view_url=view_url,
                table_row_class=table_row_class,
                is_expired=context.isExpired(obj),
                obj=obj,
                columns=columns,
                ))

        for column in self.columns.ordered:
            if not column['has_sum'] or 'sum' not in column:
                continue
            expr = column.get('expr')
            if expr:
                econtext.vars.update(item=obj, value=column['sum'])
                column['sum'] = econtext.evaluate(expr)
                del econtext.vars['value']
                del econtext.vars['item']

        return results
Exemplo n.º 7
0
 def test_interface(self):
     from DateTime.interfaces import IDateTime
     self.assertTrue(IDateTime.providedBy(DateTime()))
Exemplo n.º 8
0
def ulocalized_time(time, long_format=None, time_only=False, context=None,
                    domain='plonelocales', request=None):
    # get msgid
    msgid = long_format and 'date_format_long' or 'date_format_short'
    if time_only:
        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)
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
 def test_interface(self):
     from DateTime.interfaces import IDateTime
     self.assertTrue(IDateTime.providedBy(DateTime()))
Exemplo n.º 11
0
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 get_data(self, field):
     data = field.get(self.context)
     if IDateTime.providedBy(data):
         return data.ISO8601()
     return data
Exemplo n.º 13
0
 def get_data(self, field):
     data = field.get(self.context)
     if IDateTime.providedBy(data):
         return data.ISO8601()
     return data
Exemplo n.º 14
0
def ulocalized_time(time, formatstring, request, target_language=None):
    """time localization method copied from Products.CMFPlone.i18nl10n.
    The method was modified to allow for a custom formatstring in the
    normal python format.

    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).
    """

    domain = 'plonelocales'
    # map to a message string, to make easier reuse of original
    # method and _interp_regex.
    formatstring = format_string_to_message_string(formatstring)

    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 Exception:
            log('Failed to convert %s to a DateTime object' % time,
                severity=logging.DEBUG)
            return None

    # 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],
                                 target_language=target_language)

    # translate the time string
    return formatstring.replace("${", "{").format(**mapping)