यूनिक्स टाइमस्टैम्प में डेटाइम बदलें और इसे अजगर में वापस कन्वर्ट करें


186

मेरे पास है dt = datetime(2013,9,1,11), और मैं इस डेटाटाइम ऑब्जेक्ट का यूनिक्स टाइमस्टैम्प प्राप्त करना चाहूंगा।

जब मैं करता (dt - datetime(1970,1,1)).total_seconds()हूं मुझे टाइमस्टैम्प मिला है 1378033200

जब datetime.fromtimestampमैं इसे का उपयोग कर वापस मिल गया datetime.datetime(2013, 9, 1, 6, 0)

घंटा मेल नहीं खाता। मुझे यहाँ क्या याद आया?



1
एक साइड नोट के रूप में, यदि आप Python 3.3+ का उपयोग कर रहे हैं, तो आप वास्तव में, वास्तव में timestampइसे स्वयं करने का प्रयास करने के बजाय विधि का उपयोग करना चाहते हैं । एक बात के लिए, यह पूरी तरह से अलग-अलग टाइमज़ोन से भोलेपन को घटाने की संभावना से बचता है।
अबार्नेट

1
कहाँ dtसे आता है? क्या यह यूटीसी में स्थानीय समय या समय है?
jfs

2
@abarnert मैं सभी कोडपेस और यूनिकोड प्रतीकों को शुद्ध करने के लिए एक अनुरोध प्रस्तुत करना चाहता हूं, जो कि सभी गैर-असिसी और गैर-डिफ़ॉल्ट-कोडपेज भाषाओं को रेखांकित करने के लिए है। प्रतीकों की पेंटिंग अभी भी अनुमति दी जाती है।
डेनियल एफ

6
@ डैनियलएफ: अनुरोध अस्वीकृत। मैं यहाँ एक विश्व-भाषा बनाने में दिलचस्पी नहीं रखता, और अगर हमने किया भी तो मैं ऐतिहासिक भाषाविदों और टॉलिकेन विद्वानों के लिए जीवन को असंभव नहीं बनाना चाहता। यूनिकोड पहले से ही समस्या को हल करता है, सिवाय इसके कि कुछ संगठनों और उत्पादों (TRON कंसोर्टियम, जापानी सॉफ्टवेयर जो UTF-8 पर Shift-JIS का उपयोग करता है, Microsoft अभी भी एक OS वितरित करता है जो उपयोगकर्ता पाठ फ़ाइलों के लिए cp1252 के लिए चूक करता है, और विभिन्न SDK जो उस UTF का ढोंग करते हैं। -16 एक निश्चित-चौड़ाई वाला चारसेट है और / या यूनिकोड जैसी ही चीज) उन्हें लाइन में लाने के लिए दंडित करने की आवश्यकता है।
19

जवाबों:


105

यहां जो आपने याद किया वह टाइमजोन है।

संभवत: आपने UTC से पांच घंटे की छुट्टी ली है, इसलिए 2013-09-01T11: 00: 00 स्थानीय और 2013-09-01T06: 00: 00Z एक ही समय हैं।

आपको datetimeडॉक्स के शीर्ष को पढ़ने की आवश्यकता है , जो टाइमज़ोन और "भोले" और "जागरूक" वस्तुओं के बारे में बताते हैं।

यदि आपका मूल भोली डेटाइम UTC था, तो इसे पुनर्प्राप्त करने का तरीका utcfromtimestampइसके बजाय उपयोग करना है fromtimestamp

दूसरी ओर, यदि आपका मूल भोला जीवनकाल स्थानीय था, तो आपको पहले स्थान पर एक यूटीसी टाइमस्टैम्प को घटाया नहीं जाना चाहिए था; datetime.fromtimestamp(0)इसके बजाय का उपयोग करें ।

या, यदि आपके पास एक जागरूक डेटाटाइम ऑब्जेक्ट था, तो आपको या तो स्थानीय (जागरूक) युग का उपयोग करने की आवश्यकता है, या यूटीसी से और स्पष्ट रूप से परिवर्तित करें।

यदि आपके पास है, या पाइथन 3.3 या बाद में अपग्रेड कर सकते हैं, तो आप इन timestampतरीकों से इन सभी समस्याओं से बच सकते हैं, बजाय इसके कि आप कैसे करें, यह जानने की कोशिश करें। और यदि आप नहीं भी करते हैं, तो आप इसके स्रोत कोड को उधार लेने पर विचार कर सकते हैं ।

(और यदि आप पायथॉन 3.4 के लिए इंतजार कर सकते हैं, तो ऐसा लगता है कि पीईपी 341 को अंतिम रिलीज़ में बनाने की संभावना है, जिसका मतलब है कि सभी सामान जेएफ सेबेस्टियन और मैं टिप्पणियों के बारे में बात कर रहे थे, बस स्टालिब के साथ उचित होना चाहिए, और यूनिक्स और विंडोज दोनों पर एक ही तरह से काम करना।)


1
यदि dtस्थानीय समय क्षेत्र में है तो प्रश्न में सूत्र गलत है datetime.fromtimestamp(0)(वर्तमान समय क्षेत्र में युगीन) का उपयोग इसके बजाय datetime(1970, 1,1)(यूटीसी में यूनिक्स युग ) किया जाना चाहिए ।
jfs

@JFSebastian: मैं विस्तार से सभी तीन संभावनाओं को कवर नहीं करना चाहता था, लेकिन मुझे लगता है कि आप सही हैं, मुझे करना चाहिए।
अबर्नेट

btw, fromtimestamp(0)विफल हो सकता है यदि सिस्टम ऐतिहासिक टाइमज़ोन जानकारी को संग्रहीत नहीं करता है, उदाहरण के लिए, विंडोज पर। pytzइस मामले में इस्तेमाल किया जा सकता है।
jfs

@JFSebastian: लेकिन pytzतब तक मदद नहीं करता जब तक आप पहले से ही नहीं जानते कि आप किस टाइमज़ोन में हैं; प्रोग्रामेटिक रूप से ऐसा करने के लिए, आपको एक अलग लाइब्रेरी की आवश्यकता होती है, जो वर्तमान विंडोज़ टाइमज़ोन को प्राप्त करती है और इसे टाइमज़ोन में परिवर्तित करती है pytzऔर / या इसे नाम से देखती है।
अपहरण

वहाँ tzlocalमॉड्यूल भी विंडोज पर काम करता है। यहां बताया गया है कि आप स्थानीय समय में utc समय कैसे बदल सकते हैं
jfs

141

समाधान है

import time
import datetime
d = datetime.date(2015,1,5)

unixtime = time.mktime(d.timetuple())

12
यह मानता है कि dएक भोली तारीख / डेटाटाइम ऑब्जेक्ट है जो स्थानीय समय का प्रतिनिधित्व करता है (यह अस्पष्ट समय के लिए या अतीत / भविष्य की तारीखों के लिए विफल हो सकता है अगर ओएस एक ऐतिहासिक tz db प्रदान नहीं करता है (UTC ऑफसेट स्थानीय में अतीत में भिन्न हो सकता है) समय क्षेत्र))। अधिक विकल्प
JFS

6
ऐसा लगता है कि कोई भी दिमाग फ़्लोटिंग पॉइंट समाधान नहीं करता है। क्या यह सभी के लिए स्पष्ट है?
इवान बालाशोव

4
इससे माइक्रोसेकंड गिर जाता है। दिलचस्प हो सकता है।
अल्फ

केवल समस्या यह है कि आप समय-सीमा को ध्यान में नहीं रखते हैं।
ब्लेयरग 2323

यह नहीं होना चाहिए यदि आपको TZ को समायोजित करने की आवश्यकता है, तो आपको पहले ऐसा करने की आवश्यकता है।
Marcin Orlowski

69

यदि आप एक अजगर डेटाइम को सेकंड में बदलना चाहते हैं, तो आपको इसे स्पष्ट रूप से करना चाहिए:

>>> import datetime
>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'
>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0

पायथन 3.3+ में आप timestamp()इसके बजाय उपयोग कर सकते हैं :

>>> import datetime
>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0

5
टाइमज़ोन को ध्यान में नहीं रखता है।
ब्लेयरग

3
आप उपयोग नहीं करना चाहते हैं %s, क्योंकि यह उस सिस्टम की घड़ी के लिए स्थानीयकृत होगा, जिस पर आप वर्तमान में हैं। आपको केवल .timestamp()सही युग / UNIX समय प्राप्त करने के लिए उपयोग करना चाहिए ।
ब्लेयरग 23

3
%sविंडोज सिस्टम पर काम नहीं करता है ( ValueError: Invalid format string)
chrki

1
@ amitnair92 बस डाल 8या9
फ्रांसिस्को कोस्टा

54

POSIX टाइमस्टैम्प बनाने के लिए इस अभिव्यक्ति के बजाय dt,

(dt - datetime(1970,1,1)).total_seconds()

इसे इस्तेमाल करो:

int(dt.strftime("%s"))

मुझे दूसरी विधि का उपयोग करके आपके उदाहरण में सही उत्तर मिलता है।

संपादित करें: कुछ फॉलोअप ... के बाद कुछ टिप्पणियां (नीचे देखें), मैं समर्थन या के लिए दस्तावेज की कमी के बारे में उत्सुक था %sमें strftime। यहाँ मैं क्या पाया:

में अजगर स्रोत के लिए datetimeऔर time, स्ट्रिंग STRFTIME_FORMAT_CODESहमें बताता है:

"Other codes may be available on your platform.
 See documentation for the C library strftime function."

तो अब अगर हम man strftime(मैक ओएस एक्स जैसे बीएसडी सिस्टम पर), तो आपको इसके लिए समर्थन मिलेगा %s:

"%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3))."

वैसे भी, इसीलिए %sयह सिस्टम पर काम करता है। लेकिन ओपी की समस्या के बेहतर समाधान हैं (जो टाइमजोन को ध्यान में रखते हैं)। यहाँ देखें @ abarnert का स्वीकृत उत्तर।


4
यह अनिर्दिष्ट व्यवहार है (मेरा मानना ​​है)। उदाहरण के लिए खिड़कियों पर यह "अमान्य प्रारूप स्ट्रिंग" में परिणामित होता है।
क्रिसेंट फ्रेश

@CrescentFresh, दिलचस्प। आप शायद सही हो सकते हैं। जब मैं strftime("%s")दस्तावेज़ीकरण में नहीं दिखता , तो मैंने मैक और लिनक्स पर काम करने के लिए इसकी पुष्टि की। धन्यवाद।
डैरेन स्टोन

1
जाहिरा तौर पर यह tzinfo क्षेत्र की उपेक्षा करता है।
डेनियल एफ

1
@DarrenStone: आपको स्रोत पढ़ने की आवश्यकता नहीं है। दोनों time.strftime()और datetime.strftimeप्रलेखन strftime(3)असमर्थित निर्देशों के लिए प्लेटफ़ॉर्म फ़ंक्शन को सौंपते हैं । %sमैक ओएस एक्स जैसे पर भी विफल हो सकता है, datetime.strftime ('% s') tzinfo का सम्मान करना चाहिए
jfs

1
आपको कभी भी उपयोग नहीं करना चाहिए %sक्योंकि आप केवल उस सिस्टम के स्थानीयकृत समय का उपयोग करेंगे जिस पर आप हैं। .timestamp()यदि आप वास्तविक UNIX टाइमस्टैम्प प्राप्त करने का प्रयास कर रहे हैं तो आप इसका उपयोग करना चाहते हैं।
ब्लेयरग 23

6

यूटीसी टाइमज़ोन के साथ काम करने के लिए:

time_stamp = calendar.timegm(dt.timetuple())

datetime.utcfromtimestamp(time_stamp)

एक घंटे की खोज के बाद, यह एकमात्र उत्तर था जिसने काम किया: ')
कुरैशी

4

आपने समय क्षेत्र की जानकारी को याद कर लिया है (पहले से ही उत्तर दिया, सहमत)

arrowपैकेज डेटासेट के साथ इस यातना से बचने की अनुमति देता है; यह पहले से ही लिखा, परीक्षण किया हुआ, पीपा-प्रकाशित, क्रॉस-पाइथन (2.6 - 3.xx) है।

आप सभी की जरूरत है: pip install arrow(या निर्भरता में जोड़ें)

अपने मामले के लिए समाधान

dt = datetime(2013,9,1,11)
arrow.get(dt).timestamp
# >>> 1378033200

bc = arrow.get(1378033200).datetime
print(bc)
# >>> datetime.datetime(2013, 9, 1, 11, 0, tzinfo=tzutc())
print(bc.isoformat())
# >>> '2013-09-01T11:00:00+00:00'

3

यदि आपका डेटाटाइम ऑब्जेक्ट UTC समय का प्रतिनिधित्व करता है, तो time.mktime का उपयोग न करें, क्योंकि यह मानता है कि टपल आपके स्थानीय समय क्षेत्र में है। इसके बजाय, Calendar.timegm का उपयोग करें:

>>> import datetime, calendar
>>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
>>> calendar.timegm(d.timetuple())
60

2

खैर, जब यूनिक्स टाइमस्टैम्प में परिवर्तित हो रहा है, तो अजगर मूल रूप से यूटीसी मान रहा है, लेकिन वापस परिवर्तित करते समय यह आपको अपने स्थानीय समय क्षेत्र में परिवर्तित होने की तारीख देगा।

इस प्रश्न / उत्तर को देखें; Datetime.datetime.fromtimestamp () द्वारा उपयोग किया जाने वाला टाइमज़ोन प्राप्त करें


1
def dt2ts(dt, utc=False):
    if utc:
        return calendar.timegm(dt.timetuple())
    if dt.tzinfo is None:
        return int(time.mktime(dt.timetuple()))
    utc_dt = dt.astimezone(tz.tzutc()).timetuple()
    return calendar.timegm(utc_dt)

यदि आप UTC टाइमस्टैम्प चाहते हैं: time.mktimeसिर्फ स्थानीय dt के लिए। उपयोग calendar.timegmसुरक्षित है लेकिन dt को utc ज़ोन होना चाहिए ताकि ज़ोन को utc में बदल दें। यदि UTC में dt अभी उपयोग करें calendar.timegm


1
def datetime_to_epoch(d1):

    # create 1,1,1970 in same timezone as d1
    d2 = datetime(1970, 1, 1, tzinfo=d1.tzinfo)
    time_delta = d1 - d2
    ts = int(time_delta.total_seconds())
    return ts


def epoch_to_datetime_string(ts, tz_name="UTC"):
    x_timezone = timezone(tz_name)
    d1 = datetime.fromtimestamp(ts, x_timezone)
    x = d1.strftime("%d %B %Y %H:%M:%S")
    return x

0

यह वर्ग आपकी ज़रूरतों को पूरा करेगा, आप वैरिएबल को यूएनयूक्सटॉटडाइमटाइम में कॉल कर सकते हैं और कॉल कर सकते हैं कि आप कौन सा फंक्शन चाहते हैं।

from datetime import datetime
import time

class ConvertUnixToDatetime:
    def __init__(self, date):
        self.date = date

    # Convert unix to date object
    def convert_unix(self):
        unix = self.date

        # Check if unix is a string or int & proceeds with correct conversion
        if type(unix).__name__ == 'str':
            unix = int(unix[0:10])
        else:
            unix = int(str(unix)[0:10])

        date = datetime.utcfromtimestamp(unix).strftime('%Y-%m-%d %H:%M:%S')

        return date

    # Convert date to unix object
    def convert_date(self):
        date = self.date

        # Check if datetime object or raise ValueError
        if type(date).__name__ == 'datetime':
            unixtime = int(time.mktime(date.timetuple()))
        else:
            raise ValueError('You are trying to pass a None Datetime object')
        return type(unixtime).__name__, unixtime


if __name__ == '__main__':

    # Test Date
    date_test = ConvertUnixToDatetime(datetime.today())
    date_test = date_test.convert_date()
    print(date_test)

    # Test Unix
    unix_test = ConvertUnixToDatetime(date_test[1])
    print(unix_test.convert_unix())
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.