strftime python




قم بتحويل سلسلة التاريخ والوقت datetime إلى datetime المحلي مع Python (7)

أقوم عادة بتأجيل ذلك إلى الواجهة الأمامية - أرسل الأوقات من الخلفية كطوابع زمنية أو بعض تنسيق التاريخ والوقت الأخرى في التوقيت العالمي المنسق ، ثم اسمح للعميل باختيار إزاحة المنطقة الزمنية وعرض هذه البيانات في المنطقة الزمنية المناسبة.

بالنسبة إلى تطبيق webapp ، من السهل جدًا إجراؤه في جافا سكريبت - يمكنك معرفة التوقيت المستعرض في المتصفح بسهولة كبيرة باستخدام أساليب مدمجة ، ثم عرض البيانات من الخلفية بشكل صحيح.

لم أضطر أبدًا إلى تحويل الوقت من وإلى UTC. طلب مؤخرًا أن يكون تطبيقي على علم بالمنطقة الزمنية ، وأدير نفسي في دوائر. الكثير من المعلومات حول تحويل التوقيت المحلي إلى التوقيت العالمي المنسق (UTC) ، والذي وجدته بشكل أساسي (ربما أفعل هذا الخطأ أيضًا) ، ولكن لا يمكنني العثور على أي معلومات حول تحويل وقت UTC بسهولة إلى المنطقة الزمنية للمستخدمين النهائيين.

باختصار ، يرسل تطبيق Android البيانات (appengine app) إليّ وضمن تلك البيانات طابع زمني. لتخزين هذا الطابع الزمني لوقت utc ، أستخدم:

datetime.utcfromtimestamp(timestamp)

هذا يبدو أنه يعمل. عندما يخزن تطبيقي البيانات ، يتم تخزينها قبل 5 ساعات (أنا EST -5)

يتم تخزين البيانات على Appengine BigTable ، وعندما يتم استردادها ، تظهر كسلسلة مثل:

"2011-01-21 02:37:21"

كيف يمكنني تحويل هذه السلسلة إلى DateTime في المنطقة الزمنية الصحيحة للمستخدمين؟

أيضًا ، ما التخزين الموصى به لمعلومات المنطقة الزمنية للمستخدمين؟ (كيف تقوم عادة بتخزين معلومات tz مثل: "-5: 00" أو "EST" وما إلى ذلك؟) أنا متأكد من أن الإجابة على سؤالي الأول قد تحتوي على معلمة الإجابات الثانية.


إذا كنت ترغب في الحصول على النتيجة الصحيحة حتى بالنسبة للوقت الذي يتوافق مع التوقيت المحلي الغامض (على سبيل المثال ، أثناء انتقال DST) و / أو يختلف إزاحة utc المحلي في أوقات مختلفة في منطقتك الزمنية المحلية ثم استخدم المنطقة الزمنية pytz :

#!/usr/bin/env python
from datetime import datetime
import pytz    # $ pip install pytz
import tzlocal # $ pip install tzlocal

local_timezone = tzlocal.get_localzone() # get pytz tzinfo
utc_time = datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_timezone)

إليك طريقة مرنة لا تعتمد على أي مكتبات خارجية:

from datetime import datetime
import time

def datetime_from_utc_to_local(utc_datetime):
    now_timestamp = time.time()
    offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
    return utc_datetime + offset

هذا يتجنب مشاكل توقيت في مثال DelboyJay. وقضايا التوقيت الأقل في تعديل إريك فان أوستن.

كحاشية سفلية مثيرة للاهتمام ، يمكن أن يختلف إزاحة المنطقة الزمنية التي تم حسابها أعلاه عن التعبيرات التي تبدو متكافئة في ما يلي ، على الأرجح بسبب تغييرات قاعدة التوفير في ضوء النهار:

offset = datetime.fromtimestamp(0) - datetime.utcfromtimestamp(0) # NO!

تحديث: يحتوي هذا المقتطف على نقطة ضعف في استخدام إزاحة UTC في الوقت الحالي ، والتي قد تختلف عن إزاحة UTC لوقت الإدخال. انظر التعليقات على هذه الإجابة لحل آخر.

للالتفاف على الأوقات المختلفة ، امسك وقت الحقبة من الوقت الذي مرت فيه. وإليك ما أقوم به:

def utc2local (utc):
    epoch = time.mktime(utc.timetuple())
    offset = datetime.fromtimestamp (epoch) - datetime.utcfromtimestamp (epoch)
    return utc + offset

راجع وثائق datetime على كائنات tzinfo . يجب عليك تنفيذ المناطق الزمنية التي تريد دعمها بنفسك. هي أمثلة في الجزء السفلي من الوثائق.

إليك مثال بسيط:

from datetime import datetime,tzinfo,timedelta

class Zone(tzinfo):
    def __init__(self,offset,isdst,name):
        self.offset = offset
        self.isdst = isdst
        self.name = name
    def utcoffset(self, dt):
        return timedelta(hours=self.offset) + self.dst(dt)
    def dst(self, dt):
            return timedelta(hours=1) if self.isdst else timedelta(0)
    def tzname(self,dt):
         return self.name

GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')

print datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z')

t = datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print t
print t.astimezone(EST)

انتاج |

01/22/2011 21:52:09 
01/22/2011 21:52:09 GMT
01/22/2011 16:52:09 EST
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00a

في ما يلي إصدار سريع وقذر يستخدم إعدادات الأنظمة المحلية لتحديد فرق التوقيت. ملاحظة: لن يعمل هذا إذا كنت تحتاج إلى تحويل إلى منطقة زمنية لا يعمل فيها النظام الحالي. لقد قمت باختبار ذلك باستخدام إعدادات المملكة المتحدة في المنطقة الزمنية BST

from datetime import datetime
def ConvertP4DateTimeToLocal(timestampValue):
   assert isinstance(timestampValue, int)

   # get the UTC time from the timestamp integer value.
   d = datetime.utcfromtimestamp( timestampValue )

   # calculate time difference from utcnow and the local system time reported by OS
   offset = datetime.now() - datetime.utcnow()

   # Add offset to UTC time and return it
   return d + offset

يجب أن تكون هذه الإجابة مفيدة إذا كنت لا ترغب في استخدام أي وحدات أخرى إلى جانب datetime .

datetime.utcfromtimestamp(timestamp) بإرجاع كائن datetime ساذج (ليس على علم واحد). إدراك تلك هي المنطقة الزمنية على علم ، والسذاجة ليست كذلك. أنت تريد معرفة واحدة إذا كنت ترغب في التحويل بين المناطق الزمنية (على سبيل المثال بين التوقيت العالمي المنسق والتوقيت المحلي).

إذا لم تكن الشخص الذي يقوم بتأجيل تاريخ البدء به ، ولكن لا يزال بإمكانك إنشاء كائن datetime ساذج في وقت UTC ، فقد ترغب في تجربة هذا الرمز Python 3.x لتحويله:

import datetime

d=datetime.datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S") #Get your naive datetime object
d=d.replace(tzinfo=datetime.timezone.utc) #Convert it to an aware datetime object in UTC time.
d=d.astimezone() #Convert it to your local timezone (still aware)
print(d.strftime("%d %b %Y (%I:%M:%S:%f %p) %Z")) #Print it with a directive of choice

كن حذرًا حتى لا تفترض خطأً أنه إذا كانت منطقتك الزمنية هي MDT حاليًا ، فإن التوفير في ضوء النهار لا يعمل مع الشفرة أعلاه نظرًا لأنه يطبع MST. ستلاحظ أنه إذا قمت بتغيير الشهر إلى أغسطس ، فسوف تطبع MDT.

هناك طريقة أخرى سهلة للحصول على كائن datetime (أيضًا في Python 3.x) وهي إنشاء المنطقة الزمنية المحددة المحددة للبدء بها. إليك مثال على ذلك ، باستخدام UTC:

import datetime, sys

aware_utc_dt_obj=datetime.datetime.now(datetime.timezone.utc) #create an aware datetime object
dt_obj_local=aware_utc_dt_obj.astimezone() #convert it to local time

#The following section is just code for a directive I made that I liked.
if sys.platform=="win32":
    directive="%#d %b %Y (%#I:%M:%S:%f %p) %Z"
else:
    directive="%-d %b %Y (%-I:%M:%S:%f %p) %Z"

print(dt_obj_local.strftime(directive))

إذا كنت تستخدم Python 2.x ، فستحتاج على الأرجح إلى فئة فرعية datetime.tzinfo وتستخدم ذلك لمساعدتك في إنشاء كائن datetime واعي ، نظرًا لأن datetime.timezone غير موجود في Python 2.x.


يمكنك استخدام calendar.timegm لتحويل وقتك إلى ثوانٍ منذ تاريخ Unix و time.localtime لتحويل:

import calendar
import time

time_tuple = time.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
t = calendar.timegm(time_tuple)

print time.ctime(t)

Gives Fri Jan 21 05:37:21 2011 (لأنني في UTC + 03: 00 المنطقة الزمنية).





localtime