पाइथन में वर्ष / माह / दिन को वर्ष में परिवर्तित करें


127

मैं पायथन डेटाइम मॉड्यूल का उपयोग कर रहा हूं , अर्थात:

>>> import datetime
>>> today = datetime.datetime.now()
>>> print today
2009-03-06 13:24:58.857946

और मैं वर्ष के उस दिन की गणना करना चाहूंगा जो लीप वर्ष के प्रति संवेदनशील है। आज की तरह (6 मार्च, 2009) 2009 का 65 वां दिन है। यहां वेब-आधारित डेटटाइम कैलकुलेटर है

वैसे भी, मुझे दो विकल्प दिखाई देते हैं:

A. एक नंबर_ऑफ़_डे_इन_मार्टन सरणी = [31, 28, ...] बनाएं, यह तय करें कि यह एक लीप वर्ष है, मैन्युअल रूप से दिनों का योग करें।

ख। datetime.timedeltaवर्ष के सही दिन के लिए अनुमान लगाने और फिर बाइनरी खोज करने के लिए उपयोग करें :

>>> import datetime
>>> YEAR = 2009
>>> DAY_OF_YEAR = 62
>>> d = datetime.date(YEAR, 1, 1) + datetime.timedelta(DAY_OF_YEAR - 1)

ये दोनों बहुत ही भद्दे लगते हैं और मुझे यह महसूस होता है कि साल के दिन की गणना करने का एक अधिक "पायथोनिक" तरीका है। कोई विचार / सुझाव?

जवाबों:


255

एक बहुत ही सरल उपाय है:

from datetime import datetime
day_of_year = datetime.now().timetuple().tm_yday

13
एक बहुत ही मामूली और यकीनन पांडित्यपूर्ण जोड़ है, लेकिन इसके date.today()बजाय का उपयोग करना datetime.now()भी काम करता है और ऑपरेशन की प्रकृति पर थोड़ा अधिक जोर देता है।
जेरेमी

5
अभी तक बेहतर: time.localtime().tm_yday कोई स्थानीय समयरेखा () पैदावार के लिए एक समयसीमा में परिवर्तित करने की आवश्यकता नहीं है।
माइक एलिस

14
@MikeEllis लेकिन यह समाधान दिखाता है कि क्या करना है जब डेटाइम आज के अनुरूप नहीं है।
गेरिट

2
नोट: यह 1 से शुरू होता है
मेहदी नेलन

1
क्या होगा अगर मैं रिवर्स करना चाहता हूं, मेरे पास "वर्ष 2020 का 26 वां दिन" कहने की संख्या है, और मैं इसे "26-01-2020" तारीख में बदलना चाहता हूं?
शंकर

43

क्या आप उपयोग नहीं कर सकते strftime?

>>> import datetime
>>> today = datetime.datetime.now()
>>> print today
2009-03-06 15:37:02.484000
>>> today.strftime('%j')
'065'

संपादित करें

जैसा कि टिप्पणियों में कहा गया है, यदि आप इस संख्या के साथ तुलना या गणना करना चाहते हैं, तो आपको इसे परिवर्तित करना होगा int()क्योंकि strftime()एक स्ट्रिंग लौटाता है। यदि ऐसा है, तो आप DzinX के उत्तर का उपयोग करने से बेहतर हैं ।


1
-1: icky। बेहतर है "आज माइनस लाइफ 1st" अल्गोरिथम। बहुत क्लीनर और पूरी तरह से स्पष्ट है कि स्ट्रिपटाइम के '% j' के बारे में सामान्य ज्ञान का एक टुकड़ा।
एस.लॉट

12
गंभीरता से? यह कैसे icky और घटिया 1 जनवरी को नहीं है? strftime वहाँ एक कारण के लिए है। मैं सिर्फ सहमत नहीं हूँ। यह मेरी राय में WAY क्लीनर है।
पाओलो बेरेनटिनो

1
स्ट्रैपटाइम का उपयोग अप्रत्यक्ष है, क्योंकि यह एक संख्या से एक स्ट्रिंग का उत्पादन करता है: समय-सारणी। tm_yday सदस्य। स्रोत पढ़ें उत्पादित स्ट्रिंग को किसी भी गणना / तुलना से पहले संख्या में परिवर्तित किया जाना चाहिए, इसलिए परेशान क्यों हो?
tzot

2
यदि किसी को एक स्ट्रिंग में वर्ष के दिन की आवश्यकता होती है, तो फ़ाइल नाम में उपयोग के लिए कहें, स्ट्रैप्टम एक क्लीनर समाधान है।
Captain_M

13

DZINX का उत्तर प्रश्न के लिए एक शानदार उत्तर है। उलटे कार्य की तलाश करते हुए मुझे यह प्रश्न मिला। मुझे यह काम करने के लिए मिला:

import datetime
datetime.datetime.strptime('1936-077T13:14:15','%Y-%jT%H:%M:%S')

>>>> datetime.datetime(1936, 3, 17, 13, 14, 15)

datetime.datetime.strptime('1936-077T13:14:15','%Y-%jT%H:%M:%S').timetuple().tm_yday

>>>> 77

मैं इधर-उधर शिष्टाचार के बारे में निश्चित नहीं हूँ, लेकिन मुझे लगा कि उलटा कार्य करने वाला एक संकेत मेरे जैसे अन्य लोगों के लिए उपयोगी हो सकता है।


6

मैं पायथन 3.4, लिनक्स x64 पर विभिन्न दृष्टिकोणों का प्रदर्शन प्रस्तुत करना चाहता हूं। लाइन प्रोफाइलर से अंश:

      Line #      Hits         Time  Per Hit   % Time  Line Contents
      ==============================================================
         (...)
         823      1508        11334      7.5     41.6          yday = int(period_end.strftime('%j'))
         824      1508         2492      1.7      9.1          yday = period_end.toordinal() - date(period_end.year, 1, 1).toordinal() + 1
         825      1508         1852      1.2      6.8          yday = (period_end - date(period_end.year, 1, 1)).days + 1
         826      1508         5078      3.4     18.6          yday = period_end.timetuple().tm_yday
         (...)

तो सबसे कुशल है

yday = (period_end - date(period_end.year, 1, 1)).days

1
आपने प्रदर्शन की गणना कैसे की? मैंने time.time का उपयोग करने की कोशिश की और वे मेरे परिणाम हैं: def f (): (आज - datetime.datetime (आज, वर्ष, 1, 1)) दिन + 1 शुरू = time.time (); च (); प्रिंट ('लैप्सड {}') प्रारूप (time.time () - start)); लैप्स 5.221366882323219e-05 डीफ़ च (): int (Today.strftime ('% j')); start = time.time (); च (); प्रिंट ('लैप्सड {}') प्रारूप (time.time () - start)); 7.462501525878906e-05
ssoto

5

बस दिनांक 1 से घटाएं:

import datetime
today = datetime.datetime.now()
day_of_year = (today - datetime.datetime(today.year, 1, 1)).days + 1

1
पाओलो के खिलाफ कुछ भी नहीं है, लेकिन datetime.timedelta दिनों (और साथ ही सेकंड और माइक्रोसेकंड,) में
निंदा की जाती है

1
d.toordinal () - दिनांक (d.year, 1, 1) .toordinal () + 1 प्रलेखन के अनुसार अधिक मानक है। यह पूरे समय टपल का उत्पादन किए बिना स्वीकृत उत्तर के बराबर है।
डिंगल

5

यदि आपके पास datetimeमॉड्यूल के उपयोग से बचने का कारण है , तो ये फ़ंक्शन काम करेंगे।

def is_leap_year(year):
    """ if year is a leap year return True
        else return False """
    if year % 100 == 0:
        return year % 400 == 0
    return year % 4 == 0

def doy(Y,M,D):
    """ given year, month, day return day of year
        Astronomical Algorithms, Jean Meeus, 2d ed, 1998, chap 7 """
    if is_leap_year(Y):
        K = 1
    else:
        K = 2
    N = int((275 * M) / 9.0) - K * int((M + 9) / 12.0) + D - 30
    return N

def ymd(Y,N):
    """ given year = Y and day of year = N, return year, month, day
        Astronomical Algorithms, Jean Meeus, 2d ed, 1998, chap 7 """    
    if is_leap_year(Y):
        K = 1
    else:
        K = 2
    M = int((9 * (K + N)) / 275.0 + 0.98)
    if N < 32:
        M = 1
    D = N - int((275 * M) / 9.0) + K * int((M + 9) / 12.0) + 30
    return Y, M, D

1

यह कोड इनपुट तर्क के रूप में एक तारीख लेता है और वर्ष का दिन लौटाता है।

from datetime import datetime
date = raw_input("Enter date: ")  ## format is 02-02-2016
adate = datetime.datetime.strptime(date,"%d-%m-%Y")
day_of_year = adate.timetuple().tm_yday
day_of_year
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.