Seite 1 von 1

Kann man Daten / Uhrzeiten lokalisiert formatieren und parsen ohne die globale "locale"-Einstellung zu verändern?

Verfasst: Dienstag 18. September 2018, 19:54
von AFoeee
Hallo,
ich versuche eine Möglichkeit zu finden Daten bzw. Uhrzeiten lokalisiert zu formatieren und zu parsen.
Dabei ist die eigentliche Problematik, dass die "default locale"-Einstellung des Systems ("de_DE") von der Lokalisierung des Input / Output abweicht ("en_US").

Ich möchte also folgendes erzielen:
  • einen lokalisierten String zu einem "datetime"-Objekt parsen,
  • mittels eines "datetime"-Objekts einen formatierten String erzeugen (selbes "locale" und Muster wie Input).

Bild



Während meiner Recherche bin ich auf folgende zwei Möglichkeiten gestoßen:
  1. Verändern der globalen "locale"-Einstellung.

    Dieser Ansatz ist meiner Meinung nach etwas problematisch, da er einen globalen Wert manipuliert und daraus ggf. unerwünschte Nebeneffekte entstehen können.

    Code: Alles auswählen

    import datetime
    import locale
    
    locale.setlocale(locale.LC_TIME, "en_US.UTF-8")
    
    dt = datetime.datetime.strptime("Thu 3 Apr 2014 13:19:52",
                                    "%a %d %b %Y %H:%M:%S")
    # datetime.datetime(2014, 4, 3, 13, 19, 52)
    
    dtr_str = dt.strftime("%a %-d %b %Y %H:%M:%S")
    # 'Thu 3 Apr 2014 13:19:52'
  2. Verwenden der Python Bibliothek babel.

    Der Vorteil hieran ist, dass das gewünschte "locale" der Methode zum Formatieren einfach übergeben werden kann.
    Leider scheint babel nicht das Parsen beliebiger Muster zu unterstützen. (Offenbar funktioniert nur das Format "short" wirklich zuverlässig, welches mein Input allerdings nicht hat.)

    Code: Alles auswählen

    import babel.dates    # installed via pip
    import datetime
    
    dt = datetime.datetime(2014, 4, 3, 13, 19, 52)
    
    dt_str = babel.dates.format_datetime(dt,
                                         "EEE d MMM yyyy H:mm:ss", 
                                         locale="en_US")
    # 'Thu 3 Apr 2014 13:19:52'

Gibt es eine Möglichkeit die beschriebenen Konvertierungen durchzuführen ohne die globale "locale"-Einstellung zu verändern?

Diese Frage wurde in englischer Sprache auch auf stackoverflow gepostet.

Mit freundlichen Grüßen
AFoeee

Re: Kann man Daten / Uhrzeiten lokalisiert formatieren und parsen ohne die globale "locale"-Einstellung zu verändern?

Verfasst: Dienstag 18. September 2018, 22:32
von __blackjack__
@AFoeee: Im zweiten von Dir verlinkten Issue verweist jemand auf das `dateparser`-Modul. Dann gäbe es noch `maya` von Kenneth Reitz, der in der Dokumentation als Konkurrentz bzw. Grundlage die Packages Arrow, Delorean, und Pendulum erwähnt. Also ist gibt da durchaus noch andere Bibliotheken.

Re: Kann man Daten / Uhrzeiten lokalisiert formatieren und parsen ohne die globale "locale"-Einstellung zu verändern?

Verfasst: Mittwoch 19. September 2018, 10:23
von AFoeee
__blackjack__ hat geschrieben: Dienstag 18. September 2018, 22:32 Dann gäbe es noch `maya` von Kenneth Reitz, der in der Dokumentation als Konkurrentz bzw. Grundlage die Packages Arrow, Delorean, und Pendulum erwähnt. Also ist gibt da durchaus noch andere Bibliotheken.
Hallo __blackjack__,

die Bibliothek arrow scheint genau das zu sein, wonach ich gesucht habe. Vielen Dank!

Code: Alles auswählen

import arrow        # installiert mittels pip

dt_str = "Thu 3 Apr 2014 13:19:52"              # en_US

a_dt = arrow.get(dt_str,
                 "ddd D MMM YYYY H:mm:ss",
                 locale="en_US")                # "en_US" ist ebenfalls der default-Wert

dt = a_dt.datetime
# datetime.datetime(2014, 4, 3, 13, 19, 52, tzinfo=tzutc())

s = a_dt.format("ddd D MMM YYYY H:mm:ss",
                locale="en_US")                 # "en_US" ist ebenfalls der default-Wert
# 'Thu 3 Apr 2014 13:19:52'
Ich habe zusätzlich den Eintrag auf stackoverflow aktualisiert.

Mit freundlichen Grüßen
AFoeee

Re: Kann man Daten / Uhrzeiten lokalisiert formatieren und parsen ohne die globale "locale"-Einstellung zu verändern?

Verfasst: Donnerstag 20. September 2018, 11:29
von DeaD_EyE
Ich nutze pytz für Zeitzonen.

Könnte so aussehen:

Code: Alles auswählen

import datetime
import pytz


berlin = pytz.timezone('Europe/Berlin')
london = pytz.timezone('Europe/London')
utc_now = datetime.datetime.now(tz=pytz.UTC)

print(berlin.normalize(utc_now))
print(london.normalize(utc_now))
Was dort fehlt, ist die Lokalisierung des Strings.
DateTime nutze ich grundsätzlich mit UTC0 und erst, wenn es zur Anzeige kommt, normalisiere ich.
Falls die Ausgabe in einer Datenbank gespeichert werden soll und die Datenbank Informationen über die Zeitzone nicht speichert, sollte man ISO8601 verwenden.
Das datetime-Modul kann seit 3.7 auch ISO8601 strings parsen. Die Ausgabe als ISO8601 string wird schon etwas länger unterstützt.