2008-11-20 8 views
38

अजगर datetime.isocalendar() विधि दिया datetime वस्तु के लिए एक टपल (ISO_year, ISO_week_number, ISO_weekday) देता है। क्या कोई संबंधित व्यस्त कार्य है? यदि नहीं, तो क्या एक वर्ष, सप्ताह संख्या और सप्ताह के दिन दिए गए दिनांक की गणना करने का कोई आसान तरीका है?डेटाटाइम .isocalendar() के विपरीत खोजने का सबसे अच्छा तरीका क्या है?

उत्तर

57

मैं हाल ही में इस समस्या अपने आप हल करने के लिए किया था, और इस समाधान के साथ आया था:

import datetime 

def iso_year_start(iso_year): 
    "The gregorian calendar date of the first day of the given ISO year" 
    fourth_jan = datetime.date(iso_year, 1, 4) 
    delta = datetime.timedelta(fourth_jan.isoweekday()-1) 
    return fourth_jan - delta 

def iso_to_gregorian(iso_year, iso_week, iso_day): 
    "Gregorian calendar date for the given ISO year, week and day" 
    year_start = iso_year_start(iso_year) 
    return year_start + datetime.timedelta(days=iso_day-1, weeks=iso_week-1) 

कुछ परीक्षण मामलों:

>>> iso = datetime.date(2005, 1, 1).isocalendar() 
>>> iso 
(2004, 53, 6) 
>>> iso_to_gregorian(*iso) 
datetime.date(2005, 1, 1) 

>>> iso = datetime.date(2010, 1, 4).isocalendar()  
>>> iso 
(2010, 1, 1) 
>>> iso_to_gregorian(*iso) 
datetime.date(2010, 1, 4) 

>>> iso = datetime.date(2010, 1, 3).isocalendar() 
>>> iso 
(2009, 53, 7) 
>>> iso_to_gregorian(*iso) 
datetime.date(2010, 1, 3) 
+0

क्या आप 4 जनवरी के महत्व को स्पष्ट कर सकते हैं? क्या आईएसओ कैलेंडर मानक का विवरण कहीं कहीं उचित है? – Tom

+6

टॉम: सप्ताह 1 की औपचारिक आईएसओ परिभाषा (सप्ताह के पहले गुरुवार वाले सप्ताह) से यह इस प्रकार है कि 4 जनवरी नवीनतम है कि सप्ताह 1 शुरू हो सकता है। –

+1

http://en.wikipedia.org/wiki/ISO_week_date – Tom

-1

संपादित करें: इस पर ध्यान न दें, धार मामलों परेशान कर सकती हैं। बेन के समाधान के साथ जाओ।

ठीक है, ध्यान से पर मैंने देखा है कि strptime%W और %w मापदंडों, तो निम्न कार्य किया है:

def fromisocalendar(y,w,d): 
    return datetime.strptime("%04dW%02d-%d"%(y,w-1,d), "%YW%W-%w") 

gotchas के एक जोड़े: आईएसओ सप्ताह के नंबर, 1 पर शुरू होता है, जबकि 0 पर %W शुरू होता है । ISO सप्ताह दिन 1 पर शुरू होता है (सोमवार) है, जो %w रूप में एक ही है, इसलिए रविवार शायद 0, नहीं 7 होना चाहिए था ...

+0

आप किस संस्करण का उपयोग कर रहे हैं ?, मैं 2.4.2 पर परीक्षण कर रहा था और मेरे लिए काम नहीं किया, http://bugs.python.org/issue1045381 पाया लेकिन यह कहता है कि यह 2.3 –

+0

पर किया गया है, मैं 2.5 का उपयोग कर रहा हूं। 2,% डब्ल्यू काम कर रहा है,% यू के बारे में निश्चित नहीं है। – Tom

+0

ऐसा लगता है कि आपने इसका उत्तर दिया है। अपना जवाब क्यों स्वीकार नहीं करते? –

0

ध्यान दें कि% डब्ल्यू सप्ताह # (0-53) जो आईएसओ सप्ताह (1-53) के समान नहीं है। किनारे के मामले होंगे जहां% डब्ल्यू काम नहीं करेगा।

+0

में विफल रहा है, मैंने ध्यान दिया कि ऊपर दिए गए मेरे उत्तर में, आप किन किनारे के मामलों पर विस्तार कर सकते हैं? उदाहरण के लिए – Tom

+0

@ टॉम, वर्ष 200 9 और 2013। – akaihola

7
import datetime 

def iso_to_gregorian(iso_year, iso_week, iso_day): 
    "Gregorian calendar date for the given ISO year, week and day" 
    fourth_jan = datetime.date(iso_year, 1, 4) 
    _, fourth_jan_week, fourth_jan_day = fourth_jan.isocalendar() 
    return fourth_jan + datetime.timedelta(days=iso_day-fourth_jan_day, weeks=iso_week-fourth_jan_week) 

यह @ BenJames से अनुकूलित किया गया था बहुत अच्छा है जवाब। आपको साल के पहले दिन को नहीं जानना है। आपको बस उस तारीख का एक उदाहरण जानना है जो निश्चित रूप से एक ही आईएसओ वर्ष में है, और आईएसओ कैलेंडर सप्ताह और उस तारीख का दिन।

4 जनवरी का जनवरी केवल एक उदाहरण है, क्योंकि बेन ने बताया कि 4 जनवरी हमेशा एक ही आईएसओ वर्ष और ग्रेगोरियन वर्ष से संबंधित है, और ऐसा करने का साल का पहला दिन है।

सप्ताह के बाद से सभी समान लंबाई हैं, आप बस अपनी इच्छित तारीख के आईएसओ के बीच के दिनों और सप्ताहों को घटा सकते हैं, और उस तारीख का आईएसओ जिसे आप दोनों रूपों में जानते हैं, और उस दिन को जोड़ते हैं और सप्ताह। (इसका कोई प्रभाव नहीं इन नंबरों सकारात्मक या नकारात्मक हैं या नहीं, तो आप कुछ अन्य 'तय दिन' दिसंबर 28 वें जैसे चुन सकते हैं।)

संपादित

मैं इस को सही किया, क्योंकि जैसा कि काम आते हुए @ द्वारा बताया गया जोसो, ग्रेगोरियन वर्ष का पहला दिन जो आईएसओ वर्ष से संबंधित है, 4 जनवरी को 5 जनवरी नहीं है। जैसा कि स्पष्टीकरण कहता है, इससे कोई फर्क नहीं पड़ता कि किस तारीख को संदर्भ बिंदु के रूप में चुना जाता है, लेकिन 4 जनवरी को चुनने से यह विकल्प कम 'जादू' बन जाता है।

+1

क्या आप कृपया मुझे बता सकते हैं, अगर यह वास्तव में प्रत्येक स्थिति में निर्दोष काम करता है? – Geeocode

+3

@ जॉर्जोरोलिमोसी मैंने किसी भी वैध 'डेटाटाइम' ऑब्जेक्ट्स को खोजने के लिए परिकल्पना पाइथन परीक्षण लाइब्रेरी का उपयोग किया है जिसके लिए यह कार्य 'आइसोकेन्डर' के विपरीत नहीं है। इसे कोई भी नहीं मिला है/देखें https://github.com/jwg4/qual/blob/master/qual/tests/test_iso.py यह निश्चित रूप से गारंटी नहीं है - मुझे किसी भी बग के बारे में सुनने में दिलचस्पी होगी। यदि आप कोड के तर्क के माध्यम से काम करते हैं, तो हो सकता है कि आप यह सुनिश्चित न करें कि यह सही काम करता है। – jwg

+0

यह आवश्यक से अधिक जटिल है। बेन के जवाब या विकिपीडिया पर देखें। 4 जनवरी भी ऐसा करेगा और इसके अलावा हमेशा आईएसओ वर्ष के पहले आईएसओ सप्ताह में निहित होगा। –

1

अजगर 3.6 में शुरू, datetime.strptime()%G, %V और %u निर्देशों का समर्थन करेंगे, तो आप बस datetime.strptime('2015 1 2', '%G %V %u').date() कर सकते हैं। देखें: https://hg.python.org/cpython/rev/acdebfbfbdcf

4

अजगर 3.6 (वर्तमान में in development) के रूप में, आप नई %G, %u और %V निर्देशों का उपयोग कर सकते हैं।issue 12006 और updated documentation देखें:

%G
आईएसओ 8601 शताब्दी वर्ष है कि आईएसओ सप्ताह (%V) का बड़ा हिस्सा होता है का प्रतिनिधित्व करने के साथ वर्ष।

%u
आईएसओ 8601 सप्ताहांत दशमलव संख्या के रूप में जहां 1 सोमवार है।

%V
आईएसओ सप्ताह के पहले दिन के रूप में सोमवार से एक दशमलव संख्या के रूप में 8601 सप्ताह।

from datetime import date 

date.strptime('2002 01 1', '%G %V %u') 

या के साथ एक समारोह के रूप में: सप्ताह 01 साल, weeknumber और काम करने के दिन संख्या के साथ एक स्ट्रिंग को देखते हुए जनवरी 4.

युक्त सप्ताह है, यह उन लोगों के साथ डेट करने के लिए बाहर पार्स करने के लिए आसान है पूर्णांक आदानों:

from datetime import date 

def date_from_isoweek(iso_year, iso_weeknumber, iso_weekday): 
    return date.strptime(
     '{:04d} {:02d} {:d}'.format(iso_year, iso_weeknumber, iso_weekday) 
     '%G %V %u') 
2

अगले लोगों के लिए यहाँ आने के, एक छोटा, एकल डीईएफ़, बेन अच्छा समाधान के संस्करण:

def iso_to_gregorian(iso_year, iso_week, iso_day): 
    jan4 = datetime.date(iso_year, 1, 4) 
    start = jan4 - datetime.timedelta(days=jan4.isoweekday()-1) 
    return start + datetime.timedelta(weeks=iso_week-1, days=iso_day-1) 
संबंधित मुद्दे