উত্তর:
অভিনন্দন, আপনি জেডিবিসি: ডেট ক্লাস হ্যান্ডলিংয়ের সাথে আমার প্রিয় পোষা প্রাণীর প্রস্থকে আঘাত করেছেন।
মূলত ডেটাবেসগুলি সাধারণত তারিখের সময় ক্ষেত্রগুলির কমপক্ষে তিনটি ফর্ম সমর্থন করে যা তারিখ, সময় এবং টাইমস্ট্যাম্প। এগুলির প্রত্যেকেরই জেডিবিসিতে একটি সম্পর্কিত ক্লাস রয়েছে এবং তাদের প্রতিটি প্রসারিত হয়েছেjava.util.Date
। এই তিনটির প্রত্যেকের দ্রুত শব্দার্থবিজ্ঞান নিম্নলিখিত:
java.sql.Date
এসকিউএল তারিখের সাথে সম্পর্কিত যার অর্থ এটি বছর, মাস এবং দিন সঞ্চয় করে যখন ঘন্টা, মিনিট, সেকেন্ড এবং মিলিসেকেন্ড উপেক্ষা করা হয়। অতিরিক্তভাবে sql.Date
টাইমজোনগুলিতে আবদ্ধ নয়।java.sql.Time
এসকিউএল টাইমের সাথে অনুরূপ এবং যেমনটি স্পষ্ট হওয়া উচিত, কেবলমাত্র ঘন্টা, মিনিট, সেকেন্ড এবং মিলিসেকেন্ড সম্পর্কিত তথ্য রয়েছে ।java.sql.Timestamp
এসকিউএল টাইমস্ট্যাম্পের সাথে সম্পর্কিত যা কাস্টমাইজযোগ্য নির্ভুলতার সাথে ন্যানোসেকেন্ডের জন্য সঠিক তারিখ ( কেবলমাত্র মিলিসেকেন্ডগুলিকে সমর্থন করে মনে করুন util.Date
! )।এই তিন প্রকারের সাথে জেডিবিসি ড্রাইভার ব্যবহার করার সময় সবচেয়ে সাধারণ বাগগুলির মধ্যে একটি হ'ল টাইপগুলি ভুলভাবে পরিচালনা করা হয়। এর অর্থ এটি sql.Date
হ'ল টাইমজোন নির্দিষ্ট, sql.Time
এতে রয়েছে চলতি বছর, মাস এবং দিন এবং এটি সিটিআর ইত্যাদি contains
ক্ষেত্রের এসকিউএল ধরণের উপর নির্ভর করে really PreparedStatement
তিনটি মানের জন্য সেটটার রয়েছে , এর জন্য এবং এর জন্য #setDate()
এক হচ্ছে ।sql.Date
#setTime()
sql.Time
#setTimestamp()
sql.Timestamp
মনে রাখবেন যে আপনি যদি ব্যবহার করেন তবে বেশিরভাগ জেডিবিসি ড্রাইভারকে আপনি ps.setObject(fieldIndex, utilDateObject);
একটি স্বাভাবিক দিতে পারেন util.Date
যা আনন্দের সাথে এটি গ্রাস করে ফেলবে যেন এটি সঠিক ধরণের ছিল তবে আপনি যখন ডেটাটির জন্য অনুরোধ করবেন তখন আপনি খেয়াল করতে পারেন যে আপনি আসলে স্টাফটি মিস করছেন।
আমি যা বলছি যে মিলি সেকেন্ড / ন্যানোসেকেন্ডগুলি সরল লম্বা হিসাবে সংরক্ষণ করুন এবং আপনি যে কোনও বস্তু ব্যবহার করছেন (তা বাধ্যতামূলক জোদা-সময় প্লাগ ) এ রূপান্তর করুন । একটি হ্যাকি উপায় যা করা যায় তা হ'ল তারিখের উপাদানটিকে একটি দীর্ঘ এবং সময়ের উপাদান হিসাবে অন্য হিসাবে সংরক্ষণ করা, উদাহরণস্বরূপ এখন 20100221 এবং 154536123 হবে These এই যাদু নম্বরগুলি এসকিউএল কোয়েরিতে ব্যবহার করা যেতে পারে এবং ডাটাবেস থেকে অন্যটিতে বহনযোগ্য হতে পারে আপনাকে জেডিবিসি / জাভা ডেট এপিআইয়ের পুরো অংশটি এড়াতে দেবে: সম্পূর্ণরূপে।
দেরি সম্পাদনা: জাভা 8 দিয়ে শুরু করে আপনার কোনওটিই এড়ানো উচিত নয় java.util.Date
এবং আপনি একেবারেইjava.sql.Date
এড়াতে পারবেন না এবং পরিবর্তে java.time
অন্য কোনও কিছুর চেয়ে প্যাকেজটি (জোদার উপর ভিত্তি করে) ব্যবহার করতে পছন্দ করুন। আপনি যদি জাভা 8 এ না থাকেন তবে আসল প্রতিক্রিয়াটি এখানে:
java.sql.Date
- যখন আপনি এটি ব্যবহার করে এমন লাইব্রেরিগুলির পদ্ধতি / নির্মাতাদের কল করেন (জেডিবিসির মতো)। অন্যথায় না। আপনি অ্যাপ্লিকেশন / মডিউলগুলির জন্য ডেটাবেস লাইব্রেরিতে নির্ভরতা প্রবর্তন করতে চান না যা স্পষ্টভাবে জেডিবিসির সাথে ডিল করে না।
java.util.Date
- এটি ব্যবহার করে এমন লাইব্রেরি ব্যবহার করার সময়। অন্যথায়, যতগুলি সম্ভব সম্ভব, বিভিন্ন কারণে:
এটি পরিবর্তনীয়, যার অর্থ প্রতিবার আপনি এটি পাস করার সময় এটির একটি প্রতিরক্ষামূলক অনুলিপি তৈরি করতে হবে বা কোনও পদ্ধতি থেকে ফিরে আসতে হবে।
এটি তারিখগুলি খুব ভালভাবে পরিচালনা করে না, যা আপনার পিছনে লোকেরা সত্যিকার অর্থে, ভাবার তারিখ পরিচালনা করার ক্লাসগুলি করা উচিত।
এখন, যেহেতু জুনডি এটি খুব ভাল কাজ করে না, তাই ভয়াবহ Calendar
ক্লাসগুলি চালু হয়েছিল। এগুলি পরিবর্তনীয়ও, এবং কাজ করার জন্য ভয়ঙ্কর এবং আপনার কোনও পছন্দ না থাকলে এড়ানো উচিত।
জোডা টাইম এপিআই এর মতো আরও ভাল বিকল্প রয়েছে ( এটি এটিকে জাভা into এ পরিণত করতে পারে এবং এটি নতুন অফিসিয়াল ডেট হ্যান্ডলিং এপিআইতে পরিণত হতে পারে - একটি দ্রুত অনুসন্ধান বলে যে এটি হবে না) won't
যদি আপনি মনে করেন যে জোড়ার মতো নতুন নির্ভরতা প্রবর্তন করা long
অত্যধিক দক্ষতা নয় তবে অবজেক্টগুলিতে টাইমস্ট্যাম্প ক্ষেত্রগুলির জন্য ব্যবহার করা এতটা খারাপ নয়, যদিও আমি নিজে এগুলি চারপাশে যাওয়ার সময় সাধারণত জিউডে আবদ্ধ করি, টাইপ সুরক্ষা এবং ডকুমেন্টেশন হিসাবে।
java.sql.Date
সঙ্গে PreparedStatement
ইত্যাদি! তবে যখন আপনি এটিকে পাশ কাটিয়ে চলেছেন তখন কোনওটি আপনি LocalDate
ব্যবহার করে java.sql.Date.valueOf
এবং java.sql.Date.valueOf
সেট করার সময় রূপান্তর করুন এবং যত তাড়াতাড়ি সম্ভব java.sql.Date.toLocalDate
- আবার ব্যবহার করে এটিকে আবার রূপান্তর করুন , কারণ আপনি যতটা সম্ভব জাভা.এসকিউএল যুক্ত করতে চান, এবং কারণ এটি পরিবর্তনীয়।
ব্যবহারের একমাত্র সময় java.sql.Date
হ'ল এক PreparedStatement.setDate
। অন্যথায়, ব্যবহার করুন java.util.Date
। এটি বলছে যে ResultSet.getDate
একটি প্রদান করে java.sql.Date
তবে এটি সরাসরি একটিতে নির্ধারিত হতে পারে java.util.Date
।
java.sql.Date
নির্ধারিত হতে পারে java.util.Date
? আপনি কি বিন্দু করতে চেষ্টা করছেন?
আমার একই সমস্যা ছিল, একটি প্রস্তুত বিবৃতিতে বর্তমান তারিখটি সন্নিবেশ করানোর সবচেয়ে সহজ উপায় আমি হ'ল:
preparedStatement.setDate(1, new java.sql.Date(new java.util.Date().getTime()));
না ব্যবহার করুন।
java.time.Instant
প্রতিস্থাপন java.util.Date
java.time.LocalDate
প্রতিস্থাপন java.sql.Date
java.util.Date বনাম java.sql.Date: কখন এবং কেন ব্যবহার করবেন?
এই উভয় শ্রেণিই ভয়ানক, নকশায় এবং বাস্তবায়নে ত্রুটিযুক্ত। প্লেগ করোনাভাইরাসের মতো এড়িয়ে চলুন ।
পরিবর্তে জেএসআর 310 এ সংজ্ঞায়িত জাভা.টাইম ক্লাসগুলি ব্যবহার করুন These এই ক্লাসগুলি তারিখ-সময় পরিচালনার সাথে কাজ করার জন্য একটি শিল্প-শীর্ষস্থানীয় কাঠামো। এই স্থানচ্যুত সম্পূর্ণভাবে রক্তাক্ত ভয়াবহ উত্তরাধিকার শ্রেণীর যেমন Date
, Calendar
, SimpleDateFormat
এবং এই ধরনের।
java.util.Date
প্রথমটি java.util.Date
হ'ল ইউটিসি-তে একটি মুহুর্তের প্রতিনিধিত্ব করে, যার অর্থ ইউটিসি থেকে শূন্য ঘন্টা-মিনিট-সেকেন্ডের অফসেট।
java.time.Instant
এখন দ্বারা প্রতিস্থাপিত java.time.Instant
।
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
java.time.OffsetDateTime
Instant
জাভা.টাইমের প্রাথমিক বিল্ডিং-ব্লক ক্লাস । আরও নমনীয়তার জন্য, একই উদ্দেশ্যে OffsetDateTime
সেট ব্যবহার করুন ZoneOffset.UTC
: ইউটিসিতে একটি মুহুর্তের প্রতিনিধিত্ব করুন।
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
আপনি ব্যবহার করে একটি ডাটাবেসের সাথে এই বস্তুর পাঠাতে পারেন PreparedStatement::setObject
সঙ্গে JDBC এর 4.2 বা পরবর্তী।
myPreparedStatement.setObject( … , odt ) ;
পুনরুদ্ধার করে।
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
java.sql.Date
java.sql.Date
বর্গ এছাড়াও ভয়ানক এবং অপ্রচলিত।
এই শ্রেণিটি কেবলমাত্র একটি তারিখ উপস্থাপন করতে বোঝানো হয়, কোনও সময়ের-সময় ব্যতীত এবং সময় অঞ্চল ছাড়া। দুর্ভাগ্যক্রমে, একটি ডিজাইনের ভয়াবহ হ্যাকের ক্ষেত্রে, এই শ্রেণিটি উত্তরাধিকার সূত্রে প্রাপ্ত java.util.Date
যা থেকে একটি মুহুর্তের প্রতিনিধিত্ব হয় (ইউটিসি-তে দিনের সাথে সময়সীমা)। সুতরাং এই শ্রেণিটি কেবলমাত্র তারিখের ভান করছে, যখন সত্যই সময়ের সময় এবং ইউটিসির অন্তর্নিহিত অফসেট বহন করে। এটি এত বিভ্রান্তির কারণ হয়। এই ক্লাসটি কখনই ব্যবহার করবেন না।
java.time.LocalDate
পরিবর্তে, java.time.LocalDate
কোনও সময়ের-সময় বা কোনও সময় অঞ্চল বা অফসেট ছাড়াই কেবলমাত্র একটি তারিখ (বছরের, মাস, মাসের মাসের) ট্র্যাক করতে ব্যবহার করুন ।
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate ld = LocalDate.now( z ) ; // Capture the current date as seen in the wall-clock time used by the people of a particular region (a time zone).
ডাটাবেসে প্রেরণ করুন।
myPreparedStatement.setObject( … , ld ) ;
পুনরুদ্ধার করে।
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
Java.time ফ্রেমওয়ার্ক জাভা 8 এবং পরে পাতাটা করা হয়। এই ক্লাসগুলি , & , এর মতো সমস্যাযুক্ত পুরানো উত্তরাধিকারের তারিখ-সময়ের ক্লাসগুলিকে সহায়তা করে ।java.util.Date
Calendar
SimpleDateFormat
আরও জানতে, ওরাকল টিউটোরিয়ালটি দেখুন । এবং অনেক উদাহরণ এবং ব্যাখ্যার জন্য স্ট্যাক ওভারফ্লো অনুসন্ধান করুন। স্পেসিফিকেশনটি জেএসআর 310 ।
Joda-টাইম প্রকল্প, এখন রক্ষণাবেক্ষণ মোড , মাইগ্রেশনে উপদেশ java.time ক্লাস।
আপনি আপনার ডাটাবেসের সাথে জাভা.টাইম অবজেক্টগুলি সরাসরি বিনিময় করতে পারেন । জেডিবিসি ৪.২ বা তারপরের সাথে অনুগত একটি জেডিবিসি ড্রাইভার ব্যবহার করুন । স্ট্রিংগুলির দরকার নেই, ক্লাসের প্রয়োজন নেই ।java.sql.*
জাভা.টাইম ক্লাস কোথায় পাবেন?
জাভা.উটিল.ডেট ক্লাসটি নির্দিষ্ট সময়ের জন্য একটি নির্দিষ্ট মুহুর্তের প্রতিনিধিত্ব করে (ই, .জি।, 2013 নভেম্বর 25 16:30:45 নিচে মিলি সেকেন্ডে) তবে ডিবিতে তারিখের ডেটা টাইপ কেবল একটি তারিখ উপস্থাপন করে (যেমন, 2013 নভেম্বর 25)। আপনাকে ভুলভাবে ডিবিতে java.util.Date অবজেক্ট সরবরাহ করা থেকে বিরত রাখতে, জাভা আপনাকে java.util.Date- এ সরাসরি এসকিউএল প্যারামিটার সেট করতে দেয় না:
PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, d); //will not work
তবে এটি এখনও আপনাকে জোর করে / অভিপ্রায় করে তা করতে দেয় (তারপরে কয়েক ঘন্টা এবং মিনিট ডিবি ড্রাইভার দ্বারা উপেক্ষা করা হবে)। এটি java.sql. তারিখ শ্রেণীর মাধ্যমে করা হয়:
PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, new java.sql.Date(d.getTime())); //will work
একটি java.sql.Date অবজেক্ট সময়মতো একটি মুহুর্ত সংরক্ষণ করতে পারে (যাতে এটি java.util.Date থেকে তৈরি করা সহজ) তবে আপনি যদি ঘন্টাখানেক জিজ্ঞাসা করার চেষ্টা করেন তবে তার ব্যতিক্রমী ধারণাটি প্রয়োগ করতে ব্যতিক্রম করবে কেবলমাত্র তারিখ)। ডিবি ড্রাইভারটি এই ক্লাসটি স্বীকৃতি দেবে এবং কয়েক ঘন্টা ধরে 0 ব্যবহার করবে বলে আশা করা হচ্ছে। এটা চেষ্টা কর:
public static void main(String[] args) {
java.util.Date d1 = new java.util.Date(12345);//ms since 1970 Jan 1 midnight
java.sql.Date d2 = new java.sql.Date(12345);
System.out.println(d1.getHours());
System.out.println(d2.getHours());
}
java.util.Date
মিলিসেকেন্ড যথার্থতার সাথে সময়টিতে একটি নির্দিষ্ট তাত্ক্ষণিকের প্রতিনিধিত্ব করে। এটি সময় অঞ্চল ছাড়া তারিখ এবং সময় উভয় তথ্য উপস্থাপন করে। Java.util.Date ক্লাসটি সিরিয়ালাইজেবল, ক্লোনযোগ্য এবং তুলনীয় ইন্টারফেস প্রয়োগ করে। এটি উত্তরাধিকারসূত্রে পাওয়া যায় java.sql.Date
, java.sql.Time
এবং java.sql.Timestamp
ইন্টারফেসগুলি।
java.sql.Date
java.util.Date ক্লাসটি প্রসারিত করে যা সময় তথ্য ব্যতিরেকে তারিখের প্রতিনিধিত্ব করে এবং এটি কেবল ডাটাবেসগুলির সাথে ডিল করার সময় ব্যবহার করা উচিত। এসকিউএল তারিখের সংজ্ঞা মেনে চলার জন্য, java.sql.Date
উদাহরণস্বরূপ মোড়ানো মিলিসেকেন্ড মানগুলি নির্দিষ্ট সময় অঞ্চলে ঘন্টা, মিনিট, সেকেন্ড এবং মিলিসেকেন্ডগুলিকে শূন্যের সাথে সেট করে অবশ্যই 'স্বাভাবিককরণ' করতে হবে যার সাথে উদাহরণটি যুক্ত রয়েছে।
এটা সব পাবলিক পদ্ধতি উত্তরাধিকারী java.util.Date
যেমন getHours()
, getMinutes()
, getSeconds()
, setHours()
, setMinutes()
, setSeconds()
। যেহেতু java.sql.Date
সময়ের তথ্য সংরক্ষণ করে না, এটি প্রয়োগের সমস্ত সময়কালে ওভাররাইড করে java.util.Date
এবং java.lang.IllegalArgumentException
যদি তাদের প্রয়োগের বিশদ থেকে স্পষ্ট প্রমাণিত হয় তবে এই সমস্ত পদ্ধতি নিক্ষেপ করে ।