2011-07-19 17 views
7

मुझे SimpleDateFormat के साथ कुछ परेशान परिणाम मिल रहे हैं और मुझे उम्मीद है कि कोई इस मुद्दे पर कुछ प्रकाश डाल सकता है। उत्पादन:SimpleDateFormat सप्ताह की गणना

Time   = Mon Dec 27 00:00:00 PST 2010 
2010-01 <--- THIS IS WHAT I DON'T UNDERSTAND 
Start of week = Sun Dec 26 00:00:00 PST 2010 
2010-01 
End of Week = Sat Jan 01 23:59:59 PST 2011 
2011-01 

मैं पिछले साल है कि एक विशेष मामले के रूप अगले साल के लिए प्रदान की "सप्ताह" इलाज हो सकता है? या यह व्याख्या करने का यह सही तरीका है? जाहिर है जब अनुक्रमिक रूप से सप्ताह व्यवस्थित करने का प्रयास करते समय, आदेश गलत है। शुरुआती मूल्यों को समायोजित करना, 25 दिसंबर, 2005 को 53 वें सप्ताह माना जाता है। मैंने जोडा को अभी तक देखने के लिए नहीं देखा है कि क्या जोडा इसी तरह के परिणाम उत्पन्न करता है।

प्रासंगिक कोड:

private static Date getStartOfWeek(Date d) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.clear(); 
    calendar.setTime(d); 

    calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); 

    return calendar.getTime(); 
} 

private static Date getEndOfWeek(Date d) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.clear(); 

    calendar.setTime(d); 
    calendar.add(Calendar.WEEK_OF_YEAR, 1); 
    calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); 
    calendar.add(Calendar.MILLISECOND, -1); 

    return calendar.getTime(); 
} 


Calendar calendar = Calendar.getInstance(); 
calendar.clear(); 
calendar.set(2010, Calendar.DECEMBER, 27); 
Date d = calendar.getTime(); 
Date start = getStartOfWeek(d); 
Date end = getEndOfWeek(d); 
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-ww"); 

System.out.println("Time   = " + d); 
System.out.println(fmt.format(d)); 
System.out.println("Start of week = " + start); 
System.out.println(fmt.format(start)); 
System.out.println("End of Week = " + end); 
System.out.println(fmt.format(end)); 

पृष्ठभूमि: जब JasperReports में crosstab (सप्ताह में बांटा तारीख) का उपयोग मैं इस पाया।

संपादित करें: मैं उपयोग कर रहा हूँ JDK 1.6.0_25

संपादित करें: ऐसा लगता है कि मैं Joda उपयोग करने के लिए सही परिणाम प्राप्त करने के लिए होगा। सप्ताह की शुरुआत/अंत प्राप्त करने के लिए, मैं इसका उपयोग कर समाप्त हुआ: LocalDate.withDayOfWeek। वर्ष और सप्ताह संख्या को पुनः प्राप्त करने के लिए, मैंने DateTime.getWeekyear और DateTime.getWeekOfWeekyear का उपयोग किया।

+0

+1 दिनांक प्रस्तुतियों में एक सूक्ष्म मुद्दा लाने के लिए। नीचे मेरा जवाब देखें। –

उत्तर

14

बग आपके स्वरूपण कोड में है, जावा नहीं।

आश्चर्यजनक व्यवहार दिनांक नोटेशन में एक गूढ़ नियम के कारण है। ध्यान दें कि आईएसओ 8601 (बल्कि भ्रमित) सप्ताह संख्याओं का उपयोग करते समय वर्ष सीमाओं के लिए अलग-अलग नियम निर्दिष्ट करता है। विशेष रूप से, 2010-12-27 को सप्ताह संख्याओं का उपयोग करते समय 2011 का हिस्सा माना जाता है।

नतीजतन, आपको सामान्य वर्ष yyyy की बजाय "सप्ताह वर्ष" YYYY का उपयोग करना चाहिए। (http://download.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#week_year और http://download.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html में पिछले उदाहरण देखें।)

इसके अलावा, दिनांकों मानक संकेत एक स्पष्ट 'W' का उपयोग करता है, तो आप new SimpleDateFormat("YYYY-'W'ww") बजाय का उपयोग करना चाहिए।

संपादित करें: एक और समस्या है। जावा अमानक calendar.getMinimalDaysInFirstWeek() == 1 के लिए डिफ़ॉल्ट करने लगता है, तो आप सही साल प्राप्त करने के लिए

calendar.setMinimalDaysInFirstWeek(4); 

सेट करना होगा।

संपादित करें: Calendar javadocs पढ़ने से, आप भी को शुरुआती दिन सोमवार को सेट करने की आवश्यकता हो सकती है।इसके अलावा, YYYY प्रारूप विनिर्देश जावा 1.7 में नया प्रतीत होता है। इसके प्रकाश में, जब तक कि आप प्री-रिलीज जावा संस्करण में अपग्रेड करने के इच्छुक नहीं हैं, मैं केवल जोडा टाइम का उपयोग करने की सलाह देता हूं।

+0

अच्छी तरह से जावा 1.7 में अपग्रेड संभव नहीं है इसलिए मुझे समय के लिए जोडा का उपयोग करना होगा। – nevets1219

1

स्टैंडडार जावा तिथि & समय कक्षाएं अच्छी तरह से डिज़ाइन नहीं की गई हैं और कभी-कभी अपेक्षा के अनुसार काम नहीं करती हैं। इसके बजाय Joda Time

+0

हालांकि आपका कथन सही है, इस मामले में कोई अंतर नहीं होना चाहिए। समस्या यह है कि "सप्ताह संख्या" की गणना – Nivas

-2

हां, यह जावा में एक बग प्रतीत होता है, न कि फ़ॉर्मेटिंग कोड में। यदि आप प्रिंट करते हैं:

System.out.println("Week = " + calendar.get(Calendar.WEEK_OF_YEAR)); 

यह 1 भी दिखाता है।

आप कुछ तो साल के अंत के करीब नहीं है, जैसे करने के लिए अपनी तिथि को बदलते हैं:

calendar.set(2010, Calendar.NOVEMBER, 27); 

फिर उत्पादन सही लग रहा है। बीटीडब्ल्यू, मैंने सूर्य 1.6.0_25 64 बिट वीएम का उपयोग करके परीक्षण किया।

1

ISO Week

एक साल के पहले सप्ताह से सप्ताह है कि पहले गुरुवार वर्ष के होता है।

तो व्यवहार के पास जावा या जोडा से कोई लेना देना नहीं है। इस तरह "वर्ष का सप्ताह" दुनिया भर में कार्यान्वित किया जाता है (यदि वे आईएसओ मानक का पालन करते हैं)

संबंधित मुद्दे