2020 সালের 30 মার্চ এবং 1 মার্চের মধ্যে পার্থক্য ভুলভাবে 29 এর পরিবর্তে 28 দিন দেয়?


124
TimeUnit.DAYS.convert(
   Math.abs(
      new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse("30-03-2020 00:00:00").getTime() - 
      new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse("1-03-2020 00:00:00").getTime()
   ),
   TimeUnit.MILLISECONDS)

ফলাফলটি 28, যখন এটি 29 হওয়া উচিত।

সময় অঞ্চল / অবস্থান সমস্যা হতে পারে?


17
দ্রষ্টব্য: অনুগ্রহ করে SimpleDateFormatএটি আর ব্যবহার করবেন না any java.timeপরিবর্তে প্যাকেজ ব্যবহার করুন । ইন SimpleDateFormatএর ক্ষেত্রে, ব্যবহার DateTimeFormatter। জাভা 7 এর ক্ষেত্রে নীচে অ্যান্ডি টার্নারের মন্তব্য দেখুন।
এমসি সম্রাট

28
সময়ে গণিত করবেন না । একটি উপযুক্ত সময় গ্রন্থাগার ব্যবহার করুন ( java.time[যদিও আমি মনে করি আপনি জাভা on তে আছেন]], থ্রিটেনবিপি , জোদা)।
অ্যান্ডি টার্নার

14
আমি সেই সভায় থাকতে চাই যেখানে কেউ যায় "ঠিক আছে, এখন আমরা টাইমজোনগুলি পেয়েছি যে 100% গাধা-মোডে চলে যাই এবং ডাইটলাইট সেভিংস নামক এই জিনিসটি বাস্তবায়িত করি যা আমার এসিড ভ্রমণের পরে একটি স্বপ্নে আমার কাছে এসেছিল called গত রাত."
MonkeyZeus

5
@gmauch TimeUnitডিএসটি সম্পর্কে কিছু জানার ভান করে না। যেমন জাভাডোক বলেছেন: একটি ন্যানোসেকেন্ডকে একটি মাইক্রোসেকেন্ডের এক হাজারতম হিসাবে চিহ্নিত করা হয়েছে, একটি মাইক্রোসেকেন্ডকে এক হাজার সেকেন্ডের এক হাজারতম হিসাবে , এক মিলিসেকেন্ডকে সেকেন্ডের এক হাজারতম হিসাবে, এক মিনিটকে ষাট সেকেন্ড হিসাবে, এক ঘন্টা ষাট মিনিট হিসাবে এবং একদিন হিসাবে চব্বিশ ঘণ্টা--- যেহেতু ডিএসটি বছরের 24 দিন ঠিক 24 ঘন্টা না হওয়ার কারণ দেয় TimeUnit, তাই ডিএসটি জড়িত থাকার পরে এটি ভুল হয়ে যায়।
আন্দ্রেয়াস

1
এই সমস্যা কেবলমাত্র সেই কম্পিউটারগুলিতে ঘটে যা দিবালোকের সঞ্চয় সহ সময় জোনে থাকে। এটি টাইম জোনে দিনের সঠিক সংখ্যা দেয় (২৯) যা দিবালোকের সঞ্চয় নেই!
গোপীনাথ

উত্তর:


207

সমস্যাটি হ'ল ডাইটলাইট সেভিং টাইম শিফটের কারণে (রবিবার, মার্চ 8, 2020), এই তারিখগুলির মধ্যে 28 দিন এবং 23 ঘন্টা রয়েছে। ফলাফলটি TimeUnit.DAYS.convert(...) কেটে যায় ২৮ দিন।

সমস্যাটি দেখতে (আমি মার্কিন পূর্ব সময় অঞ্চলে আছি):

SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
long diff = fmt.parse("30-03-2020 00:00:00").getTime() -
            fmt.parse("1-03-2020 00:00:00").getTime();

System.out.println(diff);
System.out.println("Days: " + TimeUnit.DAYS.convert(Math.abs(diff), TimeUnit.MILLISECONDS));
System.out.println("Hours: " + TimeUnit.HOURS.convert(Math.abs(diff), TimeUnit.MILLISECONDS));
System.out.println("Days: " + TimeUnit.HOURS.convert(Math.abs(diff), TimeUnit.MILLISECONDS) / 24.0);

আউটপুট

2502000000
Days: 28
Hours: 695
Days: 28.958333333333332

ঠিক করতে, এমন সময় অঞ্চল ব্যবহার করুন যাতে ডিএসটি নেই, যেমন ইউটিসি :

SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
long diff = fmt.parse("30-03-2020 00:00:00").getTime() -
            fmt.parse("1-03-2020 00:00:00").getTime();

আউটপুট

2505600000
Days: 29
Hours: 696
Days: 29.0

121
"ঠিক করতে" সময়ের সাথে গণিত করবেন না। একটি সঠিক তারিখ / সময় গ্রন্থাগার ব্যবহার করুন।
অ্যান্ডি টার্নার

62
@ অ্যান্ডিটার্নারটি ঠিক করতে, অন্তর্নির্মিত জাভা 7 এপিআই ব্যবহার করে। যেহেতু এটা করতে সংশোধন করা, দেখাচ্ছে কিভাবে একটি বৈধ উত্তর। কাউকে পুরো লাইব্রেরি (জোদা-সময়, থ্রিটেন, ইত্যাদি) অন্তর্ভুক্ত করার জন্য জোর করা কেবল এই এক গণনা করার জন্য ওভারকিল হবে। অবশ্যই, একটি লাইব্রেরি ব্যবহার করার পরামর্শ দেওয়া হবে, তবে এটির প্রয়োজন নেই
আন্দ্রেস

38
আমি শ্রদ্ধার সাথে একমত। আপনি যদি কোনও গণনা করতে চান তবে এটি ঠিক করুন; এটি সঠিকভাবে করতে ব্যয় পরিশোধ করুন।
অ্যান্ডি টার্নার

16
আমার € 0.02: কোনও বাহ্যিক গ্রন্থাগার ছাড়াই জাভা 7-তে করার "সঠিক" GregorianCalendarউপায়টি হ'ল কোনও অবজেক্ট ব্যবহার করা এবং শেষ তারিখটি না পৌঁছানো পর্যন্ত এক সাথে 1 দিন যোগ করা। আমি এড়াতে একটি উচ্চ মূল্য দিতে হবে। এবং ইতিমধ্যে জাভা 8, 9, 10, 11, 12, 13,… এর অংশ হিসাবে থাকা লাইব্রেরির ব্যাকপোর্ট যুক্ত করা কোনও উচ্চ মূল্য নয়। বিপরীতে, পরের বার যখন আপনাকে তারিখ বা সময় দিয়ে কিছু করা দরকার, এটি ইতিমধ্যে একটি লাভ হবে।
ওলে ভিভি

27
এমনকি ইউটিসি-তে জুনের শেষ দিনটি মাঝে মাঝে এক সেকেন্ড খুব সংক্ষিপ্ত হয়, কোনও বাস্তব সতর্কতা বা ভবিষ্যদ্বাণী ছাড়াই। সর্বদা একটি তারিখ-সময় গ্রন্থাগার ব্যবহার করুন।
এফফি

41

ইতিমধ্যে আন্দ্রেসের উত্তরে এই সমস্যার কারণ উল্লেখ করা হয়েছে ।

প্রশ্নটি হ'ল আপনি কী গণনা করতে চান। আপনি যে সত্যটি উল্লেখ করেছেন যে 28 এর পরিবর্তে প্রকৃত পার্থক্য 29 হওয়া উচিত এবং "অবস্থান / অঞ্চল সময় কোনও সমস্যা হতে পারে" কিনা তা জিজ্ঞাসা করুন , আপনি প্রকৃতপক্ষে কী গণনা করতে চান তা প্রকাশ করে। স্পষ্টতই, আপনি যে কোনও সময় অঞ্চল পার্থক্য থেকে মুক্তি পেতে চান want

আমি ধরে নিয়েছি আপনি কেবল সময় এবং সময় অঞ্চল ছাড়াই দিনগুলি গণনা করতে চান।

জাভা 8

একটি তারিখ সময় ও সময় জোন ছাড়া - নীচে, মধ্যে দিনের সংখ্যা সঠিকভাবে হিসাব করা যেতে পারে কিভাবে উদাহরণে, আমি একটি বর্গ যে ঠিক যে প্রতিনিধিত্ব করে ব্যবহার করছি - LocalDate

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy HH:mm:ss");
LocalDate start = LocalDate.parse("1-03-2020 00:00:00", formatter);
LocalDate end = LocalDate.parse("30-03-2020 00:00:00", formatter);

long daysBetween = ChronoUnit.DAYS.between(start, end);

নোট করুন ChronoUnit, DateTimeFormatterএবং LocalDateজাভা ট্যাগ অনুসারে কমপক্ষে জাভা 8 প্রয়োজন যা আপনার কাছে উপলভ্য নয় । তবে এটি সম্ভবত ভবিষ্যতের পাঠকদের জন্য।

ওলে ভিভি দ্বারা উল্লিখিত হিসাবে, থ্রিটেন ব্যাকপোর্ট এছাড়াও রয়েছে যা জাভা 8 তারিখ এবং সময় এপিআই কার্যকারিতা জাভা 6 এবং 7 এ ব্যাকপোর্ট করে


2
@ OleV.V। আমি জানি থ্রিটেন রয়েছে, কিছু ব্যবহারকারী হয়ত এটি কয়েকবার উল্লেখ করেছেন। (আমি সমস্ত পোস্ট এবং ব্যবহারকারীর 5772882 টেক্সট ThreeTen;-) সমেত মন্তব্যগুলি ফিরিয়ে একটি SEDE ক্যোয়ারিতে লিঙ্ক করতে চলেছি , তবে দুর্ভাগ্যক্রমে এটি লেখার সময় অফলাইন)) পোস্টটি আপডেট করব।
এমসি সম্রাট

2
@ ওলেভিভি এটি মোটেই খারাপ জিনিস নয়। আমি মনে করি বেশিরভাগ লোকেরা কেবল এ সম্পর্কে অজ্ঞ java.time, কারণ স্কুলে তারা এখনও পুরানো ক্লাস ব্যবহার করে। তবে জাভা 8 ডেট এবং টাইম এপিআই খুব ভালভাবে ডিজাইন করা হয়েছে - এটি ব্যবহার না করার ক্ষতি হবে।
এমসি সম্রাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.