डेटाइम के साथ अजगर में UTC टाइमस्टैम्प प्राप्त करें


83

क्या तिथि निर्दिष्ट करके UTC टाइमस्टैम्प प्राप्त करने का कोई तरीका है? मुझे क्या उम्मीद होगी:

datetime(2008, 1, 1, 0, 0, 0, 0)

में परिणाम होना चाहिए

 1199145600

अनुभवहीन डेटाटाइम ऑब्जेक्ट बनाने का अर्थ है कि कोई समय क्षेत्र जानकारी नहीं है। अगर मैं datetime.utcfromtimestamp के लिए दस्तावेज़ीकरण को देखता हूं, तो UTC टाइमस्टैम्प बनाने का अर्थ है समय क्षेत्र की जानकारी को छोड़ना। तो मुझे लगता है, कि एक भोली डेटाइम ऑब्जेक्ट (जैसे मैंने किया) बनाने से UTC टाइमस्टैम्प होगा। तथापि:

then = datetime(2008, 1, 1, 0, 0, 0, 0)
datetime.utcfromtimestamp(float(then.strftime('%s')))

का परिणाम

2007-12-31 23:00:00

क्या अभी भी डेटाइम ऑब्जेक्ट में कोई छिपा हुआ समय क्षेत्र जानकारी है? मैं क्या गलत कर रहा हूं?


मुद्दा यह है then.strftime('%s')कि स्थानीय समय की उम्मीद है लेकिन टाइमस्टैम्प इंगित करता है कि datetime(2008, 1, 1)यूटीसी में है।
jfs

जवाबों:


91

Nave datetimeबनाम जागरूकdatetime

डिफ़ॉल्ट datetimeवस्तुओं को "भोला" कहा जाता है: वे समय क्षेत्र की जानकारी के बिना समय की जानकारी रखते हैं। एक स्पष्ट datetimeसंख्या के +4बिना भोले के बारे में सोचें (अर्थात :) वास्तव में (आपकी उत्पत्ति आपके सिस्टम की सीमा के दौरान सामान्य होगी)।

इसके विपरीत, पूरी दुनिया के लिए एक सामान्य मूल के साथ datetimeपूर्ण संख्या (यानी :) के रूप में जागरूक के बारे में सोचें 8

समय -सीमा की जानकारी के बिना आप किसी भी गैर-भोले समय प्रतिनिधित्व के लिए "भोले" डेटाइम को परिवर्तित नहीं कर सकते हैं (जहां +4हम शुरू नहीं करते हैं, तो लक्ष्य क्या होता है?)। यही कारण है कि आपके पास कोई datetime.datetime.toutctimestamp()विधि नहीं हो सकती है । (cf: http://bugs.python.org/issue1457227 )

यह जाँचने के लिए कि क्या आपका datetime dtभोला है, जाँच करें dt.tzinfo, यदि None, तो यह भोला है:

datetime.now()        ## DANGER: returns naïve datetime pointing on local time
datetime(1970, 1, 1)  ## returns naïve datetime pointing on user given time

मेरे पास भोले-भाले आंकड़े हैं, मैं क्या कर सकता हूं?

आपको अपने विशेष संदर्भ के आधार पर एक धारणा बनानी चाहिए: जो सवाल आपको खुद से पूछना चाहिए वह यह है: क्या आपका datetimeयूटीसी था? या यह स्थानीय समय था?

  • यदि आप UTC का उपयोग कर रहे थे (आप परेशानी से बाहर हैं):

    import calendar
    
    def dt2ts(dt):
        """Converts a datetime object to UTC timestamp
    
        naive datetime will be considered UTC.
    
        """
    
        return calendar.timegm(dt.utctimetuple())
    
  • यदि आप UTC का उपयोग नहीं कर रहे थे , तो नरक में आपका स्वागत है।

    आपको अपने datetimeगैर-भोलेपन को पूर्व कार्य का उपयोग करने से पहले करना होगा, उन्हें अपने इच्छित समय को वापस देकर।

    आपको टारगेट के नाम की आवश्यकता होगी और लक्ष्य भोले डेटाइम (डीएसटी के बारे में अंतिम जानकारी कॉर्नसेरकेस के लिए आवश्यक है) का उत्पादन करते समय डीएसटी लागू होने के बारे में जानकारी:

    import pytz     ## pip install pytz
    
    mytz = pytz.timezone('Europe/Amsterdam')             ## Set your timezone
    
    dt = mytz.normalize(mytz.localize(dt, is_dst=True))  ## Set is_dst accordingly
    

    प्रदान नहीं करने के परिणामis_dst :

    उपयोग न करने is_dstसे गलत समय उत्पन्न होगा (और UTC टाइमस्टैम्प) यदि लक्ष्य डेटाइम का उत्पादन किया गया था, जबकि एक पिछड़े डीएसटी को लागू किया गया था (उदाहरण के लिए एक घंटे को हटाकर डीएसटी समय को बदलना)।

    is_dstनिश्चित रूप से गलत इच्छाशक्ति प्रदान करना केवल डीएसटी ओवरलैप या छेद पर गलत समय (और यूटीसी टाइमस्टैम्प) उत्पन्न करेगा। और, जब गलत समय प्रदान करते हैं, तो "छेद" (समय जो कि आगे की शिफ्टिंग डीएसटी के कारण कभी भी अस्तित्व में नहीं है) में उत्पन्न होता है, is_dstइस फर्जी समय पर विचार करने के तरीके की व्याख्या देगा, और यह एकमात्र मामला है जहां .normalize(..)वास्तव में यहां कुछ किया जाएगा, जैसा कि तब यह एक वास्तविक वैध समय के रूप में अनुवाद करेगा (यदि आवश्यक हो तो डेटाटाइम और डीएसटी ऑब्जेक्ट को बदलते हुए)। ध्यान दें कि .normalize()अंत में एक सही UTC टाइमस्टैम्प होने के लिए आवश्यक नहीं है, लेकिन शायद यह अनुशंसा की जाती है कि आप अपने चर में बोगस बार होने के विचार को नापसंद करते हैं, खासकर यदि आप इस चर को फिर से उपयोग करते हैं।

    और निम्नलिखित का उपयोग करते हुए बचाओ : (cf: Pytz का उपयोग करते हुए डेटाटाइम रूपांतरण )

    dt = dt.replace(tzinfo=timezone('Europe/Amsterdam'))  ## BAD !!
    

    क्यों? क्योंकि लक्ष्य समय को ध्यान में .replace()रखे tzinfoबिना नेत्रहीन रूप से प्रतिस्थापित करता है और एक खराब डीएसटी वस्तु का चयन करेगा। जबकि सही DST ऑब्जेक्ट का चयन करने के .localize()लिए लक्ष्य समय और आपके is_dstसंकेत का उपयोग करता है ।

OLD का गलत उत्तर (इसे लाने के लिए धन्यवाद @JFSebastien):

उम्मीद है, जब आप अपनी भोली datetimeवस्तु बनाते हैं, तो समय-सारणी (आपकी स्थानीय उत्पत्ति) का अनुमान लगाना काफी आसान होता है क्योंकि यह सिस्टम कॉन्फ़िगरेशन से संबंधित है जिसे आप उम्मीद करते हैं कि आप भोले-भाले वस्तु निर्माण और उस पल के बीच नहीं बदलेंगे जब आप प्राप्त करना चाहते हैं। UTC टाइमस्टैम्प। इस ट्रिक का इस्तेमाल अपूर्ण प्रश्न देने के लिए किया जा सकता है ।

उपयोग करके time.mktimeहम एक बना सकते हैं utc_mktime:

def utc_mktime(utc_tuple):
    """Returns number of seconds elapsed since epoch

    Note that no timezone are taken into consideration.

    utc tuple must be: (year, month, day, hour, minute, second)

    """

    if len(utc_tuple) == 6:
        utc_tuple += (0, 0, 0)
    return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))

def datetime_to_timestamp(dt):
    """Converts a datetime object to UTC timestamp"""

    return int(utc_mktime(dt.timetuple()))

आपको यह सुनिश्चित करना चाहिए कि आपकी datetimeवस्तु उसी टाइमज़ोन पर बनाई गई है जो आपने बनाई है datetime

यह अंतिम समाधान गलत है क्योंकि यह धारणा बनाता है कि UTC ऑफसेट अब से UTC ऑफसेट की तुलना में समान है। जो बहुत सारे टाइमज़ोन (डेलाइट सेविंग टाइम (डीएसटी) ऑफसेट के लिए वर्ष के विशिष्ट क्षण में) के लिए मामला नहीं है)।


4
Naive डेटाटाइम ऑब्जेक्ट को हमेशा UTC में समय का प्रतिनिधित्व करना चाहिए। अन्य टाइमज़ोन का उपयोग केवल I / O (प्रदर्शन) के लिए किया जाना चाहिए। नहीं है datetime.timestamp()अजगर 3.3 में विधि।
jfs

2
time.mktime()केवल स्थानीय समय के लिए उपयोग किया जाना चाहिए। calendar.timegm()इस्तेमाल किया जा सकता है utc समय tuple को पॉज़िक्स टाइमस्टैम्प में बदलने के लिए। या बेहतर अभी तक केवल डेटाइम तरीकों का उपयोग करें। मेरा जवाब
jfs

4
-1। आपका कोड मानता है कि स्थानीय समय क्षेत्र में utc_offset (अब) और utc_offset (युग) समान हैं। 116 टाइमज़ोन (430 आम टाइमज़ोन से) में ऐसा नहीं है।
jfs

1
अभी भी -1: .replace()एक समय-सीमा के साथ उपयोग न करें जिसमें एक गैर-फिक्स्ड utc ऑफसेट है जैसे 'Europe/Amsterdam'Pytz का उपयोग करके डेटाटाइम टाइमज़ोन रूपांतरण देखें ।
JFS

1
1- क्या आप समझते हैं कि आपको क्यों नहीं इस्तेमाल करना चाहिए .replace(tzinfo=get_localzone())? 2- पहले से ही timegm()रिटर्न int। इसके साथ लपेटने की आवश्यकता नहीं है int। इसके अलावा, .timetuple()एक दूसरे के अंशों को गिराता है।
jfs

30

एक और संभावना है:

d = datetime.datetime.utcnow()
epoch = datetime.datetime(1970,1,1)
t = (d - epoch).total_seconds()

यह "d" और "युग" दोनों के रूप में काम करता है, भोले डेटासेटाइम हैं, जिससे "-" ऑपरेटर वैध हो जाता है, और एक अंतराल लौट आता है। total_seconds()अंतराल को सेकंड में बदल देता है। ध्यान दें कि total_seconds()एक फ्लोट लौटाता है, यहां तक ​​किd.microsecond == 0


12
ठीक नहीं, विचार समान है लेकिन यह समझने में आसान है :)
नटिम

3
आपको लगता है कि टाइम लाइब्रेरी या कुछ और में एक ही तरीका होगा ... शीश
wordsforthewise

टाइमस्टैम्प प्राप्त करने के लिए, datetime.datetime.utcnow ()। टाइमस्टैम्प ()
यूजीन

21

इस ब्लॉग प्रविष्टि द्वारा वर्णित कैलेंडर . timegm () फ़ंक्शन पर भी ध्यान दें :

import calendar
calendar.timegm(utc_timetuple)

आउटपुट को वाब के समाधान से सहमत होना चाहिए।


13

यदि इनपुट डेटाटाइम ऑब्जेक्ट UTC में है:

>>> dt = datetime(2008, 1, 1, 0, 0, 0, 0)
>>> timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
1199145600.0

नोट: यह फ्लोट करता है यानी, microseconds को एक सेकंड के अंश के रूप में दर्शाया जाता है।

यदि इनपुट दिनांक ऑब्जेक्ट UTC में है:

>>> from datetime import date
>>> utc_date = date(2008, 1, 1)
>>> timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
1199145600

पाइथन में UTC टाइमस्टैम्प पर डेटाटाइमटाइम में परिवर्तित करने के लिए अधिक विवरण देखें ।


8

मुझे लगता है कि मुख्य उत्तर अभी भी इतना स्पष्ट नहीं है, और यह समय और समय-क्षेत्र समझने के लिए समय लेने के लायक है ।

समय के साथ व्यवहार करते समय समझने के लिए सबसे महत्वपूर्ण बात यह है कि समय सापेक्ष है !

  • 2017-08-30 13:23:00: (एक भोली उम्र), दुनिया में कहीं एक स्थानीय समय का प्रतिनिधित्व करता है, लेकिन ध्यान दें कि 2017-08-30 13:23:00लंदन में सैन फ्रांसिस्को के रूप में एक ही समय नहीं है2017-08-30 13:23:00

क्योंकि एक ही समय स्ट्रिंग को विभिन्न बिंदुओं के रूप में व्याख्या की जा सकती है, जहां आप दुनिया में हैं, इस आधार पर समय की एक पूर्ण धारणा की आवश्यकता है।

एक यूटीसी टाइमस्टैम्प सेकंड (या मिलीसेकंड) में एक संख्या है से युग (के रूप में परिभाषित 1 January 1970 00:00:00पर GMT: 00 ऑफसेट समयक्षेत्र 00)।

युग GMT टाइमज़ोन पर लंगर डाला गया है और इसलिए समय में एक निरपेक्ष बिंदु है। एक UTC टाइमस्टैम्प एक निरपेक्ष समय से एक ऑफसेट है इसलिए समय में एक निरपेक्ष बिंदु को परिभाषित करता है ।

यह समय में घटनाओं को आदेश देना संभव बनाता है।

समय-क्षेत्र की जानकारी के बिना, समय सापेक्ष है, और समय-समय पर एक पूर्ण धारणा में परिवर्तित नहीं किया जा सकता है कि किस समय में भोले डेटाइम को एंकर किया जाना चाहिए, इसके कुछ संकेत दिए बिना।

कंप्यूटर सिस्टम में किस प्रकार के समय का उपयोग किया जाता है?

  • भोली उम्र : आमतौर पर प्रदर्शन के लिए, स्थानीय समय में (यानी ब्राउज़र में) जहां ओएस कार्यक्रम के लिए समय क्षेत्र की जानकारी प्रदान कर सकता है।

  • UTC टाइमस्टैम्प : UTC टाइमस्टैम्प समय का एक पूर्ण बिंदु है, जैसा कि ऊपर बताया गया है, लेकिन यह किसी दिए गए टाइमज़ोन में लंगर डाले हुए है, इसलिए UTC टाइमस्टैम्प को किसी भी समयक्षेत्र में डेटाइम में बदला जा सकता है , हालाँकि इसमें टाइमज़ोन की जानकारी नहीं है । इसका क्या मतलब है? इसका मतलब है कि 1504119325 2017-08-30T18:55:24Z, या 2017-08-30T17:55:24-0100या के अनुरूप है 2017-08-30T10:55:24-0800। यह आपको नहीं बताता कि रिकॉर्ड किया गया डेटटाइम कहां से है। यह आमतौर पर सर्वर की ओर से घटनाओं (लॉग, आदि ...) को रिकॉर्ड करने के लिए उपयोग किया जाता है या समयक्षेत्र के बारे में जागरूक डेटाइम को समय में एक निरपेक्ष बिंदु में परिवर्तित करने और समय के अंतर की गणना करने के लिए उपयोग किया जाता है ।

  • ISO-8601 डेटाइम स्ट्रिंग: ISO-8601 टाइमज़ोन के साथ डेटाटाइम रिकॉर्ड करने के लिए एक मानकीकृत प्रारूप है। (यह वास्तव में कई स्वरूपों में है, यहां पर पढ़ें: https://en.wikipedia.org/wiki/ISO_8601 ) इसका उपयोग सिस्टम के बीच क्रमबद्ध तरीके से टाइमज़ोन जागरूक डेटाटाइम जानकारी को संप्रेषित करने के लिए किया जाता है।

कब कौन सा उपयोग करें? या जब आप timezones के बारे में परवाह करने की जरूरत है?

  • यदि आपको किसी भी तरह से समय-समय पर देखभाल करने की आवश्यकता है, तो आपको समय-सीमा की जानकारी चाहिए। एक कैलेंडर या अलार्म को दुनिया के किसी भी उपयोगकर्ता के लिए दिन के सही समय पर बैठक सेट करने के लिए समय की आवश्यकता होती है। यदि यह डेटा किसी सर्वर पर सहेजा गया है, तो सर्वर को यह जानने की जरूरत है कि डेटाटाइम किस समय से मेल खाता है।

  • दुनिया में विभिन्न स्थानों से आने वाली घटनाओं के बीच समय के अंतर की गणना करने के लिए, यूटीसी टाइमस्टैम्प पर्याप्त है, लेकिन आप दिन की घटनाओं का विश्लेषण करने की क्षमता खो देते हैं (यानी वेब विश्लेषिकी के लिए, आप जानना चाहते हैं कि उपयोगकर्ता आपके कब आते हैं। अपने स्थानीय समय में साइट : क्या आप सुबह या शाम को अधिक उपयोगकर्ता देखते हैं? आप दिन की जानकारी के बिना यह पता नहीं लगा सकते हैं।

दिनांक स्ट्रिंग में टाइमज़ोन ऑफसेट :

एक और बिंदु जो महत्वपूर्ण है, वह यह है कि एक तारीख स्ट्रिंग में ओजोन ऑफसेट तय नहीं है । इसका मतलब यह है कि क्योंकि 2017-08-30T10:55:24-0800ऑफसेट -0800या 8 घंटे पहले कहते हैं , इसका मतलब यह नहीं है कि यह हमेशा रहेगा!

गर्मियों में यह दिन के समय की बचत में अच्छी तरह से हो सकता है, और यह होगा -0700

क्या इसका मतलब है कि है समय क्षेत्र ऑफसेट (+0100) के समान नहीं है समय क्षेत्र का नाम (यूरोप / फ्रांस) या यहां तक कि (सीईटी) समय क्षेत्र पदनाम

America/Los_Angelesटाइमज़ोन दुनिया में एक जगह है , लेकिन यह PSTसर्दियों में (पैसिफ़िक स्टैंडर्ड टाइम) टाइमज़ोन ऑफसेट नोटेशन और PDTगर्मियों में (पैसिफ़िक डेलाइट टाइम) में बदल जाती है।

तो, डेटस्ट्रीमिंग से टाइमज़ोन ऑफसेट होने के शीर्ष पर, आपको टाइमज़ोन नाम भी सटीक होना चाहिए।

अधिकांश पैकेज सांख्यिक ऑफसेट को दिन के समय की बचत के समय से मानक समय तक अपने दम पर परिवर्तित करने में सक्षम होंगे, लेकिन यह केवल ऑफसेट के साथ तुच्छ नहीं है। उदाहरण के लिए WATपश्चिम अफ्रीका में टाइमज़ोन पदनाम, CETफ्रांस में टाइमज़ोन की तरह ही UTC + 0100 है , लेकिन फ्रांस दिन के समय की बचत को देखता है, जबकि पश्चिम अफ्रीका ऐसा नहीं करता (क्योंकि वे भूमध्य रेखा के करीब हैं)

तो, संक्षेप में, यह जटिल है। बहुत जटिल है, और यही कारण है कि आपको यह स्वयं नहीं करना चाहिए, लेकिन एक पैकेज पर विश्वास करें जो आपके लिए करता है, और KATEP IT UP TO TO!


पायथन में दिनांक और समय के बारे में मेरे ब्लॉग पोस्ट को देखें अलग-अलग पैकेजों के नुकसान को समझने के लिए medium.com/@eleroy/…
MrE

3

बाहरी मॉड्यूल का उपयोग किए बिना एक सरल समाधान:

from datetime import datetime, timezone

dt = datetime(2008, 1, 1, 0, 0, 0, 0)
int(dt.replace(tzinfo=timezone.utc).timestamp())

2

Utcfromtimestamp का उपयोग करने और समय क्षेत्र निर्दिष्ट करने के साथ वास्तव में एक समस्या है। एक अच्छा उदाहरण / स्पष्टीकरण निम्नलिखित प्रश्न पर उपलब्ध है:

यूनिक्स समय में परिवर्तित करते समय समय क्षेत्र (यूटीसी) कैसे निर्दिष्ट करें? (अजगर)


1

मुझे लगता है कि आपके प्रश्न को वाक्यांश करने का सही तरीका है Is there a way to get the timestamp by specifying the date in UTC?, क्योंकि टाइमस्टैम्प सिर्फ एक संख्या है जो निरपेक्ष है, सापेक्ष नहीं। रिश्तेदार (या टाइमजोन जागरूक) टुकड़ा तारीख है।

मुझे टाइमपास के लिए पांडा बहुत सुविधाजनक लगते हैं, इसलिए:

import pandas as pd
dt1 = datetime(2008, 1, 1, 0, 0, 0, 0)
ts1 = pd.Timestamp(dt1, tz='utc').timestamp()
# make sure you get back dt1
datetime.utcfromtimestamp(ts1)  

पांडा का उपयोग करना IMHO सही दृष्टिकोण है, वर्तमान समय के लिए भी t = Timestamp.utcnow () सीधे सही समय पाने के लिए :)
ntg

0

स्वीकृत उत्तर मेरे लिए काम नहीं करता है। मेरा समाधान:

import time
utc_0 = int(time.mktime(datetime(1970, 01, 01).timetuple()))
def datetime2ts(dt):
    """Converts a datetime object to UTC timestamp"""
    return int(time.mktime(dt.utctimetuple())) - utc_0

यह विफल रहता है अगर dtस्थानीय समयक्षेत्र और 1970 में UTC की वर्तमान ( ) भिन्नता हो। mktime()स्थानीय समय की अपेक्षा करता है।
jfs

0

सबसे सरल तरीका:

>>> from datetime import datetime
>>> dt = datetime(2008, 1, 1, 0, 0, 0, 0)
>>> dt.strftime("%s")
'1199163600'

संपादित करें: @ डैनियल सही है, यह इसे मशीन के टाइमज़ोन में बदल देगा। यहाँ एक संशोधित जवाब है:

>>> from datetime import datetime, timezone
>>> epoch = datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc)
>>> dt = datetime(2008, 1, 1, 0, 0, 0, 0, timezone.utc)
>>> int((dt-epoch).total_seconds())
'1199145600'

वास्तव में, यह निर्दिष्ट करने के लिए भी आवश्यक नहीं है timezone.utc, क्योंकि समय का अंतर समान है, जब तक दोनों datetimeमें एक ही समयक्षेत्र (या कोई समयक्षेत्र) नहीं है।

>>> from datetime import datetime
>>> epoch = datetime(1970, 1, 1, 0, 0, 0, 0)
>>> dt = datetime(2008, 1, 1, 0, 0, 0, 0)
>>> int((dt-epoch).total_seconds())
1199145600

यह विधि utc पर वापस नहीं आती है, बल्कि वर्तमान समय के लिए डेटाटाइम समायोजित करती है। अर्थात। अगर अब tz +3 में 12am है, तो यह 9:00 युग में वापस आ जाएगा।
डैनियल डुबोव्स्की

आह आप सही हैं। मेरा टाइमजोन UTC था - यही वजह है कि इसने काम किया।
फरवरी को माइक फुरलेंडर

आप (अजगर 3.2 और नए) का उपयोग करने जा रहे हैं, तो timezone.utcवस्तु है, तो बस का उपयोग करने वाले के साथ .timestamp(): datetime(2008, 1, 1, tzinfo=timezone.utc).timestamp()। एक युग वस्तु बना सकते हैं और घटाना .. की आवश्यकता नहीं है
मार्टिन पीटर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.