50 votes

Obtenir le nom Olson TZ pour le fuseau horaire local ?

Comment puis-je obtenir le Nom du fuseau horaire d'Olson (par exemple Australia/Sydney ) correspondant à la valeur donnée par C's localtime appeler ?

Il s'agit de la valeur remplacée par TZ par lien symbolique /etc/localtime ou le réglage d'un TIMEZONE dans les fichiers de configuration du système liés au temps.

18voto

Anurag Uniyal Points 31931

Je pense que le mieux est de passer en revue tous les fuseaux horaires de pytz et de vérifier lequel correspond au fuseau horaire local, chaque objet de fuseau horaire de pytz contient des informations sur l'utcoffset et le tzname comme CDT, EST, les mêmes informations sur l'heure locale peuvent être obtenues à partir de time.timezone/altzone y time.tzname et je pense que c'est suffisant pour faire correspondre correctement le fuseau horaire local dans la base de données pytz, par exemple.

import time
import pytz
import datetime

local_names = []
if time.daylight:
    local_offset = time.altzone
    localtz = time.tzname[1]
else:
    local_offset = time.timezone
    localtz = time.tzname[0]

local_offset = datetime.timedelta(seconds=-local_offset)

for name in pytz.all_timezones:
    timezone = pytz.timezone(name)
    if not hasattr(timezone, '_tzinfos'):
        continue#skip, if some timezone doesn't have info
    # go thru tzinfo and see if short name like EDT and offset matches
    for (utcoffset, daylight, tzname), _ in timezone._tzinfos.iteritems():
        if utcoffset == local_offset and tzname == localtz:
            local_names.append(name)

print local_names

sortie :

['Amérique/Atikokan', 'Amérique/Bahia_Banderas', 'America/Bahia_Banderas', 'America/Belize', 'America/Cambridge_Bay', 'America/Cancun', 'America/Chicago', 'America/Chihuahua', "America/Coral_Harbour", "America/Costa_Rica", "America/El_Salvador", "America/Fort_Wayne", "America/Guatemala", "Amérique/Indiana/Indianapolis", "Amérique/Indiana/Knox", America/Indiana/Marengo", "America/Indiana/Marengo", America/Indiana/Petersburg", "America/Indiana/Tell_City", "America/Indiana/Vevay", "America/Indiana/Vincennes", America/Indiana/Winamac", "America/Indianapolis", "America/Iqaluit", "America/Kentucky/Louisville", "America/Kentucky/Louisville", "America/Kentucky/Monticello", "America/Knox_IN", "America/Louisville", "America/Louisville", "America/Managua", "America/Matamoros", "America/Menominee", "America/Merida", "America/Mexico_City", "America/Monterrey", Amérique/Dakota du Nord/Beulah, Amérique/Dakota du Nord/Centre, "America/North_Dakota/New_Salem", "America/Ojinaga", "America/Pangnirtung", "America/Rainy_River", "America/Rankin_Inlet", America/Resolute", "America/Resolute", "America/Tegucigalpa", America/Winnipeg', 'CST6CDT', 'Canada/Central', 'Mexico/General', US/Central', 'US/East-Indiana', 'US/Indiana-Starke']

En production, vous pouvez créer un tel mappage à l'avance et le sauvegarder au lieu de toujours itérer.

Test du script après le changement de fuseau horaire :

$ export TZ='Australia/Sydney'.
$ python get_tz_names.py
["Antarctique/Macquarie", "Australie/ACT", "Australie/Brisbane", Australie/Canberra", "Australie/Currie", "Australie/Hobart", Australie/Lindeman", "Australie/Melbourne", "Australie/NSW", Australie/Queensland", "Australie/Sydney", "Australie/Tasmanie", Australie/Victoria]

18voto

tcurvelo Points 1246

C'est un peu de la triche, je sais, mais passer de '/etc/localtime' ne fonctionne pas pour vous ? J'aime ce qui suit :

>>>  import os
>>> '/'.join(os.readlink('/etc/localtime').split('/')[-2:])
'Australia/Sydney'

J'espère que cela vous aidera.

Modifier : J'ai aimé l'idée de @A.H., au cas où '/etc/localtime' n'est pas un lien symbolique. En traduisant cela en Python :

#!/usr/bin/env python

from hashlib import sha224
import os

def get_current_olsonname():
    tzfile = open('/etc/localtime')
    tzfile_digest = sha224(tzfile.read()).hexdigest()
    tzfile.close()

    for root, dirs, filenames in os.walk("/usr/share/zoneinfo/"):
        for filename in filenames:
            fullname = os.path.join(root, filename)
            f = open(fullname)
            digest = sha224(f.read()).hexdigest()
            if digest == tzfile_digest:
                return '/'.join((fullname.split('/'))[-2:])
            f.close()
        return None

if __name__ == '__main__':
    print get_current_olsonname()

13voto

Tilo Points 13833

Un problème est qu'il y a plusieurs "jolis noms", comme "Australie/Sydney". qui désignent le même fuseau horaire (par exemple CST).

Vous devrez donc obtenir tous les noms possibles pour le fuseau horaire local, puis sélectionner le nom qui vous convient.

Par exemple, pour l'Australie, il y a 5 fuseaux horaires, mais beaucoup plus d'identifiants de fuseaux horaires :

     "Australia/Lord_Howe", "Australia/Hobart", "Australia/Currie", 
     "Australia/Melbourne", "Australia/Sydney", "Australia/Broken_Hill", 
     "Australia/Brisbane", "Australia/Lindeman", "Australia/Adelaide", 
     "Australia/Darwin", "Australia/Perth", "Australia/Eucla"

vous devez vérifier s'il existe un qui englobe TZinfo pour gérer l'API de fuseau horaire.

Par exemple : pour Python, vérifiez le pytz bibliothèque :

http://pytz.sourceforge.net/

et

http://pypi.python.org/pypi/pytz/

en Python que vous pouvez faire :

from pytz import timezone
import pytz

In [56]: pytz.country_timezones('AU')
Out[56]: 
[u'Australia/Lord_Howe',
 u'Australia/Hobart',
 u'Australia/Currie',
 u'Australia/Melbourne',
 u'Australia/Sydney',
 u'Australia/Broken_Hill',
 u'Australia/Brisbane',
 u'Australia/Lindeman',
 u'Australia/Adelaide',
 u'Australia/Darwin',
 u'Australia/Perth',
 u'Australia/Eucla']

mais l'API pour Python semble être assez limitée, par exemple il ne semble pas y avoir d'appel comme celui de Ruby all_linked_zone_names -- qui peut trouver tous les noms synonymes pour un fuseau horaire donné.

8voto

A.H. Points 23369

Si l'on évalue /etc/localtime vous convient, l'astuce suivante pourrait fonctionner - après l'avoir traduite en python :

> md5sum /etc/localtime
abcdefabcdefabcdefabcdefabcdefab /etc/localtime
> find /usr/share/zoneinfo -type f |xargs md5sum | grep abcdefabcdefabcdefabcdefabcdefab
abcdefabcdefabcdefabcdefabcdefab /usr/share/zoneinfo/Europe/London
abcdefabcdefabcdefabcdefabcdefab /usr/share/zoneinfo/posix/Europe/London
...

Les doublons pourraient être filtrés en utilisant uniquement les noms de régions officielles "Europe", "Amérique" ... S'il y a encore des doublons, vous pourriez prendre le nom le plus court :-)

7voto

pcperini Points 11448

Installer pytz

import pytz
import time
#import locale
import urllib2

yourOlsonTZ = None
#yourCountryCode = locale.getdefaultlocale()[0].split('_')[1]
yourCountryCode = urllib2.urlopen('http://api.hostip.info/country.php').read()

for olsonTZ in [pytz.timezone(olsonTZ) for olsonTZ in pytz.all_timezones]:
    if (olsonTZ._tzname in time.tzname) and (str(olsonTZ) in pytz.country_timezones[yourCountryCode]):
        yourOlsonTZ = olsonTZ
        break

print yourOlsonTZ

Ce code va essayer de deviner le fuseau horaire d'Olson en se basant sur le nom du fuseau horaire (selon le langage Python). time ), et votre code de pays (conformément à la directive sur la protection des données). Python locale module le site hostip.info qui fait référence à votre adresse IP et vous géolocalise en conséquence).

Par exemple, le simple fait de faire correspondre les noms de la Timzone pourrait donner les résultats suivants America/Moncton , America/Montreal o America/New_York pour EST (GMT-5). Si votre pays est les États-Unis, cependant, la réponse sera limitée à America/New_York .

Cependant, si votre pays est le Canada, le script choisira simplement par défaut le résultat canadien le plus élevé ( America/Moncton ). S'il y a un moyen d'affiner davantage ce système, n'hésitez pas à laisser des suggestions dans les commentaires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X