একটি নির্দিষ্ট পয়েন্টে সময় এবং তারিখের সাথে স্ট্রিংকে পার্স করা (জাভা এটিকে " Instant
" বলে ডাকে ) যথেষ্ট জটিল is জাভা বেশ কয়েকটি পুনরাবৃত্তিতে এটি মোকাবেলা করছে। সর্বশেষতম java.time
এবং এবং java.time.chrono
, প্রায় সমস্ত প্রয়োজনীয়তা ( টাইম ডাইলেশন :) বাদে ) covers
তবে সেই জটিলতা অনেকটা বিভ্রান্তি এনে দেয়।
তারিখ পার্সিং বোঝার মূল চাবিকাঠিটি হ'ল:
জাভা কেন একটি তারিখ বিশ্লেষণ করার অনেক উপায় আছে
- একটি সময় পরিমাপ করার জন্য বেশ কয়েকটি সিস্টেম রয়েছে। উদাহরণস্বরূপ, Japaneseতিহাসিক জাপানি ক্যালেন্ডারগুলি সংশ্লিষ্ট সম্রাট বা রাজবংশের সময়কাল থেকে উদ্ভূত হয়েছিল। তারপরে যেমন ইউনিক্স টাইমস্ট্যাম্প। ভাগ্যক্রমে, পুরো (ব্যবসায়) বিশ্ব একই ব্যবহার করতে সক্ষম হয়েছিল।
- Icallyতিহাসিকভাবে, বিভিন্ন কারণে সিস্টেমগুলি / থেকে স্যুইচ করা হচ্ছিল । যেমন জুলিয়ান ক্যালেন্ডার থেকে গ্রেগরিয়ান ক্যালেন্ডারে 1582 সালে So তাই 'পশ্চিমা' তারিখগুলির আগে আলাদা আচরণ করা দরকার।
- এবং অবশ্যই পরিবর্তনটি একবারে ঘটেনি। কারণ ক্যালেন্ডারটি কিছু ধর্মের সদর দফতর থেকে এসেছিল এবং ইউরোপের অন্যান্য অংশগুলি অন্যান্য ডায়েটে বিশ্বাস করে, উদাহরণস্বরূপ জার্মানি 1700 সাল পর্যন্ত পরিবর্তন করে নি।
... এবং কেন LocalDateTime
, ZonedDateTime
ইত্যাদি। তাই জটিল
আছে সময় অঞ্চল । একটি সময় অঞ্চল হ'ল মূলত পৃথিবীর পৃষ্ঠের একটি "স্ট্রিপ" * [[1] যার কর্তৃপক্ষগুলি কখন কখন অফসেট থাকে তার একই নিয়ম অনুসরণ করে। এর মধ্যে গ্রীষ্মের সময় নিয়ম অন্তর্ভুক্ত।
সময় অঞ্চল বিভিন্ন অঞ্চলগুলির জন্য সময়ের সাথে সাথে পরিবর্তিত হয়, বেশিরভাগের উপর নির্ভর করে কে কাকে বিজয়ী করে। এবং সময়ের সাথে সাথে এক সময় অঞ্চলের নিয়মগুলিও পরিবর্তিত হয় ।
সময় অফসেট আছে। এটি সময় অঞ্চলগুলির মতো নয়, কারণ একটি সময় অঞ্চল যেমন "প্রাগ" হতে পারে তবে গ্রীষ্মের সময় অফসেট এবং শীতের সময় অফসেট থাকে।
আপনি যদি কোনও সময় অঞ্চলটির সাথে টাইমস্ট্যাম্প পান তবে অফসেটটি পরিবর্তিত হতে পারে, এটি বছরের কোন অংশে থাকে তার উপর নির্ভর করে le রূপান্তরিত।
দ্রষ্টব্য: টাইমস্ট্যাম্পের দ্বারা আমার অর্থ "একটি স্ট্রিং যা একটি তারিখ এবং / অথবা সময় ধারণ করে, বিকল্পভাবে সময় অঞ্চল এবং / অথবা সময় অফসেট সহ" "
বেশ কয়েকটি সময় অঞ্চল নির্দিষ্ট সময়ের জন্য একই সময়ে অফসেট ভাগ করতে পারে। উদাহরণস্বরূপ, গ্রীষ্মের সময় অফসেট কার্যকর না হলে GMT / UTC সময় অঞ্চলটি "লন্ডন" টাইম জোনের সমান।
এটিকে কিছুটা জটিল করার জন্য (তবে এটি আপনার ব্যবহারের ক্ষেত্রে খুব বেশি গুরুত্বপূর্ণ নয়):
- বিজ্ঞানীরা পৃথিবীর গতিশীল পর্যবেক্ষণ করেন, যা সময়ের সাথে সাথে পরিবর্তিত হয়; তার উপর ভিত্তি করে, তারা পৃথক বছর শেষে কয়েক সেকেন্ড যুক্ত করে। (সুতরাং
2040-12-31 24:00:00
একটি বৈধ তারিখ-সময় হতে পারে)) এটির জন্য মেটাডেটার নিয়মিত আপডেটগুলি দরকার যা সিস্টেমগুলি তারিখ রূপান্তরগুলি সঠিক করতে ব্যবহার করে। যেমন লিনাক্সে, আপনি জাভা প্যাকেজগুলিতে এই নতুন ডেটা সহ নিয়মিত আপডেট পান।
আপডেটগুলি সর্বদা historicalতিহাসিক এবং ভবিষ্যতের উভয় টাইমস্ট্যাম্পের জন্য পূর্বের আচরণকে রাখে না। সুতরাং এটি ঘটতে পারে যে দুটি টাইমস্ট্যাম্পগুলির তুলনা করে কিছু সময় অঞ্চলের পরিবর্তনের সাথে তাদের তুলনা করা সফ্টওয়্যারটির বিভিন্ন সংস্করণে চলার সময় বিভিন্ন ফলাফল দিতে পারে । এটি প্রভাবিত সময় অঞ্চল এবং অন্যান্য সময় অঞ্চলের মধ্যে তুলনার ক্ষেত্রেও প্রযোজ্য।
এটির কারণে আপনার সফ্টওয়্যারটিতে কোনও ত্রুটি দেখা দিতে পারে, এমন কিছু টাইমস্ট্যাম্প ব্যবহার করা বিবেচনা করুন যা ইউনিক্স টাইমস্ট্যাম্পের মতো জটিল নিয়ম না করে ।
7 এর কারণে, ভবিষ্যতের তারিখগুলির জন্য, আমরা তারিখগুলি নির্ভুলতার সাথে রূপান্তর করতে পারি না। সুতরাং, উদাহরণস্বরূপ, বর্তমানের পার্সিং 8524-02-17 12:00:00
ভবিষ্যতের বিশ্লেষণ থেকে কয়েক সেকেন্ড বন্ধ হতে পারে।
এর জন্য জেডিকের এপিআইগুলি সমসাময়িক প্রয়োজনের সাথে বিকশিত হয়েছিল
- প্রারম্ভিক জাভা রিলিজগুলির
java.util.Date
কিছুটা নিখরচায় দৃষ্টিভঙ্গি ছিল যা ধরে নিয়েছিল যে বছর, মাস, দিন এবং সময় আছে। এটি দ্রুত যথেষ্ট ছিল না।
- এছাড়াও, ডাটাবেসের প্রয়োজনীয়তা আলাদা ছিল, তাই খুব তাড়াতাড়ি,
java.sql.Date
এর নিজস্ব সীমাবদ্ধতা প্রবর্তিত হয়েছিল।
- যেহেতু উভয়ই বিভিন্ন ক্যালেন্ডার এবং সময় অঞ্চলগুলি ভালভাবে কভার করেনি,
Calendar
এপিআই চালু হয়েছিল।
- এটি এখনও সময় অঞ্চলগুলির জটিলতা coverাকেনি। এবং তবুও, উপরের এপিআইগুলির মিশ্রণটি কাজ করার জন্য সত্যই একটি ব্যথা ছিল। সুতরাং জাভা বিকাশকারীরা বিশ্ব ওয়েব অ্যাপ্লিকেশনগুলিতে কাজ শুরু করার সাথে সাথে জোডাটাইমের মতো বেশিরভাগ ব্যবহারের ক্ষেত্রে লক্ষ্যযুক্ত লাইব্রেরিগুলি দ্রুত জনপ্রিয় হয়ে উঠল। জোডাটাইম প্রায় এক দশক ধরে ডি-ফ্যাক্টো স্ট্যান্ডার্ড ছিল।
- তবে জেডিকে জোদাটাইমের সাথে সংহত হয়নি, তাই এর সাথে কাজ করা কিছুটা জটিল ছিল। সুতরাং, কিভাবে ব্যাপার কাছে উপর একটি খুব দীর্ঘ আলোচনার পর, JSR-310 তৈরি করা হয়েছে প্রধানত JodaTime উপর ভিত্তি করে ।
জাভা এর সাথে এটি কীভাবে মোকাবেলা করবেন java.time
কোন টাইমস্ট্যাম্পকে পার্স করতে হবে তা নির্ধারণ করুন
আপনি যখন টাইমস্ট্যাম্প স্ট্রিং ব্যবহার করছেন তখন আপনাকে এটিতে কী তথ্য রয়েছে তা জানতে হবে। এটি গুরুত্বপূর্ণ পয়েন্ট। আপনি যদি এই অধিকার না পান তবে আপনি "তাত্ক্ষণিক তৈরি করতে পারবেন না" বা "জোন অফসেট অনুপস্থিত" বা "অজানা অঞ্চল আইডি" ইত্যাদির মতো একটি ক্রিপ্টিক ব্যতিক্রমগুলি শেষ করবেন
এতে কি তারিখ এবং সময় রয়েছে?
এটি একটি সময় অফসেট আছে?
একটি সময় অফসেট +hh:mm
অংশ হয়। কখনও কখনও, 'জুলু সময়', ইউনিভার্সাল সময় সমন্বিত, বা গ্রিনিচ গড় সময় হিসাবে +00:00
পরিবর্তিত হতে পারে । এগুলি সময় অঞ্চল নির্ধারণ করে।
এই টাইমস্ট্যাম্পগুলির জন্য, আপনি ব্যবহার করুন ।Z
UTC
GMT
OffsetDateTime
এটির কি টাইম জোন আছে?
এই টাইমস্ট্যাম্পগুলির জন্য, আপনি ব্যবহার করুন ZonedDateTime
।
অঞ্চল দ্বারা হয় নির্দিষ্ট করা হয়
- নাম ("প্রাগ", "প্যাসিফিক স্ট্যান্ডার্ড সময়", "পিএসটি"), বা
- "জোন আইডি" ("আমেরিকা / লস_এঞ্জেলস", "ইউরোপ / লন্ডন"), জাভা.টাইম.জোনআইডি দ্বারা উপস্থাপিত ।
সময় অঞ্চলগুলির তালিকা আইসিএএএন সমর্থিত একটি "টিজেড ডাটাবেস" দ্বারা সংকলিত হয়েছে ।
ZoneId
এর জাভাদোকের মতে , জোন আইডির কোনওরকমভাবে সেট Z
ও অফসেটও নির্দিষ্ট করা যেতে পারে । আমি নিশ্চিত না কীভাবে এই অঞ্চলগুলি বাস্তব অঞ্চলে যাবে। টাইমস্ট্যাম্প, যা কেবলমাত্র একটি টিজেড রয়েছে, অফসেট পরিবর্তনের এক লিপ ঘন্টার মধ্যে পড়ে যদি তা যায় তবে তা অস্পষ্ট, এবং ব্যাখ্যাটির বিষয় ResolverStyle
, নীচে দেখুন।
যদি এটি না থাকে তবে অনুপস্থিত প্রসঙ্গটি ধরে নেওয়া বা অবহেলা করা হবে। এবং ভোক্তা সিদ্ধান্ত নিতে হবে। সুতরাং এটি অনুপস্থিত তথ্য যুক্ত করে পার্স LocalDateTime
এবং রূপান্তর করা দরকার OffsetDateTime
:
- আপনি ধরে নিতে পারেন যে এটি একটি ইউটিসি সময়। ইউটিসি 0 ঘন্টা অফসেট যোগ করুন।
- আপনি ধরে নিতে পারেন যে এটি সেই স্থানের সময় যেখানে স্থানান্তর ঘটছে। সিস্টেমের সময় অঞ্চল যুক্ত করে এটিকে রূপান্তর করুন।
- আপনি অবহেলা করতে পারেন এবং ঠিক যেমন এটি ব্যবহার করতে পারেন। এটি দরকারী যেমন উদাহরণস্বরূপ বা দুটি বার বিয়োগ (দেখুন
Duration
), বা যখন আপনি জানেন না এবং এটি সত্যিই কিছু যায় না (যেমন স্থানীয় বাসের সময়সূচী)।
আংশিক সময়ের তথ্য
- কি টাইমস্ট্যাম্প রয়েছে উপর ভিত্তি করে, আপনি গ্রহণ করতে পারেন
LocalDate
, LocalTime
, OffsetTime
, MonthDay
, Year
, অথবা YearMonth
এটা শেষ হয়ে এসেছে।
আপনার কাছে সম্পূর্ণ তথ্য থাকলে আপনি একটি পেতে পারেন java.time.Instant
। এটি অভ্যন্তরীণভাবে OffsetDateTime
এবং এর মধ্যে রূপান্তর করতে ব্যবহৃত হয় ZonedDateTime
।
কীভাবে এটি পার্স করবেন তা চিত্রিত করুন
একটি বিস্তৃত ডকুমেন্টেশন রয়েছে DateTimeFormatter
যার উপর উভয়ই টাইমস্ট্যাম্প স্ট্রিং এবং স্ট্রিংয়ে ফর্ম্যাটকে পার্স করতে পারে।
প্রাক নির্মিত DateTimeFormatter
গুলি moreless সব মান টাইমস্ট্যাম্প ফরম্যাটের ঢেকে রাখুক। উদাহরণস্বরূপ, ISO_INSTANT
পার্স করতে পারেন 2011-12-03T10:15:30.123457Z
।
আপনার যদি কিছু বিশেষ ফর্ম্যাট থাকে তবে আপনি নিজের ডেটটাইম ফর্ম্যাটর তৈরি করতে পারেন (যা পার্সারও রয়েছে)।
private static final DateTimeFormatter TIMESTAMP_PARSER = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SX"))
.toFormatter();
আমি এর উত্স কোডটি দেখার DateTimeFormatter
এবং কীভাবে এটি ব্যবহার করে একটি তৈরি করতে হবে সে সম্পর্কে অনুপ্রাণিত হওয়ার পরামর্শ দিয়েছি DateTimeFormatterBuilder
। আপনি সেখানে ResolverStyle
থাকাকালীন, ফর্ম্যাটগুলি এবং অস্পষ্ট তথ্যের জন্য পার্সার লেন্সিয়েন্ট, স্মার্ট বা স্ট্রাইক কিনা তা নিয়ন্ত্রণ করে।
TemporalAccessor
এখন, ঘন ঘন ভুলটি জটিলতায় intoোকে TemporalAccessor
। এটি কীভাবে বিকাশকারীদের সাথে কাজ করতে ব্যবহৃত হয়েছিল তা থেকে আসে SimpleDateFormatter.parse(String)
। ঠিক আছে, DateTimeFormatter.parse("...")
আপনাকে দেয় TemporalAccessor
।
// No need for this!
TemporalAccessor ta = TIMESTAMP_PARSER.parse("2011-... etc");
তবে, পূর্ববর্তী বিভাগের জ্ঞান দিয়ে সজ্জিত, আপনি সহজেই আপনার প্রয়োজনীয় ধরণের পার্স করতে পারেন:
OffsetDateTime myTimestamp = OffsetDateTime.parse("2011-12-03T10:15:30.123457Z", TIMESTAMP_PARSER);
আপনার আসলে কোনওটির দরকার নেই DateTimeFormatter
। আপনি যে ধরণের পার্স করতে চান সেগুলির parse(String)
পদ্ধতি রয়েছে।
OffsetDateTime myTimestamp = OffsetDateTime.parse("2011-12-03T10:15:30.123457Z");
সম্পর্কিত TemporalAccessor
, আপনি স্ট্রিংয়ে কী তথ্য আছে সে সম্পর্কে অস্পষ্ট ধারণা থাকলে এবং রানটাইমে সিদ্ধান্ত নিতে চাইলে আপনি এটি ব্যবহার করতে পারেন।
আমি আশা করি আমি আপনার আত্মার উপর কিছুটা বোঝার আলো ফেলেছি :)
দ্রষ্টব্য: java.time
জাভা 6 এবং 7: থ্রিটেন-ব্যাকপোর্টের ব্যাকপোর্ট রয়েছে । অ্যান্ড্রয়েডের জন্য এটিতে থ্রিটেনএবিপি রয়েছে ।
[1] কেবল এগুলি নয় যে তারা স্ট্রিপস নয়, তবে কিছু অদ্ভুত মাত্রাও রয়েছে। উদাহরণস্বরূপ, কিছু প্রতিবেশী প্রশান্ত মহাসাগরীয় দ্বীপগুলিতে +14: 00 এবং -11: 00 সময় অঞ্চল রয়েছে। এর অর্থ হ'ল, এক দ্বীপে থাকাকালীন 1 মে 3 অপরাহ্ন, অন্য দ্বীপে এখনও অবধি নেই, এখনও 30 এপ্রিল 12 পিএম (যদি আমি সঠিকভাবে গণনা করি :))
ZonedDateTime
না চেয়ে চাইবেLocalDateTime
। নামটি পাল্টা স্বজ্ঞাত;Local
মানে কোন একটি নির্দিষ্ট সময়ের অঞ্চল সাধারণভাবে এলাকার বদলে। যেমন, কোনওLocalDateTime
বস্তু সময় লাইনের সাথে আবদ্ধ হয় না। অর্থের অর্থ, সময়রেখায় একটি নির্দিষ্ট মুহুর্ত পেতে আপনাকে অবশ্যই একটি সময় অঞ্চল প্রয়োগ করতে হবে।