def date_format(self, time, formatstring):
        # This is a simplified version of Products.CMFPlone.i18nl10n.ulocalized_time
        # that can take any format string.

        # ${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).

        # get the format elements used in the formatstring
        mapping = {}
        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], 'plonelocales', context=self.request, default=mapping[key])

        # Apply the data to the format string:
        return interpolate(formatstring, mapping)
Beispiel #2
0
    def toCalendarLocalizedTime(self, time):
        """Convert a date in the calendar date format"""
        time = DateTime(time.strftime("%Y-%m-%d"))

        mapping = {}
        formatstring = translate('date_format_long',
                                 'monet.calendar.extensions',
                                 mapping,
                                 self.request,
                                 default="${A} ${B} ${d} ${Y}")

        # 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],
                                     'plonelocales',
                                     context=self.request,
                                     default=mapping[key])

        # translate the time string
        return translate('date_format_long',
                         'monet.calendar.extensions',
                         mapping,
                         self.request,
                         default="${A} ${B} ${d} ${Y}")
Beispiel #3
0
    def test_regexp_interp_regex(self):
        from Products.CMFPlone.i18nl10n import _interp_regex
        locales_string = "${H}:${M}"

        # test for locale string elements:
        self.assertEquals(
            _interp_regex.findall(locales_string),
            ["${H}", "${M}"],
        )
    def toCalendarLocalizedTime(self, time):
        """Convert a date in the calendar date format"""
        time = DateTime(time.strftime("%Y-%m-%d"))

        mapping = {}
        formatstring = translate('date_format_long', 'monet.calendar.extensions', mapping,
                                 self.request, default="${A} ${B} ${d} ${Y}")
        
        # 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], 'plonelocales', context=self.request, default=mapping[key])
    
        # translate the time string
        return translate('date_format_long', 'monet.calendar.extensions', mapping,
                         self.request, default="${A} ${B} ${d} ${Y}")
Beispiel #5
0
    def date_format(self, time, formatstring):
        # This is a simplified version of
        # Products.CMFPlone.i18nl10n.ulocalized_time
        # that can take any format string.

        # ${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).

        # get the format elements used in the formatstring
        mapping = {}
        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],
                                     'plonelocales',
                                     context=self.request,
                                     default=mapping[key])

        # Apply the data to the format string:
        return interpolate(formatstring, mapping)
Beispiel #6
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)
def i18nl10n_ulocalized_time(time, long_format=None, time_only=None, context=None,
                             domain='plonelocales', request=None):
    """This patched version change the behaviour and the meaning of long_format parameter.

    This trick is quite ugly, but is the only way to keep compatibility with basic use case of this method
    all around Plone code.
    
    The format must be given using the .po format, so not if for example you want to translate this:
        '%a %d %b %Y'
    you need to change it to:
        '${a} ${d} ${b} ${Y}'
    """
    
    # get msgid
    if not long_format or (type(long_format)!=str and type(long_format)!=unicode):
        msgid = long_format and 'date_format_long' or 'date_format_short'
        if time_only is not None:
            msgid = 'time_format'
    else:
        msgid = long_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.ISO()

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