2015-10-01 6 views
0

У меня есть строка с датой в формате UTC и tzinfoПреобразовать UTC Дату и время с часовым поясом на местный

"Thu, 01 Oct 2015 00:02:01 +0200" 

Как я могу сделать, чтобы преобразовать его к моему местному времени, поэтому она выдает

"2015-10-02 02:02:01" 

I проверено

parser.parse("Thu, 01 Oct 2015 00:02:01 +0200") 

но я не могу найти способ суммировать этот tzinfo со временем, чтобы получить местное время.

Заранее спасибо

Редактировать: Вопрос Diferent, как он включает в себя время различия в данной строке и точка, чтобы добавить или sutract на этот раз различию, что иногда требуется, чтобы изменить дату, как и в указанном примере.

+0

Возможного дубликат [Python - Преобразование UTC даты и время строки в локальную DateTime] (http://stackoverflow.com/questions/4770297/ python-convert-utc-datetime-string-to-local-datetime) – Prune

+1

Вы имеете в виду 'datetime.strptime (dte,"% a,% d% b% Y% H:% M:% S% z "). astimezone (TZ = нет) '? –

+0

@Prune не совсем то же самое, в этом случае сам часовой пояс неизвестен, только смещение (как строка). Это может быть дубликат, но я не знаю, где это может быть. –

ответ

0

Я думаю, что следующий делает то, что вы хотите, реализовав несколько конкретных tzinfo классов:

from datetime import datetime, timedelta, tzinfo 
import time as _time 

_ZERO = timedelta(0) 
_STDOFFSET = timedelta(seconds=-_time.timezone) 
if _time.daylight: 
    _DSTOFFSET = timedelta(seconds=-_time.altzone) 
else: 
    _DSTOFFSET = _STDOFFSET 

_DSTDIFF = _DSTOFFSET - _STDOFFSET 

class UTC(tzinfo): 
    """ Concrete tzinfo time zone class for UTC 
    """ 
    def utcoffset(self, dt): 
     return _ZERO 
    def tzname(self, dt): 
     return "UTC" 
    def dst(self, dt): 
     return _ZERO 

UTC = UTC() 

class LocalTimezone(tzinfo): 
    """ Concrete tzinfo time zone class for current timezone 
    """ 
    def utcoffset(self, dt): 
     if self._isdst(dt): 
      return _DSTOFFSET 
     else: 
      return _STDOFFSET 

    def dst(self, dt): 
     if self._isdst(dt): 
      return _DSTDIFF 
     else: 
      return _ZERO 

    def tzname(self, dt): 
     return _time.tzname[self._isdst(dt)] 

    # everything depends on this private method which assumes 'dt' argument 
    # is in local time 
    def _isdst(self, dt): 
     tt = (dt.year, dt.month, dt.day, 
       dt.hour, dt.minute, dt.second, 
       dt.weekday(), 0, -1) # last -1 means dst unknown (mktime will fill in) 
     stamp = _time.mktime(tt) # mktime returns secs 
     tt = _time.localtime(stamp) # localtime returns time_struct with tm_isdst attribute 
     return tt.tm_isdst > 0 

LOCAL = LocalTimezone() 

stamp = 'Thu, 01 Oct 2015 00:02:01 +0200' 
dt = datetime(*_time.strptime(' '.join(stamp.split()[:-1]), 
           '%a, %d %b %Y %H:%M:%S')[:6], tzinfo=UTC) 
local_dt = dt.astimezone(LOCAL) 
print(local_dt.strftime('%Y-%M-%d %H:%M:%S')) 
+0

¡Uau! Это работает исправно, но я никогда не думаю, что было бы нужно много работать. Хотя это можно сделать в нескольких строках. – Pep

+0

@Pep: 'LocalTimezone', который использует [' time.timezone', 'time.daylight', может не работать в некоторых случаях с краем на текущее время] (http://stackoverflow.com/a/3168394/4279), и это определенно может провалиться для прошлых/будущих дат, если местное смещение utc могло быть другим в прошлом. – jfs

+0

Да, требуется достаточное количество кода, потому что фондовый Python определяет только абстрактный класс 'tzinfo'. Несмотря на это, то, что я предоставил, является попыткой только достаточно конкретной реализации для решения вашей проблемы общим способом, используя только встроенные модули. Альтернативы, такие как модуль ['pytz'] (https://pypi.python.org/pypi/pytz/), содержат намного больше кода. Потребность в таком количестве кода объясняется удивительной сложностью, казалось бы, простой, но чрезвычайно идиоматической практики (которая, по иронии судьбы, со временем менялась). – martineau

1

Вот STDLIB решение: формат

#!/usr/bin/env python 
from datetime import datetime 
from email.utils import parsedate_tz, mktime_tz 

timestamp = mktime_tz(parsedate_tz("Thu, 01 Oct 2015 00:02:01 +0200")) 
print(datetime.fromtimestamp(timestamp)) # get local time 

ввода времени rfc 5322 time format что understood by email module. datetime.fromtimestamp() может не работать для прошлых/будущих дат, если он не использует базу данных хронологического времени на данной платформе. Портативное решение заключается в использовании pytz модуля, чтобы получить доступ к базе данных TZ:

#!/usr/bin/env python 
from datetime import datetime 
from email.utils import parsedate_tz, mktime_tz 
import tzlocal # $ pip install tzlocal 

local_timezone = tzlocal.get_localzone() # return pytz tzinfo 
timestamp = mktime_tz(parsedate_tz("Thu, 01 Oct 2015 00:02:01 +0200")) 
print(datetime.fromtimestamp(timestamp, local_timezone)) 
+0

Формат входного времени также совместим со старой спецификацией [rfc 2822] (http://tools.ietf.org/html/rfc2822.html#section-3.3), что и является Python 2.x [documentation] (https://docs.python.org/2/library/email.util.html#module-email.utils). Хороший портативный и лаконичный ответ. +1 – martineau

+0

@martineau: rfc 5322 obsoletes 2822 – jfs

+0

Да, я знаю ... только указывал, почему работает более старый код, написанный на rfc 2822. – martineau

Смежные вопросы