java.util.Date এক্সএমএল গ্রেগরিয়ানক্যালেন্ডারে


600

জাভা.উটিল.ডেট থেকে এক্সএমএল গ্রেগরিয়ানক্যালেন্ডারে যাওয়ার কোনও সুবিধাজনক উপায় নেই?


এফওয়াইআই: এই দু'টি ভয়ংকর ক্লাস দুটি বছর পূর্বে জেএসআর 310-এ সংজ্ঞায়িত জাভা.টাইম ক্লাস দ্বারা সংবহন করা হয়েছিল। ZonedDateTimeশ্রেণি দেখুন এবং উত্তরাধিকার শ্রেণিতে নতুন রূপান্তর পদ্ধতি যুক্ত হয়েছে added এই উত্তরে ওলে ভিভি-র বিবরণ
বাসিল বাউরক

উত্তর:


35

আমার এই 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শৈলীর প্রয়োজন হয়, তবে বেন নোল্যান্ডের উত্তরটি ব্যবহার করুন।

লিংক


1034
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);

5
কিছু রূপান্তরকারী শ্রেণিতে স্থিতিশীল পরিবর্তনশীল হিসাবে getInstance () রাখার জন্য এটি সংরক্ষণ করা হয়? আমি জাভাডকে এটি সন্ধান করার চেষ্টা করেছি কিন্তু কিছুই পাইনি। একসাথে ব্যবহারের ক্ষেত্রে সমস্যা হবে কিনা তা জানা শক্ত?
মার্টিন

36
আপনি যদি জোডটাইম ব্যবহার করতে ইচ্ছুক হন তবে আপনি এটি এক লাইনে করতে পারেন: ডেটাটাইপফ্যাক্টরি.নিউইনস্ট্যান্স ()। নতুন এক্সএমএল গ্রেগরিয়ানক্যালেন্ডার (নতুন ডেটটাইম ()। টু গ্রেগরিয়ানক্যালেন্ডার ())
নিকোলাস Mommaerts

3
এক্সএমএল গ্রেগরিয়ানক্যালেন্ডার তারিখ 2 = ডেটাটাইপফ্যাক্টরি.নিউইনস্ট্যান্স ()। নতুন এক্সএমএল গ্রেগরিয়ানক্যালেন্ডার (নতুন গ্রেগরিয়ানক্যালেন্ডার (ওয়াইওয়াইওয়াই, এমএম, ডিডি));
জুনচেন লিউ

3
দয়া করে সচেতন হন যে ক্যালেন্ডারটি থ্রেডসেফ নয় এবং সেইজন্য গ্রেগরিয়ান ক্যালেন্ডারও নয়। এছাড়াও স্ট্যাকওভারফ্লো.com
প্রশ্নগুলি /

একটি লাইন সংস্করণ - ডেটাটাইপফ্যাক্টরি.নুআইন্সট্যান্স ()। নতুন এক্সএমএল গ্রেগরিয়ানক্যালেন্ডার (নতুন গ্রেগরিয়ানক্যালেন্ডার () {{সেটটাইম (আপনার তারিখ);}})
অ্যালেক্স ভাইদা

205

তাদের এখানে যা বিপরীত রূপান্তরটির জন্য এখানে থেকে শেষ হতে পারে from XMLGregorianCalendar করতে Date):

XMLGregorianCalendar xcal = <assume this is initialized>;
java.util.Date dt = xcal.toGregorianCalendar().getTime();

31

গ্রেগরিয়ানক্যালেন্ডার থেকে এক্সএমএল গ্রেগরিয়ানক্যালেন্ডারে রূপান্তর করার জন্য একটি পদ্ধতি এখানে রয়েছে; আমি আপনার জন্য অনুশীলন হিসাবে 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);
   }

}

সম্পাদনা: স্লুও :-)


6
এই সমাধানটি গ্রেগরিয়ানক্যালেন্ডারকে এক্সএমএল গ্রেগরিয়ানক্যালেন্ডারে রূপান্তর করার জন্য এবং প্রশ্নের মধ্যে যা ইঙ্গিত করা হয়েছে তা নয়
ftrujillo


12

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

সেখানে কয়েকটি গোথকা নোট করুন, যেমন মাসে একটি যুক্ত করা (যেহেতু জাভা মাস থেকে 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);

10

আমি আশা করি এখানে আমার এনকোডিংটি ঠিক আছে; ডি এটি দ্রুত করার জন্য কেবল কনগ্রাক্টর কলের পরিবর্তে গ্রেগরিয়ানক্যালেন্ডারের কলস ব্যবহার করুন:

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);
   }

}

14
.GetInstance () ব্যবহারের জন্য -1। GregorianCalendar.getInstance()এর সমতূল্য Calendar.getInstance()Calendar.getInstance(), এটি দ্রুত করতে পারেন না, কারণ এটি একই ব্যবহার new GregorianCalendar(), কিন্তু আগেই ডিফল্ট লোকেল পরীক্ষা এবং পরিবর্তে জাপানি বা Buddish ক্যালেন্ডার তৈরি করতে পারে নি, তাই ততক্ষণ ভাগ্যবান ব্যবহারকারীদের জন্য এটা হবে ClassCastException!
কান

6

ধরে 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হয় তবে সম্ভবত খুব ভাল।


0

এই কোডটি দেখুন: -

/* 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);

আপনি এখানে সম্পূর্ণ উদাহরণ দেখতে পারেন


আমি মনে করি না যে এই উত্তরটি নতুন কিছু সরবরাহ করে না .. সম্ভবত আপনি প্রায় একই পোস্টের পরিবর্তে পূর্ববর্তী উত্তরটি সম্পাদনা করতে পারেন।
শীতকাল

1
এক্সএমএল গ্রেগরিয়ানক্যালেন্ডারের জন্য ডেট ফর্ম্যাট কীভাবে করবেন?
পানাদোল চং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.