সময়ের সাথে সাথে বর্তমান অবস্থা

যে সময় থেকে JDBC উদ্ভাবিত হয়েছিল এবং এর ইন্টারফেসগুলিকে মানসম্মত করা হয়েছিল, 20 বছর কেটে গেছে, এবং এই সময়ের মধ্যে অনেক কিছু পরিবর্তিত হয়েছে।

প্রথমত, বিশ্ব বিশ্বব্যাপী হয়ে উঠেছে এবং এখন একটি সার্ভার সারা বিশ্ব থেকে ব্যবহারকারীদের পরিষেবা দিতে পারে। ইন্টারনেটের গতি বেড়েছে। অতএব, সময়ের সাথে কাজ করার জন্য এসকিউএল-এ আরেকটি ডেটা টাইপ যোগ করা হয়েছিল । এখন প্রকারগুলি এইরকম দেখায়:

  • DATE - তারিখ সংরক্ষণ করে: বছর, মাস, দিন।
  • TIME - সময় সঞ্চয় করে: ঘন্টা, মিনিট, সেকেন্ড।
  • টাইমস্ট্যাম্প - সময়ের মধ্যে একটি নির্দিষ্ট বিন্দু সঞ্চয় করে: তারিখ, সময় এবং মিলিসেকেন্ড।
  • টাইম জোনের সাথে টাইমস্ট্যাম্প - টাইমস্ট্যাম্প এবং টাইম জোন (জোনের নাম বা অফসেট)।

দ্বিতীয়ত, জাভা গ্লোবাল টাইম ম্যানেজমেন্টের জন্য ডেটটাইম এপিআই চালু করেছে। এটির নিম্নলিখিত ক্লাস রয়েছে:

  • তারিখ এবং সময় :
    • স্থানীয় তারিখ
    • স্থানীয় সময়
  • সঠিক মুহূর্ত :
    • java.time.Instant
    • java.time.LocalDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime
  • সময় অঞ্চলের সাথে সময় :
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime

তৃতীয় আকর্ষণীয় বিষয় হল যে অনেক SQL ক্লায়েন্ট তাদের স্থানীয় অঞ্চলে ইতিমধ্যেই সার্ভার থেকে সময় পেতে চায় । অবশ্যই, আপনি ফ্লাইতে সময় রূপান্তর করতে পারেন, কিন্তু এটি সুবিধাজনক নয়, এবং ভুল আছে।

উদাহরণস্বরূপ, আমি ডাটাবেস থেকে আজকের জন্য সমস্ত কাজ পেতে চাই। SQL সার্ভার এর জন্য একটি CURDATE() ফাংশন আছে। শুধুমাত্র এখানে সার্ভারটি মার্কিন যুক্তরাষ্ট্রে এবং আমি জাপানে। এবং আমি চাই সে "আমার আজকের" জন্য সমস্ত রেকর্ড ফেরত দেবে, "তার আজকের" নয়।

সাধারণভাবে, SQL সার্ভারকে অবশ্যই বিভিন্ন সময় অঞ্চলে ক্লায়েন্টদের সাথে স্মার্টভাবে কাজ করতে সক্ষম হতে হবে।

আধুনিক সমস্যার আধুনিক সমাধান প্রয়োজন

নীতিগতভাবে, Java DateTime API থেকে নতুন ধরনের এবং SQL থেকে প্রকারগুলি সুবিধামত ম্যাপ করা যেতে পারে। জাভাতে DATE প্রকারের প্রতিনিধিত্ব করতে , আপনাকে JDK 8 DateTime API থেকে java.time.LocalDate ক্লাস ব্যবহার করতে হবে।

ডাটাবেস থেকে টাইম টাইপ জাভা থেকে দুই ধরনের দ্বারা প্রতিনিধিত্ব করা যেতে পারে: java.time.LocalTime এবং java.time.OffsetTime । জটিল কিছু না.

ডাটাবেসের টাইমস্ট্যাম্প টাইপ দ্বারা উপস্থাপিত সময়ের একটি নির্দিষ্ট বিন্দু, জাভাতে 4 প্রকার দ্বারা প্রতিনিধিত্ব করা যেতে পারে:

  • java.time.Instant
  • java.time.LocalDateTime
  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

এবং পরিশেষে, টাইম জোনের সাথে টাইমস্ট্যাম্প দুটি প্রকারের দ্বারা উপস্থাপন করা যেতে পারে:

  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

যেহেতু আপনি ইতিমধ্যেই DateTime API এর সাথে পরিচিত, তাই এই বিষয়টি মনে রাখা আপনার জন্য কঠিন হবে না :)

আমি এটি একটি টেবিল আকারে লিখব, তাই এটি সহজ হবে:

এসকিউএল টাইপ জাভা টাইপ
তারিখ java.time.LocalDate
টাইম java.time.LocalTime
java.time.OffsetTime
টাইমস্ট্যাম্প java.time.Instant
java.time.LocalDateTime
java.time.OffsetDateTime
java.time.ZonedDateTime
টাইম জোনের সাথে টাইমস্ট্যাম্প java.time.OffsetDateTime
_

তারিখ পাচ্ছেন

আমি আপনার জন্য একটি ভাল খবর আছে. দীর্ঘ সময়ের মধ্যে প্রথম। আমরা getDate() পদ্ধতির সীমাবদ্ধতা অতিক্রম করতে পারি , যা একটি java.sql তারিখের ধরন প্রদান করে।

বিন্দু যে বস্তুফলাফল সেটআরেকটি আকর্ষণীয় পদ্ধতি আছে - getObject() । এই পদ্ধতিতে দুটি প্যারামিটার লাগে: একটি কলাম এবং একটি টাইপ, এবং প্রদত্ত টাইপে রূপান্তরিত কলামের মান প্রদান করে। পদ্ধতির সাধারণ ফর্ম নিম্নরূপ:

ClassName Name = getObject(column, ClassName);

এবং আপনি যদি DATE প্রকারকে java.time.LocalDate type এ রূপান্তর করতে চান , তাহলে আপনাকে কিছু লিখতে হবে:

LocalDate localDate = results.getObject(4, LocalDate.class);

এবং সাধারণভাবে যেকোনো TIMESTAMP একগুচ্ছ প্রকারে রূপান্তরিত হতে পারে:

java.time.Instant instant = results.getObject(9, java.time.Instant.class);
java.time.LocalDateTime local = results.getObject(9, java.time. LocalDateTime.class);
java.time.OffsetDateTime offset = results.getObject(9, java.time. OffsetDateTime.class);
java.time.ZonedDateTime zoned = results.getObject(9, java.time. ZonedDateTime.class);

গুরুত্বপূর্ণ ! আপনার যদি পুরানো MySQL JDBC ড্রাইভার থাকে তবে এই কোডটি কাজ করবে না । আপনার pom.xml-এ লেখা "mysql-connector-java"-এর সংস্করণে মনোযোগ দিন, অথবা প্রকল্প সেটিংসে লাইব্রেরিতে যোগ করুন।

যাইহোক, একইভাবে, আপনি আদিম প্রকারের জন্য নাল সংরক্ষণ করার অক্ষমতার কাছাকাছি পেতে পারেন। যদি একটি টেবিল কলাম INT টাইপের হয়, তাহলে এটি থেকে নাল পাওয়ার কয়েকটি উপায় রয়েছে। নীচের উদাহরণ দেখুন:

Integer id1 = results.getObject(8, Integer.class);    	 // this will work
Integer id2 = results.getObject(8, int.class);                 //this will also work
int id3 = results.getObject(8,  Integer.class);            	//method will return null, JVM will throw NPE
int id4 = results.getObject(8,  int.class);                    	//method will return null, JVM will throw NPE

MySQL-এ টাইমজোন সেটিং

MySQL এর সাথেও অনেক আকর্ষণীয় জিনিস ঘটেছে। আপনি জানেন, একটি MySQL সংযোগ তৈরি করার সময়, আপনি এতে বিভিন্ন পরামিতি যোগ করতে পারেন :
mysql://localhost:3306/db_scheme?Name=meaning&Name=meaning

সুতরাং, মাইএসকিউএল-এ টাইম জোনের সাথে কাজ করার জন্য তিনটি প্যারামিটার যোগ করা হয়েছে। আপনি যখন সার্ভারে একটি সংযোগ স্থাপন করেন তখন আপনি এই পরামিতিগুলি পাস করতে পারেন৷

নীচে আমি তাদের সাথে একটি টেবিল দেব:

প্যারামিটার মূল্যবোধ ডিফল্ট মান
সংযোগ টাইমজোন স্থানীয় | সার্ভার | ব্যবহারকারী-জোন সার্ভার
forceConnectionTimeZoneToSession সত্য | মিথ্যা সত্য
তাত্ক্ষণিক সংরক্ষণ করুন সত্য | মিথ্যা মিথ্যা

কানেকশনটাইমজোন প্যারামিটার ব্যবহার করে , আমরা টাইম জোন (টাইম জোন) নির্বাচন করি যেখানে সমস্ত অনুরোধ কার্যকর করা হবে। ক্লায়েন্টের দৃষ্টিকোণ থেকে, সার্ভারটি নির্দিষ্ট সময় অঞ্চলে চলছে।

forceConnectionTimeZoneToSession প্যারামিটারের কারণে সেশন time_zone ভেরিয়েবল উপেক্ষা করা হয় এবং connectTimeZone দিয়ে প্রতিস্থাপিত হয়।

অবশেষে, preserveInstants প্যারামিটার JVM এর টাইমজোন এবং কানেকশনটাইমজোনের মধ্যে সঠিক-সময়-রূপান্তর নিয়ন্ত্রণ করে।

সবচেয়ে সাধারণ কনফিগারেশন হল:

  • connectionTimeZone=LOCAL & force ConnectionTimeZoneToSession=false - UseLegacyDatetimeCode=true সহ পুরানো MySQL JDBC ড্রাইভার সংস্করণ 5.1-এর সাথে মিলে যায়।

  • connectionTimeZone=LOCAL & force ConnectionTimeZoneToSession=true হল একটি নতুন মোড যা তারিখ এবং সময়ের মানগুলি পরিচালনা করার সবচেয়ে স্বাভাবিক উপায় প্রদান করে।

  • connectionTimeZone=SERVER & preserveInstants=true - পুরানো MySQL JDBC ড্রাইভার সংস্করণ 5.1 এর সাথে useLegacyDatetimeCode=false-এর সাথে মিলে যায়।

  • connectionTimeZone=user_defined & preserveInstants=true - এমন পরিস্থিতি কাটিয়ে উঠতে সাহায্য করে যেখানে সার্ভারের টাইম জোন সংযোগকারী দ্বারা স্বীকৃত হতে পারে না কারণ এটি CET/CEST-এর মতো জেনেরিক সংক্ষেপণ হিসাবে সেট করা হয়েছে।

হ্যাঁ, তারিখগুলি একটি আকর্ষণীয় বিষয় এবং তাদের সাথে অনেক সমস্যা রয়েছে। প্রবাদটি হিসাবে: এটি অবশ্যই ভীতিজনক, তবে আমিও বিরক্ত নই! :)