উত্তর:
আমার এই 10 বছরের পুরানো প্রশ্নের পিছনে একটি পদক্ষেপ এবং আধুনিক চেহারা নেওয়া উচিত। ক্লাস উল্লেখ করা হয়েছে, Date
এবং XMLGregorianCalendar
এখন বয়স। আমি তাদের ব্যবহারকে চ্যালেঞ্জ জানাই এবং বিকল্প প্রস্তাব দিই।
Date
সর্বদা দুর্বল নকশা করা হয়েছিল এবং 20 বছরেরও বেশি পুরানো। এটি সহজ: এটি ব্যবহার করবেন না।XMLGregorianCalendar
খুব পুরানো এবং একটি পুরানো ফ্যাশন নকশা আছে। আমি এটি বুঝতে পেরে, এটি এক্সএমএল নথিগুলির জন্য এক্সএমএল ফর্ম্যাটে তারিখ এবং সময় উত্পাদন করার জন্য ব্যবহৃত হয়েছিল। লাইক 2009-05-07T19:05:45.678+02:00
বা 2009-05-07T17:05:45.678Z
। এই ফর্ম্যাটগুলি আইএসও 8601 এর সাথে যথেষ্ট সম্মত হয় যে জাভা.টাইম, আধুনিক জাভা তারিখ এবং সময় এপিআই, এর ক্লাসগুলি তাদের উত্পাদন করতে পারে, যা আমরা পছন্দ করি।অনেক (সবচেয়ে?) উদ্দেশ্যে একটি জন্য আধুনিক প্রতিস্থাপন Date
একটি হতে হবে Instant
। একটি Instant
সময় একটি পয়েন্ট (ঠিক যেমন একটি Date
হয়)।
Instant yourInstant = // ...
System.out.println(yourInstant);
এই স্নিপেট থেকে একটি উদাহরণ আউটপুট:
2009-05-07T17: 05: 45.678Z
এটি আমার উদাহরণস্বরূপ XMLGregorianCalendar
স্ট্রিংয়ের উপরেরটি একই । আপনারা বেশিরভাগই জানেন যে এটি Instant.toString
স্পষ্টভাবে দ্বারা ডাকা হচ্ছে System.out.println
। Java.time সঙ্গে, অনেক ক্ষেত্রে আমরা ধর্মান্তর পুরানো দিনের মধ্যে আমরা মধ্যে গঠিত যে প্রয়োজন হবে না Date
, Calendar
, XMLGregorianCalendar
এবং অন্যান্য শ্রেণীর (কিছু কিছু ক্ষেত্রে আমরা প্রয়োজন ধর্মান্তর না, যদিও, আমি আপনাকে পরবর্তী বিভাগে একটি দম্পতি দেখাচ্ছে am) ।
আমরাও একটি Date
কিংবা মধ্যে Instant
কোন সময় জোন পেয়েছে অথবা একটি ইউটিসি অফসেট। বেন নোল্যান্ডের পূর্বে গৃহীত এবং এখনও সর্বাধিক ভোট দেওয়া জবাবটি অফসেট নির্বাচনের জন্য জেভিএমের বর্তমান ডিফল্ট সময় অঞ্চল ব্যবহার করে XMLGregorianCalendar
। একটি আধুনিক অবজেক্টে অফসেট অন্তর্ভুক্ত করতে আমরা একটি ব্যবহার করি OffsetDateTime
। উদাহরণ স্বরূপ:
ZoneId zone = ZoneId.of("America/Asuncion");
OffsetDateTime dateTime = yourInstant.atZone(zone).toOffsetDateTime();
System.out.println(dateTime);
2009-05-07T13: 05: 45.678-04: 00
আবার এটি এক্সএমএল ফর্ম্যাট অনুসারে। আপনি বর্তমান জেভিএম সময় অঞ্চল সেটিং আবার ব্যবহার করতে চান তাহলে, সেট zone
করতে ZoneId.systemDefault()
।
রূপান্তর Instant
করার আরও অনেক উপায় আছে XMLGregorianCalendar
। আমি একটি দম্পতি উপস্থাপন করব, প্রত্যেককে এর উপকারিতা এবং বিপরীতে। প্রথমত, যেমন XMLGregorianCalendar
একটি স্ট্রিং তৈরি করে 2009-05-07T17:05:45.678Z
, তেমন স্ট্রিং থেকেও এটি তৈরি করা যায়:
String dateTimeString = yourInstant.toString();
XMLGregorianCalendar date2
= DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTimeString);
System.out.println(date2);
2009-05-07T17: 05: 45.678Z
প্রো: এটি সংক্ষিপ্ত এবং আমি কোনও চমক দেয় বলে মনে করি না। কন: আমার কাছে এটি তাত্ক্ষণিকভাবে কোনও স্ট্রিংতে তাত্ক্ষণিক বিন্যাস করে পিছনে পার্স করার মতো মনে হয়।
ZonedDateTime dateTime = yourInstant.atZone(zone);
GregorianCalendar c = GregorianCalendar.from(dateTime);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
System.out.println(date2);
2009-05-07T13: 05: 45.678-04: 00
প্রো: এটি সরকারী রূপান্তর। অফসেট নিয়ন্ত্রণ করা স্বাভাবিকভাবেই আসে। কন: এটি আরও পদক্ষেপগুলির মধ্য দিয়ে যায় এবং তাই দীর্ঘ।
যদি আপনি Date
কোনও লিগ্যাসি এপিআই থেকে একটি পুরানো ফ্যাশনযুক্ত জিনিস পেয়ে থাকেন যা এখনই আপনি পরিবর্তনের পক্ষে না পারেন তবে এটিকে রূপান্তর করুন Instant
:
Instant i = yourDate.toInstant();
System.out.println(i);
আউটপুট আগের মতো:
2009-05-07T17: 05: 45.678Z
আপনি যদি অফসেটটি নিয়ন্ত্রণ করতে চান তবে OffsetDateTime
উপরের মত একইভাবে আরও একটি রূপান্তর করুন ।
যদি আপনি একটি পুরানো ফ্যাশন পেয়ে থাকেন Date
এবং একেবারে পুরানো XMLGregorianCalendar
শৈলীর প্রয়োজন হয়, তবে বেন নোল্যান্ডের উত্তরটি ব্যবহার করুন।
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
তাদের এখানে যা বিপরীত রূপান্তরটির জন্য এখানে থেকে শেষ হতে পারে from XMLGregorianCalendar
করতে Date
):
XMLGregorianCalendar xcal = <assume this is initialized>;
java.util.Date dt = xcal.toGregorianCalendar().getTime();
গ্রেগরিয়ানক্যালেন্ডার থেকে এক্সএমএল গ্রেগরিয়ানক্যালেন্ডারে রূপান্তর করার জন্য একটি পদ্ধতি এখানে রয়েছে; আমি আপনার জন্য অনুশীলন হিসাবে java.util. তারিখ থেকে গ্রেগরিয়ানক্যালেন্ডারে রূপান্তর করার অংশটি ছেড়ে দেব:
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
public class DateTest {
public static void main(final String[] args) throws Exception {
GregorianCalendar gcal = new GregorianCalendar();
XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(gcal);
System.out.println(xgcal);
}
}
সম্পাদনা: স্লুও :-)
জোদা-টাইম লাইব্রেরি ব্যবহার করে একটি লাইন উদাহরণ :
XMLGregorianCalendar xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(new DateTime().toGregorianCalendar());
গৃহীত উত্তরে তার মন্তব্য থেকে নিকোলাস মোমাদার্সকে কৃতিত্ব ।
কেবল ভেবেছি আমি নীচে আমার সমাধান যুক্ত করব, যেহেতু উপরের উত্তরগুলি আমার সঠিক চাহিদা মেটাচ্ছে না। আমার এক্সএমএল স্কিমাটির জন্য পৃথক তারিখ এবং সময় উপাদানগুলির প্রয়োজন, একটি সেজ ডেটিটাইম ক্ষেত্র নয়। উপরে ব্যবহৃত স্ট্যান্ডার্ড এক্সএমএল গ্রেগরিয়ানক্যালেন্ডার কনস্ট্রাক্টর একটি ডেটটাইম ক্ষেত্র তৈরি করবে
সেখানে কয়েকটি গোথকা নোট করুন, যেমন মাসে একটি যুক্ত করা (যেহেতু জাভা মাস থেকে 0 থেকে গণনা করা হয়)।
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(yourDate);
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH), 0);
XMLGregorianCalendar xmlTime = DatatypeFactory.newInstance().newXMLGregorianCalendarTime(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), 0);
আমি আশা করি এখানে আমার এনকোডিংটি ঠিক আছে; ডি এটি দ্রুত করার জন্য কেবল কনগ্রাক্টর কলের পরিবর্তে গ্রেগরিয়ানক্যালেন্ডারের কলস ব্যবহার করুন:
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
public class DateTest {
public static void main(final String[] args) throws Exception {
// do not forget the type cast :/
GregorianCalendar gcal = (GregorianCalendar) GregorianCalendar.getInstance();
XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(gcal);
System.out.println(xgcal);
}
}
GregorianCalendar.getInstance()
এর সমতূল্য Calendar.getInstance()
। Calendar.getInstance()
, এটি দ্রুত করতে পারেন না, কারণ এটি একই ব্যবহার new GregorianCalendar()
, কিন্তু আগেই ডিফল্ট লোকেল পরীক্ষা এবং পরিবর্তে জাপানি বা Buddish ক্যালেন্ডার তৈরি করতে পারে নি, তাই ততক্ষণ ভাগ্যবান ব্যবহারকারীদের জন্য এটা হবে ClassCastException
!
ধরে JAXB
নিই যে আপনি ডিকোডিং করছেন বা এক্সএমএল এনকোড করছেন এবং ব্যবহার করছেন , তাহলে ডেটটাইম বাইন্ডিং সম্পূর্ণরূপে প্রতিস্থাপন করা এবং স্কিমাতে প্রতিটি তারিখের জন্য 'এক্সএমএলগ্রিগরিয়ানক্যালেন্ডার' ব্যতীত অন্য কিছু ব্যবহার করা সম্ভব।
যেভাবে আপনি করতে পারেন JAXB
পুনরাবৃত্তিমূলক জিনিসগুলি রাখতে পারেন যখন আপনি মূল্যবান বিতরণকারী দুর্দান্ত কোড লেখার জন্য সময় ব্যয় করতে পারেন।
জোডাটাইমের উদাহরণ DateTime
: (java.util.Date দিয়ে এটি করাও কাজ করবে - তবে নির্দিষ্ট সীমাবদ্ধতার সাথে। আমি জোদাটিম পছন্দ করি এবং এটি আমার কোড থেকে অনুলিপি করা হয় তাই আমি জানি যে এটি কাজ করে ...)
<jxb:globalBindings>
<jxb:javaType name="org.joda.time.LocalDateTime" xmlType="xs:dateTime"
parseMethod="test.util.JaxbConverter.parseDateTime"
printMethod="se.seb.bis.test.util.JaxbConverter.printDateTime" />
<jxb:javaType name="org.joda.time.LocalDate" xmlType="xs:date"
parseMethod="test.util.JaxbConverter.parseDate"
printMethod="test.util.JaxbConverter.printDate" />
<jxb:javaType name="org.joda.time.LocalTime" xmlType="xs:time"
parseMethod="test.util.JaxbConverter.parseTime"
printMethod="test.util.JaxbConverter.printTime" />
<jxb:serializable uid="2" />
</jxb:globalBindings>
এবং রূপান্তরকারী:
public class JaxbConverter {
static final DateTimeFormatter dtf = ISODateTimeFormat.dateTimeNoMillis();
static final DateTimeFormatter df = ISODateTimeFormat.date();
static final DateTimeFormatter tf = ISODateTimeFormat.time();
public static LocalDateTime parseDateTime(String s) {
try {
if (StringUtils.trimToEmpty(s).isEmpty())
return null;
LocalDateTime r = dtf.parseLocalDateTime(s);
return r;
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static String printDateTime(LocalDateTime d) {
try {
if (d == null)
return null;
return dtf.print(d);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static LocalDate parseDate(String s) {
try {
if (StringUtils.trimToEmpty(s).isEmpty())
return null;
return df.parseLocalDate(s);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static String printDate(LocalDate d) {
try {
if (d == null)
return null;
return df.print(d);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static String printTime(LocalTime d) {
try {
if (d == null)
return null;
return tf.print(d);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static LocalTime parseTime(String s) {
try {
if (StringUtils.trimToEmpty(s).isEmpty())
return null;
return df.parseLocalTime(s);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
এখানে দেখুন: কীভাবে তারিখ অনুসারে এক্সএমএল গ্রেগরিয়ানক্যালেন্ডার প্রতিস্থাপন করবেন?
আপনি যদি টাইমজোন + টাইমস্ট্যাম্পের ভিত্তিতে কেবল তাত্ক্ষণিক মানচিত্র করতে খুশি হন এবং মূল সময় অঞ্চলটি সত্যিই প্রাসঙ্গিক না java.util.Date
হয় তবে সম্ভবত খুব ভাল।
এই কোডটি দেখুন: -
/* Create Date Object */
Date date = new Date();
XMLGregorianCalendar xmlDate = null;
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(date);
try{
xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
}
catch(Exception e){
e.printStackTrace();
}
System.out.println("XMLGregorianCalendar :- " + xmlDate);
আপনি এখানে সম্পূর্ণ উদাহরণ দেখতে পারেন
ZonedDateTime
শ্রেণি দেখুন এবং উত্তরাধিকার শ্রেণিতে নতুন রূপান্তর পদ্ধতি যুক্ত হয়েছে added এই উত্তরে ওলে ভিভি-র বিবরণ