arrow-py / arrow

🏹 Better dates & times for Python
https://arrow.readthedocs.io
Apache License 2.0
8.71k stars 676 forks source link

Storing locale with Arrow so that it is used by format #309

Open synotna opened 8 years ago

synotna commented 8 years ago

A great side effect of how Arrow's formatting is implemented, is that it can be used like any other type with regular string formatting, e.g.

'My name is {name} and my birthday is {birthday:MMMM-YYYY}'.format(**myself)

However, if I want the Arrow formatting to be in a specific locale, I have a problem. Even though I can specifiy locale with .get(), the locale is only used for parsing but not stored, and I have no way of providing arrow with the locale when calling format above.

My quick & dirty solution, which may be helpful for others with the same problem, is:

class LocaleArrow(arrow.Arrow):
    def format(self, *args, **kwargs):
        if 'locale' not in kwargs and hasattr(self, 'locale'):
            return super().format(locale=self.locale, *args, **kwargs)
        return super().format(*args, **kwargs)

class LocaleArrowFactory(arrow.ArrowFactory):
    def __init__(self, type=LocaleArrow):
        self.type = type

    def get(self, *args, **kwargs):
        arw = super().get(*args, **kwargs)
        if 'locale' in kwargs:
            arw.locale = kwargs.get('locale')
        return arw

arw = LocaleArrowFactory().get(dt, locale=self.locale)

Would, or have you considered storing & using the locale in as part of regular Arrow?

andrewelkins commented 7 years ago

Yes I could see that being very useful. I'd welcome a PR

Syeberman commented 7 years ago

I'm still concerned about adding the locale to Arrow. Generally, Python objects do not store their formatting options as part of the object, but instead are specified at the time of formatting.

If we extended Arrow.__format__ to include a locale in the format string itself, would that work for you @synotna? Something like:

f'My name is {name} and my birthday is {birthday:MMMM-YYYY#fr_ca}'
# (We'd need to research if `#` is a good choice for this)