ইন java.util.Calendar
, জানুয়ারী মাস 0 হিসাবে গণ্য করা হয়, 1 মাস নয়। এর কোনও নির্দিষ্ট কারণ আছে কি?
আমি অনেক লোককে এ সম্পর্কে বিভ্রান্ত হতে দেখেছি ...
ইন java.util.Calendar
, জানুয়ারী মাস 0 হিসাবে গণ্য করা হয়, 1 মাস নয়। এর কোনও নির্দিষ্ট কারণ আছে কি?
আমি অনেক লোককে এ সম্পর্কে বিভ্রান্ত হতে দেখেছি ...
উত্তর:
এটি ভয়াবহ গণ্ডগোলের অংশ মাত্র যা জাভা তারিখ / সময় এপিআই। এতে কী সমস্যা আছে তা তালিকাভুক্ত করতে খুব দীর্ঘ সময় লাগবে (এবং আমি নিশ্চিত যে সমস্যার অর্ধেকটি আমি জানি না)। স্বীকারোক্তিজনকভাবে তারিখ এবং সময় নিয়ে কাজ করা কঠিন, তবে যেভাবেই হোক না কেন।
নিজের পক্ষে নিজেকে করুন এবং পরিবর্তে জোদা সময় ব্যবহার করুন, বা সম্ভবত জেএসআর -310 ।
সম্পাদনা: যে কারণগুলির জন্য - অন্যান্য উত্তরে যেমন উল্লেখ করা হয়েছে, এটি পুরানো সি এপিআইগুলির কারণে, বা 0 থেকে সমস্ত কিছু শুরু করার সাধারণ অনুভূতির কারণে হতে পারে ... তবে দিনগুলি অবশ্যই 1 দিয়ে শুরু করা উচিত of মূল বাস্তবায়ন দলের বাইরের কেউ সত্যই কারণগুলি বর্ণনা করতে পারে কিনা তা নিয়ে আমি সন্দেহ করি - তবে আবার আমি পাঠকদের প্রতি আহ্বান জানাব যে খারাপ সিদ্ধান্ত কেন নেওয়া হয়েছে সে সম্পর্কে এতটা চিন্তা না করার জন্য, যাতে ঘৃণ্যতার পুরো বিষয়টি সম্পর্কে নজর দেওয়া যায় java.util.Calendar
এবং আরও ভাল কিছু পাওয়া যায়।
এক বিন্দু যা হয় 0 ভিত্তিক সূচী ব্যবহারের পক্ষে এটি "নামের অ্যারে" ভালো জিনিস তোলে সহজ:
// I "know" there are 12 months
String[] monthNames = new String[12]; // and populate...
String name = monthNames[calendar.get(Calendar.MONTH)];
অবশ্যই, আপনি 13 মাসের সাথে ক্যালেন্ডার পাওয়ার সাথে সাথে এটি ব্যর্থ হবে ... তবে কমপক্ষে নির্দিষ্ট আকারটি আপনার প্রত্যাশিত মাসের সংখ্যা।
এটি কোনও ভাল কারণ নয়, তবে এটি একটি কারণ ...
সম্পাদনা: একটি মন্তব্য সাজানোর অনুরোধ হিসাবে তারিখ / ক্যালেন্ডারের সাথে আমার কী ভুল বলে মনে হয় সে সম্পর্কে কয়েকটি ধারণা অনুরোধ করে:
Date
এবং Calendar
বিভিন্ন জিনিস হিসাবে ভাল, তবে "স্থানীয়" বনাম "জোনেড" মানগুলির পৃথকীকরণ অনুপস্থিত, যেমন তারিখ / সময় বনাম তারিখ বনাম সময়Date.toString()
বাস্তবায়ন যা সবসময় সিস্টেম স্থানীয় সময় অঞ্চল ব্যবহার (যে এর অনেক স্ট্যাক ওভারফ্লো ব্যবহারকারীদের সামনে এখন বিভ্রান্ত)কারণ মাস সহ গণিত করা অনেক সহজ is
ডিসেম্বরের পরের 1 মাস জানুয়ারী, তবে সাধারণত এটি বের করতে আপনাকে মাসের নম্বরটি নিয়ে গণিত করতে হবে
12 + 1 = 13 // What month is 13?
আমি জানি! আমি 12 এর একটি মডিউল ব্যবহার করে এটি দ্রুত সমাধান করতে পারি।
(12 + 1) % 12 = 1
এটি নভেম্বর পর্যন্ত 11 মাস ঠিক কাজ করে ...
(11 + 1) % 12 = 0 // What month is 0?
আপনি মাসটি যুক্ত করার আগে 1 টি বিয়োগ করে আপনি এই সমস্ত কাজটি আবার করতে পারেন, তারপরে আপনার মডুলাসটি করুন এবং শেষ পর্যন্ত আবার 1 যুক্ত করুন ... অন্তর্নিহিত সমস্যার আশেপাশের কাজ।
((11 - 1 + 1) % 12) + 1 = 12 // Lots of magical numbers!
এখন আসুন 0 - 11 মাসের সমস্যা সম্পর্কে ভাবা যাক।
(0 + 1) % 12 = 1 // February
(1 + 1) % 12 = 2 // March
(2 + 1) % 12 = 3 // April
(3 + 1) % 12 = 4 // May
(4 + 1) % 12 = 5 // June
(5 + 1) % 12 = 6 // July
(6 + 1) % 12 = 7 // August
(7 + 1) % 12 = 8 // September
(8 + 1) % 12 = 9 // October
(9 + 1) % 12 = 10 // November
(10 + 1) % 12 = 11 // December
(11 + 1) % 12 = 0 // January
সমস্ত মাস একই কাজ করে এবং চারপাশের কোনও কাজ প্রয়োজন হয় না।
((11 - 1 + 1) % 12) + 1 = 12
শুধু (11 % 12) + 1
মাসের 1..12 জন্য অর্থাত আপনি মাত্র 1 যোগ করতে হবে পরে মডিউল করছেন। কোন যাদু প্রয়োজন।
এর উত্তর অনেক আছে, তবে আমি যাই হোক না কেন এই বিষয়ে আমার মতামত দেব। এই অদ্ভুত আচরণের পেছনের কারণটি আগে বলা হয়েছে, পসিক্স সি থেকে এসেছে time.h
যেখানে কয়েক মাসের মধ্যে 0-10 রেঞ্জের সাথে সংরক্ষণ করা হয়। কেন তা ব্যাখ্যা করার জন্য, এটি এর মতো দেখুন; বছর এবং দিনগুলিকে কথ্য ভাষায় সংখ্যা হিসাবে বিবেচনা করা হয়, তবে মাসের নিজস্ব নাম রয়েছে। সুতরাং জানুয়ারী প্রথম মাস হওয়ায় এটি প্রথম অ্যারের উপাদান অফসেট 0 হিসাবে সংরক্ষণ করা হবে।monthname[JANUARY]
হবে "January"
। বছরের প্রথম মাসে প্রথম মাসের অ্যারের উপাদান।
অন্যদিকে দিনের সংখ্যা, যেহেতু তাদের নাম নেই, সেহেতু 0-30 হিসাবে একটি ইনট্রে সংরক্ষণ করা বিভ্রান্তিকর হবে, প্রচুর পরিমাণে যুক্ত করুন day+1
আউটপুট দেওয়ার জন্য নির্দেশাবলী এবং অবশ্যই বাগের ঝুঁকিতে পড়বেন।
বলা হচ্ছে, অসঙ্গতিটি বিভ্রান্তিকর, বিশেষত জাভাস্ক্রিপ্টে (যা এই "বৈশিষ্ট্যটি "ও পেয়েছে), এটি একটি স্ক্রিপ্টিং ভাষা যেখানে এই লিঙ্গ থেকে অনেক দূরে সরানো উচিত।
টিএল; ডিআর : কারণ মাসের নাম এবং মাসের দিন থাকে না।
জাভা 8-এ, একটি নতুন তারিখ / সময় এপিআই জেএসআর 310 রয়েছে যা আরও বুদ্ধিমান। স্পেক সীসা জোদাটাইমের প্রাথমিক লেখকের সমান এবং তারা অনেকগুলি অনুরূপ ধারণা এবং নিদর্শনগুলি ভাগ করে।
আমি অলসতা বলব। অ্যারে 0 থেকে শুরু হয় (প্রত্যেকে এটি জানেন); বছরের মাসগুলি একটি অ্যারে হয়, যা আমাকে বিশ্বাস করতে পরিচালিত করে যে সুনের কিছু প্রকৌশলী কেবল জাভা কোডের মধ্যে এই একটি ছোট্ট নব্বইটি লাগিয়ে বিরক্ত করেননি।
কারণ প্রোগ্রামাররা 0-ভিত্তিক সূচকগুলিতে আবেশযুক্ত। ঠিক আছে, এটি এর চেয়ে কিছুটা জটিল: আপনি যখন 0-ভিত্তিক সূচক ব্যবহার করতে নিম্ন-স্তরের যুক্তি দিয়ে কাজ করছেন তখন এটি আরও বোধগম্য হয়। তবে বড় বড়, আমি এখনও আমার প্রথম বাক্যটি ধরে রেখেছি।
ব্যক্তিগতভাবে, আমি জাভা ক্যালেন্ডার এপিআইয়ের অদ্ভুততাটিকে একটি ইঙ্গিত হিসাবে গ্রহণ করেছি যে গ্রেগরিয়ান-কেন্দ্রিক মানসিকতা থেকে নিজেকে তালাক দেওয়া এবং সেই বিষয়ে আরও কৃষ্ণবিজ্ঞানের সাথে প্রোগ্রাম করার চেষ্টা করা দরকার। বিশেষত, আমি মাসের মতো জিনিসগুলির জন্য হার্ডকডযুক্ত ধ্রুবকগুলি এড়াতে আবারও শিখেছি।
নিম্নলিখিত কোনটি সঠিক হওয়ার সম্ভাবনা বেশি?
if (date.getMonth() == 3) out.print("March");
if (date.getMonth() == Calendar.MARCH) out.print("March");
এটি এমন একটি বিষয় চিত্রিত করে যা জোদা সময় সম্পর্কে আমাকে কিছুটা কমায় ks (তবে কিছুটা হলেও। জোদা প্রোগ্রামারদের খারাপ প্রোগ্রাম করতে বাধ্য করছে বলে মনে হচ্ছে না))
আমার জন্য, কেউ এটিকে মাইন্ডপ্রো ডটকমের চেয়ে ভালভাবে ব্যাখ্যা করে না :
Gotchas
java.util.GregorianCalendar
old java.util.Date
ক্লাসের তুলনায় অনেক কম বাগ এবং গোটচ রয়েছে তবে এটি এখনও কোনও পিকনিক নয়।ডেফলট সেভিং টাইমটি প্রথম প্রস্তাবিত হওয়ার পরে যদি প্রোগ্রামাররা থাকত তবে তারা এটিকে পাগল এবং অন্তরঙ্গ হিসাবে ভেটো করে দিত। দিবালোক সাশ্রয়ের সাথে একটি মৌলিক অস্পষ্টতা রয়েছে। শরত্কালে আপনি যখন আপনার ঘড়িগুলি দুপুর ২ টা ৪৫ মিনিটে ফিরে যান তখন সেখানে দুটি ভিন্ন তাত্ক্ষণিক সময় উপস্থিত থাকে উভয়কে স্থানীয় সময় 1:30 এএম বলা হয়। আপনি যদি কেবল রাইট রেকর্ডিং বা পড়াশোনার সাথে স্ট্যান্ডার্ড সময় চেয়েছিলেন কিনা তা রেকর্ড করে তবেই আপনি এগুলি বলতে পারবেন।
দুর্ভাগ্যক্রমে,
GregorianCalendar
আপনি কোনটি উদ্দেশ্য করে তা জানানোর উপায় নেই । অস্পষ্টতা এড়াতে আপনার অবশ্যই ডামি ইউটিসি টাইমজোন এর সাথে স্থানীয় সময়টি বলার অবলম্বন করতে হবে। প্রোগ্রামাররা সাধারণত এই সমস্যার দিকে তাদের চোখ বন্ধ করে রাখে এবং কেবল আশা করি এই সময়ের মধ্যে কেউ কিছু করবে না।মিলেনিয়াম বাগ বাগগুলি এখনও ক্যালেন্ডার শ্রেণীর বাইরে নেই। এমনকি জেডিকে (জাভা ডেভলপমেন্ট কিট) ১.৩ এ একটি 2001 বাগ রয়েছে। নিম্নলিখিত কোড বিবেচনা করুন:
GregorianCalendar gc = new GregorianCalendar(); gc.setLenient( false ); /* Bug only manifests if lenient set false */ gc.set( 2001, 1, 1, 1, 0, 0 ); int year = gc.get ( Calendar.YEAR ); /* throws exception */
বাগটি এমএসটি-র জন্য 2001/01/01 সকাল 7 টা থেকে অদৃশ্য হয়ে যায়।
GregorianCalendar
টাইপযুক্ত ইন্টি ম্যাজিক কনস্ট্যান্টের একটি বিশালাকার গাদা দ্বারা নিয়ন্ত্রিত হয়। এই কৌশলটি সংকলন-সময় ত্রুটি পরীক্ষার কোনও আশা সম্পূর্ণরূপে ধ্বংস করে দেয়। উদাহরণস্বরূপ আপনি যে মাসটি ব্যবহার করেন তা পেতেGregorianCalendar. get(Calendar.MONTH));
GregorianCalendar
কাঁচাGregorianCalendar.get(Calendar.ZONE_OFFSET)
এবং দিবালোক সঞ্চয় আছেGregorianCalendar. get( Calendar. DST_OFFSET)
, তবে প্রকৃত সময় অঞ্চলটি অফসেট পাওয়ার কোনও উপায় নেই। আপনাকে অবশ্যই এই দুটি পৃথক করে একসাথে যুক্ত করতে হবে।
GregorianCalendar.set( year, month, day, hour, minute)
0 এ সেকেন্ড সেট করে না।
DateFormat
এবংGregorianCalendar
সঠিকভাবে জাল না। আপনাকে অবশ্যই দুবার ক্যালেন্ডার নির্দিষ্ট করতে হবে, একবার অপ্রত্যক্ষভাবে তারিখ হিসাবে।যদি ব্যবহারকারী তার সময় অঞ্চলটি সঠিকভাবে কনফিগার না করে থাকে তবে এটি শান্তভাবে পিএসটি বা জিএমটি-তে ডিফল্ট হয়ে যাবে।
গ্রেগরিয়ানক্যালেন্ডারে, গ্রহটির প্রত্যেকের মতো 1 টির পরিবর্তে মাস গণনা করা হয় 0 জানুয়ারিতে। তবুও দিনগুলি রবিবার = 1, সোমবার = 2,… শনিবার = 7 এর সাথে সপ্তাহের দিনগুলির মতো 1 এ শুরু হয়। তবুও ডেটফর্ম্যাট। পার্স Januaryতিহ্যবাহী পদ্ধতিতে জানুয়ারী = 1 এর সাথে আচরণ করে।
java.util.Month
জাভা আপনাকে কয়েক মাসের জন্য 1 ভিত্তিক সূচকগুলি ব্যবহার করার অন্য উপায় সরবরাহ করে। java.time.Month
এনাম ব্যবহার করুন । একটি বস্তু বারো মাসের প্রতিটি জন্য পূর্বনির্ধারিত is জানুয়ারি-ডিসেম্বরের জন্য তাদের প্রত্যেকের জন্য 1-12 নির্ধারিত নম্বর রয়েছে; getValue
নম্বর জন্য কল করুন ।
এর করতে ব্যবহার Month.JULY
(আপনি 7 দেয়) পরিবর্তে Calendar.JULY
(আপনি 6 দেয়)।
(import java.time.*;)
Month.FEBRUARY.getValue() // February → 2.
2
জন স্কিট দ্বারা উত্তর সঠিক।
এখন আমাদের সেই অসুবিধাগুলি পুরানো উত্তরাধিকারের তারিখ-সময় ক্লাস: জাভা.টাইম ক্লাসগুলির জন্য একটি আধুনিক প্রতিস্থাপন রয়েছে ।
java.time.Month
এই ক্লাসগুলির মধ্যে এনামও রয়েছে । একটি এনাম এক বা একাধিক পূর্বনির্ধারিত অবজেক্ট, বস্তুগুলি বহন করে যা শ্রেণি লোড হওয়ার পরে স্বয়ংক্রিয়ভাবে ইনস্ট্যান্ট হয়। উপর : আমরা এক ডজন যেমন বস্তুর আছে, প্রতিটি একটি নাম দেওয়া , , , ইত্যাদি। এগুলির প্রত্যেকটি একটি শ্রেণির ধ্রুবক। আপনি এই কোডগুলি আপনার কোডের যে কোনও জায়গায় ব্যবহার এবং পাস করতে পারেন। উদাহরণ:Month
Month
JANUARY
FEBRUARY
MARCH
static final public
someMethod( Month.AUGUST )
সৌভাগ্যক্রমে, তাদের সংখ্যার সংখ্যার পরিমাণ রয়েছে, 1-12 যেখানে 1 জানুয়ারী এবং 12 ডিসেম্বর হয়।
Month
নির্দিষ্ট মাসের সংখ্যার (1-12) জন্য একটি অবজেক্ট পান ।
Month month = Month.of( 2 ); // 2 → February.
অন্য দিকে যেতে, Month
কোনও মাসের মাসের সংখ্যা জিজ্ঞাসা করুন ।
int monthNumber = Month.FEBRUARY.getValue(); // February → 2.
এই শ্রেণিতে অন্যান্য অনেক সহজ পদ্ধতি যেমন প্রতি মাসে কত দিনের সংখ্যা জেনে রাখা । ক্লাসটি এমনকি মাসের একটি স্থানীয় নাম তৈরি করতে পারে ।
আপনি বিভিন্ন দৈর্ঘ্য বা সংক্ষিপ্তসারগুলিতে মাসের স্থানীয়করণের নামটি পেতে পারেন।
String output =
Month.FEBRUARY.getDisplayName(
TextStyle.FULL ,
Locale.CANADA_FRENCH
);
ফেব্রুয়ারী
এছাড়াও, আপনার কোড বেসের উপরে এই এনামের অবজেক্টগুলি কেবল পূর্ণসংখ্যার সংখ্যার পরিবর্তে পাস করা উচিত । এটি করা প্রকারের সুরক্ষা প্রদান করে, মানগুলির একটি বৈধ পরিসীমা নিশ্চিত করে এবং আপনার কোডকে আরও স্ব-ডকুমেন্টিং করে। জাভাতে আশ্চর্যজনকভাবে শক্তিশালী এনাম সুবিধার সাথে অজানা থাকলে ওরাকল টিউটোরিয়ালটি দেখুন ।
আপনি দরকারী Year
এবং YearMonth
ক্লাসগুলিও দরকারী খুঁজে পেতে পারেন ।
Java.time ফ্রেমওয়ার্ক জাভা 8 এবং পরে পাতাটা করা হয়। এই ক্লাসগুলি , & , এর মতো সমস্যাযুক্ত পুরানো উত্তরাধিকারের তারিখ-সময়ের ক্লাসগুলিকে সহায়তা করে ।java.util.Date
.Calendar
java.text.SimpleDateFormat
Joda-টাইম প্রকল্প, এখন রক্ষণাবেক্ষণ মোড , স্থানান্তরণ java.time করার পরামর্শ দেয়।
আরও জানতে, ওরাকল টিউটোরিয়াল দেখুন । এবং অনেক উদাহরণ এবং ব্যাখ্যার জন্য স্ট্যাক ওভারফ্লো অনুসন্ধান করুন। স্পেসিফিকেশনটি জেএসআর 310 ।
জাভা.টাইম ক্লাস কোথায় পাবেন?
ThreeTen-অতিরিক্ত প্রকল্প অতিরিক্ত শ্রেণীর সাথে java.time প্রসারিত করে। এই প্রকল্পটি জাভা.টাইমে সম্ভাব্য ভবিষ্যতের সংযোজনগুলির একটি প্রমাণযোগ্য ক্ষেত্র। আপনি এখানে কিছু দরকারী শ্রেণীর যেমন খুঁজে পেতে পারেন Interval
, YearWeek
, YearQuarter
, এবং আরো ।
এটি প্রতি সেউর মতো শূন্য হিসাবে সংজ্ঞায়িত নয়, এটি ক্যালেন্ডার হিসাবে সংজ্ঞায়িত করা হয়েছে an জানুয়ারী। এটি এনামগুলির পরিবর্তে অন্তরগুলি স্থির হিসাবে ব্যবহার করার সমস্যা। ক্যালেন্ডার.জানুরি == 0।
যেহেতু ভাষা লেখাগুলি দেখতে তার চেয়ে শক্ত এবং বিশেষত পরিচালনা করার সময়টি বেশিরভাগ লোকেরা মনে করেন তার চেয়ে অনেক কঠিন। সমস্যার অল্প অংশের জন্য (বাস্তবে জাভা নয়), https://www.youtube.com/watch?v=-5wpm-gesOY এ ইউটিউব ভিডিও "টাইম অ্যান্ড টাইমজোনস - কম্পিউটারফিলি সঙ্গে সমস্যা" দেখুন । আপনার মাথা গুলিয়ে ফেললে বিস্মিত হবেন না।
ড্যানিস্মার্ফের আলস্যতার উত্তর ছাড়াও, আমি যুক্ত করব যে এটি আপনাকে ধ্রুবকগুলি ব্যবহার করতে উত্সাহিত করবে Calendar.JANUARY
।
কারণ সমস্ত কিছু 0 দিয়ে শুরু হয় এটি জাভাতে প্রোগ্রামিংয়ের একটি প্রাথমিক তথ্য fact যদি একটি জিনিস এটি থেকে বিচ্যুত হয়, তবে এটি বিভ্রান্তির পুরো স্লুতে পরিচালিত করবে। আসুন তাদের গঠন এবং তাদের সাথে কোড যুক্তি না।