2013-09-03 9 views
21

Ich habe ein Date-Objekt in Python und ich muss einen Zeitstempel im C-Gebietsschema für ein Altsystem mit den Codes% a (Wochentag) und% b (Monat) generieren. Ich möchte jedoch nicht das Gebietsschema der Anwendung ändern, da andere Teile das aktuelle Gebietsschema des Benutzers berücksichtigen müssen. Gibt es eine Möglichkeit, strftime() mit einem bestimmten Gebietsschema aufzurufen?Wie strikte ich ein Datumsobjekt in einem anderen Gebietsschema?

Antwort

24

Die von Rob gegebenen Beispiel ist groß, ist aber nicht THREAD. Hier ist eine Version, die mit Fäden funktioniert:

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

Es schafft einen Thread-Kontext-Manager eine globale Sperre verwenden und ermöglicht es Ihnen, mehrere Threads laufen locale-abhängigen Code zu haben, durch die LOCALE_LOCK verwenden. Es behandelt auch Ausnahmen von der Yield-Anweisung, um sicherzustellen, dass das ursprüngliche Gebietsschema immer wiederhergestellt wird.

+2

Beachten Sie, dass für das erfolgreiche Setzen von setlocale() das Gebietsschema auf Systemebene installiert sein muss. Auf die Sie sich im Allgemeinen nicht verlassen können. Für etwas, das lokalisierbar sein soll, müssen Sie sich von der strftzeit fernhalten und eine richtige Bibliothek wie Babel benutzen. – ddaa

+0

ist das ein Tippfehler auf 'saved = locale.setlocale (...'? – vonPetrushev

+0

Ich glaube nicht, dass es einen Tippfehler gibt - wenn das zweite Argument zu setlocale None ist, dann erhalten Sie das aktuell eingestellte Gebietsschema. – Daniel

-3

werfen Sie einen Blick auf die pytz package

Sie diese

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 in der Zeitzone rendert Monatsnamen zum Beispiel in dem Lokalisierungs-Einsatz verwenden kann calendar angegeben

für haben:

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

inspizieren mo re tief Kalender für mehr Informationen

+0

Das ist interessant, aber ich muss einen Datumsstempel mit englischen Wörtern für Wochentage (% a) und Monate (% b) generieren, die Zeitzone nicht ändern. Kann Pytz das auch tun? – MagerValp

+0

werfen Sie einen Blick auf Kalender http://docs.python.org/2/library/calendar.html#module-calendar und die Methode calendar.month_name vielleicht –

+0

Wieder ist es nicht, was OP will. 'calendar.month_name' Ein Array, das die Monate des Jahres im aktuellen Gebietsschema darstellt. –

11

Nein, gibt es keine Möglichkeit strftime() mit einem bestimmten Gebietsschema aufzurufen.

Angenommen, Ihre App ist nicht multi-threaded, speichern und wiederherstellen Sie das vorhandene Gebietsschema und setzen Sie Ihr Gebietsschema auf 'C', wenn Sie strftime aufrufen.

#! /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')) 

Wenn Sie es vorziehen with: zu try: - finally: Sie eine Kontext-Manager entfachen könnte:

#! /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

das ist das Gebietsschema in all dem Skript Ich denke schon vorsichtig sein –

+0

Ja, 'locale.setlocale()' betrifft das gesamte Programm. Der 'try-finally'-Block oder der 'with'-Block setzt und stellt das Gebietsschema wieder her, um den Rest des Programms nicht zu stören. –

Verwandte Themen