2013-09-03 8 views
21

Mam obiekt daty w python i potrzebuję wygenerować znacznik czasu w locale C dla starszego systemu, używając kodów% a (weekday) i% b (month). Nie chcę jednak zmieniać ustawień narodowych aplikacji, ponieważ inne części muszą respektować bieżące ustawienia narodowe użytkownika. Czy istnieje sposób wywołania strftime() z określonym locale?Jak utworzyć strftime obiektu daty w innym języku?

Odpowiedz

24

Przykład podany przez Roba jest super, ale nie jest threadsafe. Oto wersja, która współpracuje z wątków:

import locale 
import threading 

from datetime import datetime 
from contextlib import contextmanager 


LOCALE_LOCK = threading.Lock() 

@contextmanager 
def setlocale(name): 
    with LOCALE_LOCK: 
     saved = locale.setlocale(locale.LC_ALL) 
     try: 
      yield locale.setlocale(locale.LC_ALL, name) 
     finally: 
      locale.setlocale(locale.LC_ALL, saved) 

# Let's set a non-US locale 
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8') 

# Example to write a formatted English date 
with setlocale('C'): 
    print(datetime.now().strftime('%a, %b')) # e.g. => "Thu, Jun" 

# Example to read a formatted English date 
with setlocale('C'): 
    mydate = datetime.strptime('Thu, Jun', '%a, %b') 

Tworzy menedżera kontekstowe threadsafe przy użyciu globalnej blokady i pozwala mieć wiele wątków uruchomionych lokalizacji zależnej od kodu za pomocą LOCALE_LOCK. Obsługuje również wyjątki od deklaracji zysku, aby zapewnić, że oryginalne ustawienia narodowe są zawsze przywracane.

+2

Należy pamiętać, że aby funkcja setlocale() powiodła się, potrzebne są ustawienia narodowe zainstalowane na poziomie systemu. Zasadniczo nie można na niej polegać. Cokolwiek oznacza lokalizację, musisz trzymać się z dala od strftime i używać odpowiedniej biblioteki i18n, takiej jak Babel. – ddaa

+0

jest to literówka na 'saved = locale.setlocale (...'? – vonPetrushev

+0

Nie wierzę, że istnieje literówka - jeśli drugim argumentem dla setlocale jest None, otrzymasz aktualnie ustawione ustawienia regionalne. – Daniel

-3

spojrzeć na pytz package

można używać jak to

import pytz 
UTC = pytz.timezone('UTC') # utc 
fr = pytz.timezone('Europe/Paris') #your local 
from datetime import datetime 
date = datetime.now(fr) 
dateUTC = date.astimezone(UTC) 

strftime odda w strefie czasowej określonej

dla mieć nazwę miesiąca w korzystaniu locale calendar na przykład:

import calendar 
print calendar.month_name[dateUTC.month] #will print in the locale 

inspekcja mo ponownie głęboko w kalendarzu, aby uzyskać więcej informacji

+0

To interesujące, ale muszę wygenerować datownik z angielskimi słowami na dni powszednie (% a) i miesiące (% b), nie zmieniać strefy czasowej. Czy Python może to zrobić? – MagerValp

+0

spójrz na kalendarz http://docs.python.org/2/library/calendar.html#module-calendar i metoda calendar.month_name prawdopodobnie –

+0

Ponownie, nie jest to, co chce OP. 'calendar.month_name' Tablica reprezentująca miesiące roku w bieżącym locale. –

11

Nie, nie ma sposobu, aby zadzwonić pod numer strftime() z określonymi ustawieniami regionalnymi.

Zakładając, że twoja aplikacja nie jest wielowątkowa, zapisz i przywróć istniejące ustawienia narodowe i ustaw język na 'C' po wywołaniu strftime.

#! /usr/bin/python3 
import time 
import locale 


def get_c_locale_abbrev(): 
    lc = locale.setlocale(locale.LC_TIME) 
    try: 
    locale.setlocale(locale.LC_TIME, "C") 
    return time.strftime("%a-%b") 
    finally: 
    locale.setlocale(locale.LC_TIME, lc) 

# Let's suppose that we're french 
locale.setlocale(locale.LC_ALL, 'fr_FR.utf8') 

# Should print french, english, then french 
print(time.strftime('%a-%b')) 
print(get_c_locale_abbrev()) 
print(time.strftime('%a-%b')) 

Jeśli wolisz with: do try: - finally:, można wzbudzać menedżera kontekstowego:

#! /usr/bin/python3 
import time 
import locale 
import contextlib 

@contextlib.contextmanager 
def setlocale(*args, **kw): 
    saved = locale.setlocale(locale.LC_ALL) 
    yield locale.setlocale(*args, **kw) 
    locale.setlocale(locale.LC_ALL, saved) 

def get_c_locale_abbrev(): 
    with setlocale(locale.LC_TIME, "C"): 
    return time.strftime("%a-%b") 

# Let's suppose that we're french 
locale.setlocale(locale.LC_ALL, 'fr_FR.utf8') 

# Should print french, english, then french 
print(time.strftime('%a-%b')) 
print(get_c_locale_abbrev()) 
print(time.strftime('%a-%b')) 
+0

to ustawienie narodowe we wszystkich skryptach uważam więc bądź ostrożny –

+0

Tak, 'locale.setlocale()' wpływa na cały program. Blok 'try-finally' lub' with' ustawia i przywraca ustawienia narodowe, aby nie zakłócać reszty programu. –

Powiązane problemy