আইএসও 8601- অনুসারী স্ট্রিংটিকে java.util.Date এ রূপান্তর করা হচ্ছে


667

আমি একটি আইএসও 8601 ফর্ম্যাট স্ট্রিংকে এ তে রূপান্তর করার চেষ্টা করছি java.util.Date

yyyy-MM-dd'T'HH:mm:ssZলোকাল (নমুনার তুলনায়) ব্যবহার করা থাকলে আমি প্যাটার্নটি আইএসও 8601- অনুসারী হতে পেলাম।

তবে, ব্যবহার করে java.text.SimpleDateFormat, আমি সঠিকভাবে ফর্ম্যাট স্ট্রিং রূপান্তর করতে পারি না 2010-01-01T12:00:00+01:002010-01-01T12:00:00+0100কোলন ছাড়াই আমাকে প্রথমে রূপান্তর করতে হবে ।

সুতরাং, বর্তমান সমাধান হয়

SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.GERMANY);
String date = "2010-01-01T12:00:00+01:00".replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
System.out.println(ISO8601DATEFORMAT.parse(date));

যা স্পষ্টতই এটি দুর্দান্ত নয়। আমি কি কিছু মিস করছি বা এর থেকে আরও ভাল সমাধান আছে?


উত্তর

জুয়ানজের মন্তব্যে ধন্যবাদ, আমি জোদা-টাইম যাদুটি পেয়েছি , এটি এখানেও বর্ণিত হয়েছে

সুতরাং, সমাধান হয়

DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2010-01-01T12:00:00+01:00";
System.out.println(parser2.parseDateTime(jtdate));

বা আরও সহজভাবে, কনস্ট্রাক্টরের মাধ্যমে ডিফল্ট পার্সার ব্যবহার করুন:

DateTime dt = new DateTime( "2010-01-01T12:00:00+01:00" ) ;

আমার কাছে, এটি দুর্দান্ত।


243
প্রচুর "জোডটাইম ব্যবহার করুন" উত্তর পেতে প্রস্তুত থাকুন ...
জুয়ানজে

3
@ আইস09: যদি ডেটটাইমফর্ম্যাটটির জন্য এপিআই ডকুমেন্টেশন সঠিক হয় (জোডা ডকুমেন্টেশন বিভ্রান্তিমূলক, ভুল বা অসম্পূর্ণ হতে পারে) তবে আপনি নিজের "উত্তর" ব্যবহার করেছেন এমন প্যাটার্নটি আইএসও 8601 এর সাথে সামঞ্জস্যপূর্ণ নয়।
jarnbjo

21
কখন এটি যুক্ত করা হয়েছিল তা সম্পর্কে আমি নিশ্চিত নই, তবে 'এক্স' প্রদর্শিত হবে সিম্পলডেট ফরমেটের মধ্যে এই সমস্যাটি সমাধান করার জন্য। "Yyyy-MM-dd'T'HH: মিমি: এসএসএক্স" প্যাটার্নটি প্রশ্নের সফলভাবে উদাহরণটিকে পার্স করেছে।
mlohbihler

12
জাভা 7. থেকে 'এক্স' উপলভ্য
লার্স গ্রামেল

3
জাভা 8 এটি সহজ করে তোলে! নীচের উত্তরে
ফ্যাবিয়ান কেলার

উত্তর:


477

দুর্ভাগ্যক্রমে, সিম্পলডিটফর্ম্যাট (জাভা 6 এবং তার আগের) এর জন্য উপলব্ধ সময় অঞ্চল ফর্ম্যাটগুলি আইএসও 8601 অনুসারে নয় । সিম্পলডিটফর্ম্যাটটি "জিএমটি + 01: 00" বা "+0100" এর মতো টাইম জোনের স্ট্রিংগুলি বোঝে, আরএফসি # 822 অনুসারে পরবর্তীটি ।

এমনকি জাভা 7 আইএসও 8601 অনুসারে টাইম জোন বর্ণনাকারীদের জন্য সমর্থন যুক্ত করলেও সিম্পলডিটফর্ম্যাটটি এখনও একটি সম্পূর্ণ তারিখের স্ট্রিং সঠিকভাবে পার্স করতে সক্ষম হয় না, কারণ এটিতে alচ্ছিক অংশগুলির কোনও সমর্থন নেই।

Regexp ব্যবহার করে আপনার ইনপুট স্ট্রিংটির পুনরায় ফর্ম্যাট করা অবশ্যই একটি সম্ভাবনা, তবে প্রতিস্থাপনের নিয়মগুলি আপনার প্রশ্নের মতো সহজ নয়:

  • কিছু সময় অঞ্চলগুলি ইউটিসির পুরো ঘন্টা নয় , সুতরাং স্ট্রিংটি অগত্যা ": 00" দিয়ে শেষ হবে না।
  • আইএসও ৮60০১ কেবলমাত্র সময় অঞ্চলে অন্তর্ভুক্ত হওয়া কত ঘন্টার সংখ্যার অনুমতি দেয় তাই "+01" "+01: 00" এর সমান
  • আইএসও 8601 "জেড" এর ব্যবহারটিকে "+00: 00" এর পরিবর্তে ইউটিসি নির্দেশ করতে দেয়।

সহজ সমাধানটি সম্ভবত জ্যাকএক্সবিতে ডেটা টাইপ রূপান্তরকারী ব্যবহার করা হয়, যেহেতু জ্যাকএক্সবি অবশ্যই এক্সএমএল স্কিমা স্পেসিফিকেশন অনুযায়ী ISO8601 তারিখের স্ট্রিং পার্স করতে সক্ষম হবে। javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z")আপনাকে একটি Calendarঅবজেক্ট দেবে এবং আপনার যদি কোনও Dateঅবজেক্টের প্রয়োজন হয় তবে আপনি কেবল এটিতে getTime () ব্যবহার করতে পারেন ।

আপনি সম্ভবত জোদা-সময়ও ব্যবহার করতে পারেন , তবে কেন আপনাকে কেন এটি বিরক্ত করা উচিত তা আমি জানি না।


18
জ্যাকএক্সবি-সমাধানটি আসলেই একটি সৃজনশীল পদ্ধতির! এটি পাশাপাশি কাজ করে, আমি এটি আমার নমুনা দিয়ে পরীক্ষা করেছি। তবে যার পক্ষে সমস্যার মুখোমুখি হয় এবং জোদাটাইম ব্যবহার করার অনুমতি দেওয়া হয়, আমি এটি ব্যবহার করার পরামর্শ দেব, কারণ এটি আরও প্রাকৃতিক বোধ করে। তবে আপনার সমাধানের জন্য অতিরিক্ত লাইব্রেরিগুলির প্রয়োজন নেই (কমপক্ষে জাভা 6 সহ)।
આઇસ09

36
বিপরীতটি এখানে: ক্যালেন্ডার সি = গ্রেগরিয়ানক্যালেন্ডার.গেট ইনস্ট্যানস (); সি.সেটটাইম (অ্যাডেট); রিটার্ন জাভ্যাক্স.এক্সএমএল.বাইন্ড।ড্যাট্যাটাইপ কনভার্টার.প্রিন্টডেটটাইম (সি);
আলেকজান্ডার ল্যাংবার্গ

4
আসলে এটি এত সহজ বি / সি নয়, আপনাকে জ্যাক্সবি ডেটাটাইপ কনভার্টারটি শুরু করতে হবে। আমি ডেটাটাইপফ্যাক্টরিটি নিজেকে শেষ করেছিলাম যেমন ডেটাটাইপকনভার্টারআইএমপি অভ্যন্তরীণভাবে করেছে did কি মাথা ব্যথা।
gtrak

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

4
@ জার্নবজো আপনি প্রথম এবং একমাত্র ব্যক্তি যিনি আমার মুখোমুখি হয়েছিলেন যোডা সময়ের তুলনায় 1.8 পূর্বের জাভা তারিখের ক্লাসগুলি পছন্দ করেন। আমি জোদা-সময়টিকে ব্যবহার করার জন্য একটি আক্ষরিক আনন্দ পাই, বিশেষত যখন স্ট্যান্ডার্ড এপিআইয়ের সাথে তুলনা করা একটি ঘৃণা।
নিমচিম্পস্কি

245

জাভা 7 ডকুমেন্টেশন দ্বারা আশীর্বাদ করা উপায় :

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String string1 = "2001-07-04T12:08:56.235-0700";
Date result1 = df1.parse(string1);

DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
String string2 = "2001-07-04T12:08:56.235-07:00";
Date result2 = df2.parse(string2);

আপনি অধ্যায় আরো উদাহরণ জানতে পারেন উদাহরণSimpleDateFormat javadoc

ইউপিডি 02/13/2020: জাভা 8 এ এটি করার সম্পূর্ণ নতুন উপায় রয়েছে is


7
আপনার উত্তর আমাকে মোঙ্গোডিবির আইএসওডেটকে স্থানীয় তারিখে রূপান্তর করতে সহায়তা করেছে। শুভেচ্ছা।
নীল আকাশ

9
@ b.long জাভা এই জাতীয় আইএসও 8601 অনুবর্তী ফর্ম্যাটগুলির জন্য ধ্রুবক ছাড়াও বেশি যুক্ত করেছে। জাভা তারিখ-সময়ের কাজের জন্য একটি সম্পূর্ণ নতুন কাঠামো পেয়েছে যাতে এই ধরণের ফর্ম্যাটগুলির জন্য অন্তর্নির্মিত ডিফল্ট সমর্থন অন্তর্ভুক্ত। জাভা -টাইম দ্বারা অনুপ্রাণিত জাভা -টাইম দ্বারা অনুপ্রাণিত জাভা.ইটি.এল.ডেট, .ক্যালেন্ডার এবং সিম্পলডেটফর্ম্যাট ক্লাসগুলি সরবরাহ করে জাভা 8-তে নতুন java.timeকাঠামো দেখুন ।
তুলসী বাউরিক

2
এর অর্থ এই নয় যে আপনার আগে তারিখের ফর্ম্যাটটি জানা উচিত? যদি আপনাকে গ্রহণ করতে হয় string1এবং string2তবে আপনি কী পাবেন তা জানেন না।
টিমম্মে

16
'জেড' এর উদ্ধৃতিতে থাকা দরকার
kervin

7
@ কেভিনিন যদি জেডটি উদ্ধৃতিগুলিতে থাকে তবে ফর্ম্যাটরটি বিশেষত জেড অক্ষরটি অনুসন্ধান করবে না, এটি অফসেটের সমস্ত স্ট্রিং উপস্থাপন করতে পারে না? দেখে মনে হচ্ছে জেডের উদ্ধৃতিটি কেবল কাকতালীয়ভাবে কাজ করবে, যদি আপনার তারিখের স্ট্রিংগুলি ইউটিসিতে থাকে।
spaaarky21

201

ঠিক আছে, এই প্রশ্নের উত্তর ইতিমধ্যে দেওয়া হয়েছে, তবে আমি আমার উত্তর যেভাবেই ফেলে দেব। এটি কারও সাহায্য করতে পারে।

আমি অ্যান্ড্রয়েড (এপিআই 7) এর সমাধান খুঁজছি ।

  • জোদা প্রশ্নের বাইরে ছিল - এটি বিশাল এবং ধীর সূচনাতে ভুগছে। এটি নির্দিষ্ট উদ্দেশ্যে একটি বড় ওভারকিল বলে মনে হয়েছিল।
  • জড়িত উত্তরগুলি javax.xmlঅ্যান্ড্রয়েড এপিআই 7 এ কাজ করবে না।

এই সাধারণ শ্রেণিটি বাস্তবায়নের জন্য শেষ হয়েছিল। এটি আইএসও 8601 স্ট্রিংগুলির মধ্যে সর্বাধিক সাধারণ রূপটি অন্তর্ভুক্ত করে তবে কিছু ক্ষেত্রে এটি যথেষ্ট হওয়া উচিত (যখন আপনি নিশ্চিত হন যে ইনপুটটি এই ফর্ম্যাটে থাকবে)।

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Helper class for handling a most common subset of ISO 8601 strings
 * (in the following format: "2008-03-01T13:00:00+01:00"). It supports
 * parsing the "Z" timezone, but many other less-used features are
 * missing.
 */
public final class ISO8601 {
    /** Transform Calendar to ISO 8601 string. */
    public static String fromCalendar(final Calendar calendar) {
        Date date = calendar.getTime();
        String formatted = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
            .format(date);
        return formatted.substring(0, 22) + ":" + formatted.substring(22);
    }

    /** Get current date and time formatted as ISO 8601 string. */
    public static String now() {
        return fromCalendar(GregorianCalendar.getInstance());
    }

    /** Transform ISO 8601 string to Calendar. */
    public static Calendar toCalendar(final String iso8601string)
            throws ParseException {
        Calendar calendar = GregorianCalendar.getInstance();
        String s = iso8601string.replace("Z", "+00:00");
        try {
            s = s.substring(0, 22) + s.substring(23);  // to get rid of the ":"
        } catch (IndexOutOfBoundsException e) {
            throw new ParseException("Invalid length", 0);
        }
        Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
        calendar.setTime(date);
        return calendar;
    }
}

পারফরম্যান্স নোট: অ্যান্ড্রয়েড ২.১ এ কোনও বাগ এড়াতে আমি প্রতিবার নতুন সিম্পলডেট ফরমেট ইনস্ট্যান্ট করি । আপনি যদি আমার মতো বিস্মিত হন তবে এই ধাঁধাটি দেখুন । অন্যান্য জাভা ইঞ্জিনগুলির জন্য, আপনি ব্যক্তিগত স্ট্যাটিক ক্ষেত্রে উদাহরণটি ক্যাশে করতে পারেন (থ্রেডলোকাল ব্যবহার করে, থ্রেড নিরাপদ থাকতে)।


2
সম্ভবত এটি একটি নিজস্ব প্রশ্ন তৈরি করা উচিত ছিল, তার নিজের উত্তর দিয়ে?
থর্বার

5
আমি যখন উত্তরটি খুঁজছিলাম তখন এটিই আমি প্রথম পৃষ্ঠায় ফেলেছিলাম, সুতরাং এটি উপযুক্ত বলে মনে হয়েছিল। বেশিরভাগ জাভা বিকাশকারীদের জন্য অ্যান্ড্রয়েড হ'ল জাভা নয়। যাইহোক, বেশিরভাগ ক্ষেত্রে, একজন অন্যের মতো একইভাবে কাজ করে, তাই অনেকগুলি অ্যান্ড্রয়েড বিকাশকারী এটি খুঁজতে গিয়ে "জাভা" অনুসন্ধান করবে।
wrygiel

1
দ্রষ্টব্য যে এটি মিলিসেকেন্ড রেজোলিউশনের জন্য অ্যাকাউন্ট করে না। এটি যুক্ত করা সহজ।
স্কাই কেলসি

6
ভগ্নাংশের সেকেন্ডের জন্য আমাকে .SSS যুক্ত করতে হয়েছিল তবে দুর্দান্ত থেক্সে কাজ করে। আপনি কেন করেন s = s.substring(0, 22) + s.substring(23);- আমি এতে বিন্দুটি দেখতে পাচ্ছি না
ডরি

1
ইনপুট = ইনপুট.রেপসএল ("[জেডজেড]", "+0000"); খুব কাজ করবে এবং সাবস্ট্রিং অপারেশন এড়ানো যায়।
জাভানেটর

115

java.time

Java.time এপিআই (জাভা 8 এবং পরে পাতাটা), এই একটি সামান্য সহজ করে তোলে।

যদি আপনি জানেন যে ইনপুটটি ইউটিসিতে রয়েছে , যেমন Z(জুলুর পক্ষে) শেষে, Instantশ্রেণিটি বিশ্লেষণ করতে পারে।

java.util.Date date = Date.from( Instant.parse( "2014-12-12T10:39:40Z" ));

আপনার ইনপুট হতে পারে তাহলে অন্য অফসেট-থেকে-ইউটিসি মান বদলে ইউটিসি দ্বারা নির্দেশিত Z(জুলু) প্রান্তে, ব্যবহার OffsetDateTimeবিশ্লেষণ করতে বর্গ।

OffsetDateTime odt = OffsetDateTime.parse( "2010-01-01T12:00:00+01:00" );

তারপরে একটি বের করুন Instantএবং java.util.Dateকল করে একটিতে রূপান্তর করুন from

Instant instant = odt.toInstant();  // Instant is always in UTC.
java.util.Date date = java.util.Date.from( instant );

8
এই উত্তরটি খুব পরিশ্রম করছে। একটি java.util.Date সংজ্ঞা অনুসারে কোনও সময় অঞ্চল নেই। সুতরাং সেই সময় অঞ্চল সম্পর্কিত কোডের দরকার নেই: LocalDateTimeএবং ZoneIdএবং atZone। এই সাধারণ ওয়ান-লাইনারটি করবে:java.util.Date date = Date.from( ZonedDateTime.parse( "2014-12-12T10:39:40Z" ).toInstant() );
তুলিল বাউরক

5
@ বাসিলবার্ক এটি অহেতুক জটিল: Date.from(Instant.parse("2014-12-12T10:39:40Z" ));যথেষ্ট।
Assylias

3
@assylias তুমি সঠিক কিন্তু যে শুধুমাত্র কাজ করবে যখন তারিখের স্ট্রিংকে ইউটিসি জোন, ISO8601 কোন সময় অঞ্চল পারবেন ...
আদম

2
@ অ্যাডাম আমার খারাপ - আমি বুঝতে পারি নি যে প্রশ্নটি আপনার উদাহরণের চেয়ে বেশি সাধারণ। পাশের মন্তব্য হিসাবে OffsetDateTimeISO8601 (যা টাইম জোনের তথ্য ধারণ করে না তবে কেবল একটি অফসেট) পার্স করার পক্ষে যথেষ্ট হবে।
assylias

1
@ এ্যাসিয়ালিয়াস Instantপার্সিং করতে দেওয়ার বিষয়ে আপনার মন্তব্যের জন্য ধন্যবাদ । যদিও এই নির্দিষ্ট প্রশ্নের পক্ষে পর্যাপ্ত নয়, এটি উল্লেখ করার মতো গুরুত্বপূর্ণ পার্থক্য। তাই আমি কোডের একটি দ্বিতীয় উদাহরণ যুক্ত করেছি। ওফ, ঠিক লক্ষ্য করা এটি মূলত আমার উত্তর নয়; আমি আশা করি অ্যাডাম অনুমোদন করেছেন।
তুলিল বাউরক

67

জ্যাকসন-databind গ্রন্থাগার এছাড়াও আছে ISO8601DateFormat বর্গ যে (প্রকৃত বাস্তবায়ন করে ISO8601Utils

ISO8601DateFormat df = new ISO8601DateFormat();
Date d = df.parse("2010-07-28T22:25:51Z");

এটা তোলে এই তারিখের বিশ্লেষণ করতে ব্যর্থ হলে: 2015-08-11T13:10:00। আমি পেতে String index out of range: 19। কোডটি দেখে মনে হচ্ছে এটির জন্য মিলিসেকেন্ডগুলি নির্দিষ্ট করা দরকার, এবং সময় অঞ্চল। এগুলি alচ্ছিক হওয়া উচিত।
টিমম্মে

2
ডকুমেন্টেশন উদ্ধৃত করার জন্য, পার্স ফরম্যাট: [yyyy-MM-dd|yyyyMMdd][T(hh:mm[:ss[.sss]]|hhmm[ss[.sss]])]?[Z|[+-]hh:mm]]। অন্য কথায়, মিলিসেকেন্ডগুলি alচ্ছিক তবে টাইমজোন বাধ্যতামূলক।
ডেভিড_পি

2
আহ হ্যাঁ আসলে আপনার ঠিক মনে হচ্ছে। তবুও, আমি নিশ্চিত যে ISO8601 আপনাকে টাইমজোনটি বাদ দিতে দেয় তাই এটি এখনও ভুল। জোডাটাইম যদিও কাজ করে:new DateTime("2015-08-11T13:10:00").toDate()
টিম্ম্মে

3
সেই শ্রেণিটি এখন অবহিত করা হয়েছে, নতুনটি স্টাডিটেট ফরম্যাট। অন্যথায় এটি একই কাজ করে।
জনয়ে

51

TL; ড

OffsetDateTime.parse ( "2010-01-01T12:00:00+01:00" )

জাভা.টাইম ব্যবহার

জাভা 8- র নতুন জাভা.টাইম প্যাকেজটি জোদা-টাইম দ্বারা অনুপ্রাণিত হয়েছিল।

OffsetDateTimeবর্গ একটি সঙ্গে টাইমলাইনে একটি মুহূর্ত প্রতিনিধিত্ব করে অফসেট-থেকে-ইউটিসি কিন্তু কোন সময় জোন।

OffsetDateTime odt = OffsetDateTime.parse ( "2010-01-01T12:00:00+01:00" );

কলিং toStringস্ট্যান্ডার্ড আইএসও 8601 ফর্ম্যাটে একটি স্ট্রিং উত্পন্ন করে:

2010-01-01T12: 00 +01: 00

ইউটিসি লেন্সের মাধ্যমে একই মান দেখার জন্য, একটি নিষ্কর্ষ Instantবা সমন্বয় অফসেট +01:00করতে 00:00

Instant instant = odt.toInstant();  

... অথবা ...

OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC );

চাইলে একটি সময় অঞ্চলে সামঞ্জস্য করুন। একটি সময় জোন একটি ইতিহাস অফসেট-থেকে-ইউটিসি যেমন দিবালোক সংরক্ষণকারী সময় (ডিএসটি) যেমন ব্যতিক্রমসমূহ পরিচালনা করার জন্য নিয়ম একটি সেট সঙ্গে, একটি অঞ্চলের জন্য মান। সুতরাং যখনই সম্ভব কেবলমাত্র অফসেটের চেয়ে সময় অঞ্চল প্রয়োগ করুন।

ZonedDateTime zonedDateTimeMontréal = odt.atZoneSameInstant( ZoneId.of( "America/Montreal" ) );

জাভা.টাইম সম্পর্কে

Java.time ফ্রেমওয়ার্ক জাভা 8 এবং পরে পাতাটা করা হয়। এই ক্লাসগুলি , & , এর মতো সমস্যাযুক্ত পুরানো উত্তরাধিকারের তারিখ-সময়ের ক্লাসগুলিকে সহায়তা করে ।java.util.DateCalendarSimpleDateFormat

Joda-টাইম প্রকল্প, এখন রক্ষণাবেক্ষণ মোড , মাইগ্রেশনে উপদেশ java.time ক্লাস।

আরও জানতে, ওরাকল টিউটোরিয়ালটি দেখুন । এবং অনেক উদাহরণ এবং ব্যাখ্যার জন্য স্ট্যাক ওভারফ্লো অনুসন্ধান করুন। স্পেসিফিকেশনটি জেএসআর 310

আপনি আপনার ডাটাবেসের সাথে জাভা.টাইম অবজেক্টগুলি সরাসরি বিনিময় করতে পারেন । জেডিবিসি ৪.২ বা তারপরের সাথে অনুগত একটি জেডিবিসি ড্রাইভার ব্যবহার করুন । স্ট্রিংগুলির দরকার নেই, ক্লাসের প্রয়োজন নেই ।java.sql.*

জাভা.টাইম ক্লাস কোথায় পাবেন?

ThreeTen-অতিরিক্ত প্রকল্প অতিরিক্ত শ্রেণীর সাথে java.time প্রসারিত করে। এই প্রকল্পটি জাভা.টাইমে সম্ভাব্য ভবিষ্যতের সংযোজনগুলির একটি প্রমাণযোগ্য ক্ষেত্র। আপনি এখানে কিছু দরকারী শ্রেণীর যেমন খুঁজে পেতে পারেন Interval, YearWeek, YearQuarter, এবং আরো



27

জাভা সংস্করণ 7 এর জন্য

আপনি ওরাকল ডকুমেন্টেশন অনুসরণ করতে পারেন: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

এক্স - আইএসও 8601 টাইম জোনের জন্য ব্যবহৃত হয়

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

System.out.println(nowAsISO);

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
//nowAsISO = "2013-05-31T00:00:00Z";
Date finalResult = df1.parse(nowAsISO);

System.out.println(finalResult);

এর অর্থ সময় অঞ্চল প্রয়োজন । আইএসও 8601 অনুসারে এটি alচ্ছিক। তাই এই শুধুমাত্র আইএসও 8601. একটি নির্দিষ্ট উপসেট parses হিসাবে সেকেন্ড, ইত্যাদি হয়
Timmmm

1
জাভা 1.8 দিয়ে দুর্দান্ত কাজ করে
থিয়াগো পেরেইরা

20

ডেটাটাইপ কনভার্টর সলিউশন সমস্ত ভিএম-তে কাজ করে না। নিম্নলিখিতটি আমার পক্ষে কাজ করে:

javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar("2011-01-01Z").toGregorianCalendar().getTime()

আমি খুঁজে পেয়েছি যে জোদা বাক্সটির বাইরে কাজ করে না (বিশেষত উদাহরণস্বরূপ আমি তারিখে টাইমজোন দিয়ে উপরে দিয়েছি, যা বৈধ হওয়া উচিত)


15

আমি মনে করি আমাদের ব্যবহার করা উচিত

DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

তারিখ জন্য 2010-01-01T12:00:00Z


5
এটি কেন অন্যদের চেয়ে উত্তম উত্তর, 76 76 টি উর্ধ্বত্তের সাথে স্বীকৃত উত্তর অন্তর্ভুক্ত করে?
এরিক রবার্টসন

3
@ এরিকরবার্টসন: এটি সহজ, বাক্সের বাইরে, নমনীয়, কোনও রূপান্তর নেই এবং বেশিরভাগ লোক সময় অঞ্চল সম্পর্কে চিন্তা করে না।
TWiStErRob

7
আপনি সময় অঞ্চল সম্পর্কে যত্ন না যদি সময় সঙ্গে কাজ খুব পয়েন্ট নয়!
ডুরি

16
এই সময়টাকে পুরোপুরি ইগনোরস করে। এটি হচ্ছিল না হওয়া পর্যন্ত এটি ব্যবহার করা ছিল, তাই আমি জোডটাইমে স্যুইচ করেছি।
জোশুয়া পিন্টার

3
সময় অঞ্চলটিকে দূরে সরিয়ে দেওয়ার ফলে কিছুটা সময় ত্রুটি ঘটবে।
বার্ট ভ্যান কুইক

11

জাভা 8 থেকে শুরু করে, এটি করার জন্য একটি সম্পূর্ণ নতুন অফিশিয়ালি সমর্থিত উপায় রয়েছে:

    String s = "2020-02-13T18:51:09.840Z";
    TemporalAccessor ta = DateTimeFormatter.ISO_INSTANT.parse(s);
    Instant i = Instant.from(ta);
    Date d = Date.from(i);

2
স্ট্রিংটি যদি Zঅফসেট হিসাবে অনুসরণ করে তাত্ক্ষণিক বিন্যাসে থাকে তবে আমাদের এটিকে স্পষ্টভাবে নির্দিষ্ট করার দরকার নেই। শুধু Instant i = Instant.parse(s);। প্রশ্নের স্ট্রিংটিতে ছিল +01:00, কোন ক্ষেত্রে DateTimeFormatter.ISO_INSTANTকাজ করে না (কমপক্ষে আমার জাভা ১১-তে নয়)।
ওলে ভিভি

2
@ OleV.V। আপনি ISO_OFFSET_DATE_TIMEঅফসেটের সাথে তারিখগুলি ফর্ম্যাট করতে ব্যবহার করতে পারেন , যেমন +01:00( ডকস.ওরকল /
জাভাসে /

1
এটি সত্য, @ লুকাসবাস্কেরোটো। যদিও সেই ফর্ম্যাটরটি স্পষ্টভাবে উল্লেখ করা হয়নি, আদম এবং বাসিল বাউরকের উত্তর ইতিমধ্যে একই রকম করেছে।
ওলে ভিভি

10

আইএসও 8601 টাইমস্ট্যাম্পগুলি পার্স করার আরও একটি সহজ উপায় হ'ল org.apache.commons.lang.time.DateUtils:

import static org.junit.Assert.assertEquals;

import java.text.ParseException;
import java.util.Date;
import org.apache.commons.lang.time.DateUtils;
import org.junit.Test;

public class ISO8601TimestampFormatTest {
  @Test
  public void parse() throws ParseException {
    Date date = DateUtils.parseDate("2010-01-01T12:00:00+01:00", new String[]{ "yyyy-MM-dd'T'HH:mm:ssZZ" });
    assertEquals("Fri Jan 01 12:00:00 CET 2010", date.toString());
  }
}

6

java.time

নোট করুন যে জাভা 8-এ, আপনি java.ime.ZoneDateTime শ্রেণি এবং এটির স্থির parse(CharSequence text)পদ্ধতিটি ব্যবহার করতে পারেন ।


প্রশ্নের ইনপুট স্ট্রিংগুলিতে কেবল একটি অফসেট-ইউটিসি থেকে থাকে, পুরো সময়ের অঞ্চল নয়। সুতরাং Instantএবং ZonedDateTimeএখানে উপযুক্ত, না ZonedDateTime
তুলসী বাউরক

6

জাভা 7+ এর জন্য কাজটি সরলডেটফর্ম্যাটটি ব্যবহার করছে:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US);

এই কোডটি আইএসও 8601 ফর্ম্যাটটিকে পার্স করতে পারে:

  • 2017-05-17T06:01:43.785Z
  • 2017-05-13T02:58:21.391+01:00

তবে জাভা on-তে, চরিত্রটি SimpleDateFormatবোঝে না Xএবং ছুঁড়ে ফেলবে
IllegalArgumentException: Unknown pattern character 'X'
আমাদের জাভা in এর পাঠ্যযোগ্য ফর্ম্যাটে ISO8601 তারিখটি স্বাভাবিক করতে হবে SimpleDateFormat

public static Date iso8601Format(String formattedDate) throws ParseException {
    try {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US);
        return df.parse(formattedDate);
    } catch (IllegalArgumentException ex) {
        // error happen in Java 6: Unknown pattern character 'X'
        if (formattedDate.endsWith("Z")) formattedDate = formattedDate.replace("Z", "+0000");
        else formattedDate = formattedDate.replaceAll("([+-]\\d\\d):(\\d\\d)\\s*$", "$1$2");
        DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
        return df1.parse(formattedDate);
    }
}

জাভা 6 এ ত্রুটি দেখা দিলে [ Zসাথে +0000] বা [ +01:00সাথে +0100] প্রতিস্থাপন করার জন্য উপরের পদ্ধতি (আপনি জাভা সংস্করণটি সনাক্ত করতে পারেন এবং যদি বিবৃতি দিয়ে চেষ্টা / ক্যাপ প্রতিস্থাপন করতে পারেন)।


না, সমস্যাযুক্ত পুরানো তারিখের সময়ের ক্লাসগুলি যেমন Dateএবং SimpleDateFormatখারাপভাবে নকশাকৃত, বিভ্রান্তিকর এবং ত্রুটিযুক্ত। এগুলি এখন লিগ্যাসি, জাভা ৮ এবং তার পরে জাভা.টাইম ক্লাসগুলির দ্বারা পরিপূর্ণ। জাভা 6 এবং জাভা 7 এর জন্য, জাভা.টাইম কার্যকারিতার বেশিরভাগ অংশ থ্রিটেন-ব্যাকপোর্ট প্রকল্পে ব্যাক-পোর্ট করা হয়েছে । সেই অ্যাপ্লিকেশনটিতে সেই লিগ্যাসিরি যুক্ত করা আরও ভাল leg Java.time এক লাইন সমাধান:OffsetDateTime.parse( "2010-01-01T12:00:00+01:00" )
বেসিল Bourque

5

আমি একই সমস্যার মুখোমুখি হয়েছি এবং নিম্নলিখিত কোড দ্বারা এটি সমাধান করেছি।

 public static Calendar getCalendarFromISO(String datestring) {
    Calendar calendar = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault()) ;
    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
    try {
        Date date = dateformat.parse(datestring);
        date.setHours(date.getHours() - 1);
        calendar.setTime(date);

        String test = dateformat.format(calendar.getTime());
        Log.e("TEST_TIME", test);

    } catch (ParseException e) {
        e.printStackTrace();
    }

    return calendar;
}

আগে আমি ব্যবহার ছিল SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault());

তবে পরে আমি খুঁজে পেলাম ব্যতিক্রমের মূল কারণটি হ'ল yyyy-MM-dd'T'HH:mm:ss.SSSZ,

সুতরাং আমি ব্যবহার

SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());

এটা আমার জন্য ভাল কাজ করেছিল .


জোদা-সময়, এক্সএমএল এপিআই বা অন্য কিছু ব্যবহার না করেই আমার যা প্রয়োজন। ঠিক সঠিক প্যাটার্ন।
ফিলিপ জিওসিফি

4

এছাড়াও আপনি নিম্নলিখিত ক্লাসটি ব্যবহার করতে পারেন -

org.springframework.extensions.surf.util.ISO8601DateFormat


Date date = ISO8601DateFormat.parse("date in iso8601");

জাভা ডক্সের সাথে লিঙ্ক করুন - প্যাকেজের জন্য শ্রেণিবদ্ধতা


থামানো হয়েছে: ব্যবহার করুন com.fasterxml.jackson.databind.util.StdDateFormat পরিবর্তে
সংস্করণটি

4

জাভাতে একটি তারিখ-সময়কে বিশ্লেষণের জন্য এক ডজন বিভিন্ন উপায় রয়েছে, যেমন এখানে দুর্দান্ত উত্তরগুলি দেখায়। তবে কিছুটা আশ্চর্যজনকভাবে, জাভার কোনও টাইম ক্লাসই আইএসও 8601 পুরোপুরি প্রয়োগ করে না!

জাভা 8 দিয়ে, আমি সুপারিশ করব:

ZonedDateTime zp = ZonedDateTime.parse(string);
Date date = Date.from(zp.toInstant());

এটি ইউটিসি এবং "2017-09-13T10: 36: 40Z" বা "2017-09-13T10: 36: 40 + 01: 00" এর মতো অফসেট সহ উভয়ই উদাহরণগুলি পরিচালনা করবে। এটি বেশিরভাগ ব্যবহারের ক্ষেত্রে করবে।

কিন্তু এটা মত উদাহরণ হ্যান্ডেল করবে না "2017-09-13T10: 36: 40 +01", যা হল একটি বৈধ ISO 8601 তারিখ-সময়।
এটি কেবল তারিখটি পরিচালনা করবে না, যেমন "2017-09-13"।

যদি আপনার সেগুলি পরিচালনা করতে হয় তবে আমি সিনট্যাক্সটি শোঁকাতে প্রথমে একটি রেজিেক্স ব্যবহার করার পরামর্শ দেব।

প্রচুর কর্নারের কেস সহ এখানে আইএসও 8601 উদাহরণের একটি দুর্দান্ত তালিকা রয়েছে: https://www.myintervals.com/blog/2009/05/20/iso-8601-date-ificationsation-that-doesnt-suck/ আমি কোনও জাভা ক্লাস সম্পর্কে অবগত নয় যা তাদের সকলের সাথে মোকাবেলা করতে পারে।


OffsetDateTimeএকটি অফসেটের সাথে আরও ভাল করে তারিখ-সময়ের সাথে মিলবে এবং ধারণার সাথে মিলবে।
ওলে ভিভি

আরে @ ওলেভ.ভি। পরামর্শের জন্য ধন্যবাদ. দুঃখজনকভাবে নয়: অফসেটডেটটাইম.পারস () বেশ কয়েকটি বৈধ আইএসও 8601 স্ট্রিংয়ের জন্য একটি ব্যতিক্রম ছুঁড়ে দেবে, যেমন "2017-09-13T10: 36: 40 + 01" বা "2017-09-13"
ড্যানিয়েল উইন্টারস্টেইন

আমি কেবল বলতে OffsetDateTimeচাইছিলাম যে আপনি যে উদাহরণগুলি পরিচালনা করেন তা পরিচালনা করে ZonedDateTime। আমি বিশ্বাস করি যে এটি উদাহরণগুলির কোনওটি পরিচালনা ZonedDateTimeকরে না। সেই অর্থে এটি কোনও উন্নতি নয় (তবে এর চেয়ে খারাপও নয়)। দুঃখিত, আমি পুরোপুরি পরিষ্কার ছিল না।
ওলে ভিভি

1
বিষয়গুলির স্থিতি দিয়ে 2020-এ এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
স্ল্যাশ কোডার

3

টিকে থাকার তারিখগুলির জন্য অ্যাপাচি জ্যাক্রাবিট আইএসও 8601 ফর্ম্যাটটি ব্যবহার করে এবং তাদের পার্স করার জন্য একটি সহায়ক শ্রেণি রয়েছে:

org.apache.jackrabbit.util.ISO8601

জ্যাক্রাবিট-জিসিআর-কমন্স নিয়ে আসে ।


জ্যাক্রাবিটের সাবসেটটি কাজ করতে পারে, তবে এটি একটি পূর্ণ-উদ্দেশ্যপূর্ণ বিল্ট্রয়েড ব্যবহার করা আরও বোধগম্য। জাভাতে এর অর্থ জোদা-সময় বা জাভা.টাইম either
তুলসী বাউর্ক

3

অন্যরা যেমন উল্লেখ করেছেন যে এসডিকে অন্তর্ভুক্ত ক্লাসগুলি ব্যবহার করে অ্যান্ড্রয়েডের ISO 8601 তারিখগুলি পার্সিং / ফর্ম্যাট করতে সমর্থন করার ভাল উপায় নেই। আমি এই কোডটি একাধিকবার লিখেছি তাই শেষ পর্যন্ত আমি একটি গিস্ট তৈরি করেছি যার মধ্যে একটি ডেটুটিলস ক্লাস রয়েছে যা আইএসও 8601 এবং আরএফসি 1123 তারিখের ফর্ম্যাট এবং পার্সিং সমর্থন করে। গিস্টটিতে একটি পরীক্ষার কেসও অন্তর্ভুক্ত রয়েছে যা এটি সমর্থন করে showing

https://gist.github.com/mraccola/702330625fad8eebe7d3


2

জাভা 1.7 এর সিম্পলডেট ফরমেটে আইএসও 8601 ফর্ম্যাটের জন্য দুর্দান্ত প্যাটার্ন রয়েছে।

ক্লাস সিম্পলডেট ফরমেট

আমি যা করেছি তা এখানে:

Date d = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
         Locale.ENGLISH).format(System.currentTimeMillis());

2
Zফর্ম্যাট স্ট্রিংয়ে আইএসও 8601 টাইম জোন নয়, আপনি আইএসও 8601 টাইম জোন চাইলে আপনার ব্যবহার করা উচিত X( XXবা XXX)
ভোজটা


1

এটা এভাবে করো:

public static void main(String[] args) throws ParseException {

    String dateStr = "2016-10-19T14:15:36+08:00";
    Date date = javax.xml.bind.DatatypeConverter.parseDateTime(dateStr).getTime();

    System.out.println(date);

}

এখানে ফলাফল:

বুধবার অক্টোবর 19 15:15:36 সিএসটি 2016


1

মত স্ট্রিং ব্যবহার করুন LocalDate.parse(((String) data.get("d_iso8601")),DateTimeFormatter.ISO_DATE)


1

আমি অবাক হয়েছি যে একটি জাভা গ্রন্থাগারও https://en.wikedia.org/wiki/ISO_8601 অনুসারে সমস্ত আইএসও 8601 তারিখের ফর্ম্যাটকে সমর্থন করে না । জোডা ডেটটাইম তাদের বেশিরভাগকেই সমর্থন করছিল তবে সমস্তটি নয় এবং তাই এগুলি সমস্ত পরিচালনা করার জন্য আমি কাস্টম যুক্তি যুক্ত করেছি। এখানে আমার বাস্তবায়ন।

import java.text.ParseException;
import java.util.Date;

import org.apache.commons.lang3.time.DateUtils;
import org.joda.time.DateTime;

public class ISO8601DateUtils {
	
	/**
	 * It parses all the date time formats from https://en.wikipedia.org/wiki/ISO_8601 and returns Joda DateTime.
	 * Zoda DateTime does not support dates of format 20190531T160233Z, and hence added custom logic to handle this using SimpleDateFormat.
	 * @param dateTimeString ISO 8601 date time string
	 * @return
	 */
	public static DateTime parse(String dateTimeString) {
		try {
			return new DateTime( dateTimeString );
		} catch(Exception e) {
			try {
				Date dateTime = DateUtils.parseDate(dateTimeString, JODA_NOT_SUPPORTED_ISO_DATES);
				return new DateTime(dateTime.getTime());
			} catch (ParseException e1) {
				throw new RuntimeException(String.format("Date %s could not be parsed to ISO date", dateTimeString));
			}
		}
	}
  
  	private static String[] JODA_NOT_SUPPORTED_ISO_DATES = new String[] {
			// upto millis
			"yyyyMMdd'T'HHmmssSSS'Z'",
			"yyyyMMdd'T'HHmmssSSSZ",
			"yyyyMMdd'T'HHmmssSSSXXX",
			
			"yyyy-MM-dd'T'HHmmssSSS'Z'",
			"yyyy-MM-dd'T'HHmmssSSSZ",
			"yyyy-MM-dd'T'HHmmssSSSXXX",
			
			// upto seconds
			"yyyyMMdd'T'HHmmss'Z'",
			"yyyyMMdd'T'HHmmssZ",
			"yyyyMMdd'T'HHmmssXXX",
			
			"yyyy-MM-dd'T'HHmmss'Z'", 
			"yyyy-MM-dd'T'HHmmssZ",
			"yyyy-MM-dd'T'HHmmssXXX",
			
			// upto minutes
			"yyyyMMdd'T'HHmm'Z'",
			"yyyyMMdd'T'HHmmZ",
			"yyyyMMdd'T'HHmmXXX",

			"yyyy-MM-dd'T'HHmm'Z'",
			"yyyy-MM-dd'T'HHmmZ",
			"yyyy-MM-dd'T'HHmmXXX",
			
			//upto hours is already supported by Joda DateTime
	};
}


1

একটি ছোট পরীক্ষা যা দেখায় যে কীভাবে আইএসও 8601 এ একটি তারিখকে পার্স করতে হবে এবং লোকালডেটটাইমটি ডিএসটি হ্যান্ডেল করে না।

 @Test
    public void shouldHandleDaylightSavingTimes() throws ParseException {

        //ISO8601 UTC date format
        SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");

        // 1 hour of difference between 2 dates in UTC happening at the Daylight Saving Time
        Date d1 = utcFormat.parse("2019-10-27T00:30:00.000Z");
        Date d2 = utcFormat.parse("2019-10-27T01:30:00.000Z");

        //Date 2 is before date 2
        Assert.assertTrue(d1.getTime() < d2.getTime());
        // And there is 1 hour difference between the 2 dates
        Assert.assertEquals(1000*60*60, d2.getTime() - d1.getTime());

        //Print the dates in local time
        SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm z Z", Locale.forLanguageTag("fr_CH"));
        localFormat.setTimeZone(TimeZone.getTimeZone("Europe/Zurich"));

        //Both dates are at 02h30 local time (because of DST), but one is CEST +0200 and the other CET +0100 (clock goes backwards)
        Assert.assertEquals("2019-10-27 02:30 CEST +0200", localFormat.format(d1));
        Assert.assertEquals("2019-10-27 02:30 CET +0100", localFormat.format(d2));

        //Small test that shows that LocalDateTime does not handle DST (and should not be used for storing timeseries data)
        LocalDateTime ld1 = LocalDateTime.ofInstant(d1.toInstant(), ZoneId.of("Europe/Zurich"));
        LocalDateTime ld2 = LocalDateTime.ofInstant(d2.toInstant(), ZoneId.of("Europe/Zurich"));

        //Note that a localdatetime does not handle DST, therefore the 2 dates are the same
        Assert.assertEquals(ld1, ld2);

        //They both have the following local values
        Assert.assertEquals(2019, ld1.getYear());
        Assert.assertEquals(27, ld1.getDayOfMonth());
        Assert.assertEquals(10, ld1.getMonthValue());
        Assert.assertEquals(2, ld1.getHour());
        Assert.assertEquals(30, ld1.getMinute());
        Assert.assertEquals(0, ld1.getSecond());

    }

3
অবগতির জন্য, যেমন ভয়ঙ্কর বিরক্তিজনক তারিখ-সময় শ্রেণীর java.util.Date, java.util.Calendarএবং java.text.SimpleDateFormatএখন উত্তরাধিকার দ্বারা supplanted java.time জাভা 8 এবং পরে পাতাটা ক্লাস। ওরাকল দ্বারা টিউটোরিয়াল দেখুন ।
বেসিল Bourque

আপনি সঠিক যে LocalDateTimeগ্রীষ্মের সময় (ডিএসটি) হ্যান্ডেল করে না কারণ এটি কোনও সময় অঞ্চল হ্যান্ডেল করে না। তার জন্য আমাদের দরকার ZonedDateTime। প্রস্তাব দেওয়া Dateএবং SimpleDateFormatহ'ল - আইএমএইচও খারাপ।
ওলে ভিভি

1
প্রকৃতপক্ষে জোনেডেটটাইম কাজ করে। এবং java.time.Instant ডিএসটি হ্যান্ডেল করার জন্য একটি ভাল বিকল্প। আমি জানি যে java.util.Date
তারিখটি হ্রাস পেয়েছে

0

আমার একই রকম প্রয়োজন ছিল: আমার আগেই সঠিক ফর্ম্যাটটি না জেনে কোনও তারিখের ISO8601 অনুসারে পার্স করতে সক্ষম হওয়া দরকার এবং আমি একটি হালকা ওজনের সমাধান চাই যা অ্যান্ড্রয়েডেও কাজ করবে।

যখন আমি আমার প্রয়োজনগুলি গুগল করলাম তখন আমি এই প্রশ্নে হোঁচট খেয়েছি এবং লক্ষ্য করেছি যে এএফএআইইউ, কোনও উত্তর আমার প্রয়োজনের সাথে পুরোপুরি ফিট করে না। সুতরাং আমি jISO8601 বিকাশ করেছি এবং এটিকে সেন্ট্রালে ।

শুধু আপনার মধ্যে যোগ করুন pom.xml:

<dependency>
  <groupId>fr.turri</groupId>
  <artifactId>jISO8601</artifactId>
  <version>0.2</version>
</dependency>

এবং তারপরে আপনি যেতে ভাল:

import fr.turri.jiso8601.*;
...
Calendar cal = Iso8601Deserializer.toCalendar("1985-03-04");
Date date = Iso8601Deserializer.toDate("1985-03-04T12:34:56Z");

আশা করি এটি সাহায্য করে।


0

ঠিক এইর মতো একটি তারিখ ফর্ম্যাট করতে নীচে আমার জন্য জাভা 6 ভিত্তিক অ্যাপ্লিকেশনটিতে কাজ করেছে। থাইমেলিফ প্রকল্পে একটি DateFormatশ্রেণি JacksonThymeleafISO8601DateFormatরয়েছে যা নিখোঁজ কোলনটি সন্নিবেশ করায়:

https://github.com/thymeleaf/thymeleaf/blob/40d27f44df7b52eda47d1bc6f1b3012add6098b3/src/main/java/org/thymeleaf/standard/serializer/StandardJavaScriptSerializer.java

আমি এটি ECMAScript তারিখের ফর্ম্যাট তুলনামূলক জন্য ব্যবহার করেছি।


-1

বেস ফাংশন সৌজন্যে: @ রাইগিয়েল।

এই ফাংশনটি আইএসও 8601 ফর্ম্যাটটিকে জাভা ডেটে রূপান্তর করতে পারে যা অফসেট মানগুলি পরিচালনা করতে পারে। আইএসও 8601 এর সংজ্ঞা অনুযায়ী অফসেটটি বিভিন্ন ফর্ম্যাটে উল্লেখ করা যেতে পারে।

±[hh]:[mm]
±[hh][mm]
±[hh]

Eg:  "18:30Z", "22:30+04", "1130-0700", and "15:00-03:30" all mean the same time. - 06:30PM UTC

এই শ্রেণীর রূপান্তর করার জন্য স্থির পদ্ধতি রয়েছে

  • তারিখের (স্থানীয় সময় অঞ্চল) অবজেক্টে ISO8601 স্ট্রিং
  • ISO8601 স্ট্রিংয়ের তারিখ
  • দিবালোক সংরক্ষণ স্বয়ংক্রিয়ভাবে গণনা করা হয়

নমুনা ISO8601 স্ট্রিং

/*       "2013-06-25T14:00:00Z";
         "2013-06-25T140000Z";
         "2013-06-25T14:00:00+04";
         "2013-06-25T14:00:00+0400";
         "2013-06-25T140000+0400";
         "2013-06-25T14:00:00-04";
         "2013-06-25T14:00:00-0400";
         "2013-06-25T140000-0400";*/


public class ISO8601DateFormatter {

private static final DateFormat DATE_FORMAT_1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private static final DateFormat DATE_FORMAT_2 = new SimpleDateFormat("yyyy-MM-dd'T'HHmmssZ");
private static final String UTC_PLUS = "+";
private static final String UTC_MINUS = "-";

public static Date toDate(String iso8601string) throws ParseException {
    iso8601string = iso8601string.trim();
    if(iso8601string.toUpperCase().indexOf("Z")>0){
        iso8601string = iso8601string.toUpperCase().replace("Z", "+0000");
    }else if(((iso8601string.indexOf(UTC_PLUS))>0)){
        iso8601string = replaceColon(iso8601string, iso8601string.indexOf(UTC_PLUS));
        iso8601string = appendZeros(iso8601string, iso8601string.indexOf(UTC_PLUS), UTC_PLUS);
    }else if(((iso8601string.indexOf(UTC_MINUS))>0)){
        iso8601string = replaceColon(iso8601string, iso8601string.indexOf(UTC_MINUS));
        iso8601string = appendZeros(iso8601string, iso8601string.indexOf(UTC_MINUS), UTC_MINUS);
    }

    Date date = null;
    if(iso8601string.contains(":"))
        date = DATE_FORMAT_1.parse(iso8601string);
    else{
        date = DATE_FORMAT_2.parse(iso8601string);
    }
    return date;
}

public static String toISO8601String(Date date){
    return DATE_FORMAT_1.format(date);
}

private static String replaceColon(String sourceStr, int offsetIndex){
    if(sourceStr.substring(offsetIndex).contains(":"))
        return sourceStr.substring(0, offsetIndex) + sourceStr.substring(offsetIndex).replace(":", "");
    return sourceStr;
}

private static String appendZeros(String sourceStr, int offsetIndex, String offsetChar){
    if((sourceStr.length()-1)-sourceStr.indexOf(offsetChar,offsetIndex)<=2)
        return sourceStr + "00";
    return sourceStr;
}

}


2
সতর্কতা অবলম্বন করুন - ডেটফর্ম্যাট এবং উত্পন্ন ক্লাসগুলি মাল্টিথ্রিডের সাথে সামঞ্জস্যপূর্ণ নয়! স্ট্যাটিক সিম্পলডিটফর্ম্যাট অবজেক্ট যেমন DATE_FORMAT_1 এবং DATE_FORMAT_2 ব্যবহার করার অর্থ ISO8601 তারিখ ফর্ম্যাটর ফাংশনগুলিতে কল করা একাধিক থ্রেড একই তারিখফর্ম্যাট অবজেক্টটি ভাগ করে দেবে। এটি ডেটা ফর্ম্যাট কলগুলি থেকে ডেটা দুর্নীতির দিকে যায় এবং ভুল তারিখগুলি ফেরত আসে। এটি ঠিক করার জন্য, আপনাকে কেবল প্যাটার্নের স্ট্রিংগুলি ধ্রুবক তৈরি করা উচিত এবং যখনই প্রয়োজন হবে স্থানীয় সিম্পলডেটফর্ম্যাট ভেরিয়েবলগুলি তৈরি করা উচিত। এটি নিশ্চিত করবে যে প্রতিটি বস্তু কেবল একটি থ্রেড দ্বারা ব্যবহৃত হয়েছে।
থিও

থ্রেড-সুরক্ষার জন্য আরও ভাল সমাধানের পরিবর্তে থ্রেড-সুরক্ষার জন্য নির্মিত তারিখ-সময় গ্রন্থাগার ব্যবহার করা। জাভাতে সেই বিশ্বটি হয় জোডা-টাইম বা জাভা.টাইম হয়।
তুলসী বাউরক

-1

এটি আমার পক্ষে সবচেয়ে ভাল কাজ করেছে বলে মনে হয়েছিল:

public static Date fromISO8601_( String string ) {

    try {
            return new SimpleDateFormat ( "yyyy-MM-dd'T'HH:mm:ssXXX").parse ( string );
    } catch ( ParseException e ) {
        return Exceptions.handle (Date.class, "Not a valid ISO8601", e);
    }


}

আমার জাভা স্ক্রিপ্টের তারিখের স্ট্রিংগুলিকে জাভাতে রূপান্তর করতে হবে। আমি সুপারিশ সহ উপরের কাজগুলি পেয়েছি। সিম্পলডেটফর্ম্যাট ব্যবহার করে এমন কয়েকটি উদাহরণ রয়েছে যা কাছাকাছি থাকলেও তারা প্রস্তাবিত সাবটেট বলে মনে হয় নি:

http://www.w3.org/TR/NOTE-datetime

এবং পিআইএলএসটি এবং জাভাস্ক্রিপ্ট স্ট্রিংস দ্বারা সমর্থিত এবং এর মতো যা আমার প্রয়োজন।

এটি আইএসও 8601 স্ট্রিংয়ের সর্বাধিক সাধারণ রূপ এবং একটি ভাল উপসেট বলে মনে হচ্ছে।

তারা যে উদাহরণ দেয় তা হ'ল:

1994-11-05T08:15:30-05:00 corresponds 
November 5, 1994, 8:15:30 am, US Eastern Standard Time.

 1994-11-05T13:15:30Z corresponds to the same instant.

আমার একটি দ্রুত সংস্করণ রয়েছে:

final static int SHORT_ISO_8601_TIME_LENGTH =  "1994-11-05T08:15:30Z".length ();
                                            // 01234567890123456789012
final static int LONG_ISO_8601_TIME_LENGTH = "1994-11-05T08:15:30-05:00".length ();


public static Date fromISO8601( String string ) {
    if (isISO8601 ( string )) {
        char [] charArray = Reflection.toCharArray ( string );//uses unsafe or string.toCharArray if unsafe is not available
        int year = CharScanner.parseIntFromTo ( charArray, 0, 4 );
        int month = CharScanner.parseIntFromTo ( charArray, 5, 7 );
        int day = CharScanner.parseIntFromTo ( charArray, 8, 10 );
        int hour = CharScanner.parseIntFromTo ( charArray, 11, 13 );

        int minute = CharScanner.parseIntFromTo ( charArray, 14, 16 );

        int second = CharScanner.parseIntFromTo ( charArray, 17, 19 );

        TimeZone tz ;

         if (charArray[19] == 'Z') {

             tz = TimeZone.getTimeZone ( "GMT" );
         } else {

             StringBuilder builder = new StringBuilder ( 9 );
             builder.append ( "GMT" );
             builder.append( charArray, 19, LONG_ISO_8601_TIME_LENGTH - 19);
             String tzStr = builder.toString ();
             tz = TimeZone.getTimeZone ( tzStr ) ;

         }
         return toDate ( tz, year, month, day, hour, minute, second );

    }   else {
        return null;
    }

}

...

public static int parseIntFromTo ( char[] digitChars, int offset, int to ) {
    int num = digitChars[ offset ] - '0';
    if ( ++offset < to ) {
        num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
        if ( ++offset < to ) {
            num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
            if ( ++offset < to ) {
                num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                if ( ++offset < to ) {
                    num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                    if ( ++offset < to ) {
                        num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                        if ( ++offset < to ) {
                            num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                            if ( ++offset < to ) {
                                num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                                if ( ++offset < to ) {
                                    num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return num;
}


public static boolean isISO8601( String string ) {
      boolean valid = true;

      if (string.length () == SHORT_ISO_8601_TIME_LENGTH) {
          valid &=  (string.charAt ( 19 )  == 'Z');

      } else if (string.length () == LONG_ISO_8601_TIME_LENGTH) {
          valid &=  (string.charAt ( 19 )  == '-' || string.charAt ( 19 )  == '+');
          valid &=  (string.charAt ( 22 )  == ':');

      } else {
          return false;
      }

    //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
    // "1 9 9 4 - 1 1 - 0 5 T 0 8 : 1 5 : 3 0 - 0 5 : 0 0

    valid &=  (string.charAt ( 4 )  == '-') &&
                (string.charAt ( 7 )  == '-') &&
                (string.charAt ( 10 ) == 'T') &&
                (string.charAt ( 13 ) == ':') &&
                (string.charAt ( 16 ) == ':');

    return valid;
}

আমি এটি বেঞ্চমার্ক করি নি, তবে আমার ধারণা এটি খুব দ্রুত হবে। মনে হচ্ছে এটি কাজ করে। :)

@Test
public void testIsoShortDate() {
    String test =  "1994-11-05T08:15:30Z";

    Date date = Dates.fromISO8601 ( test );
    Date date2 = Dates.fromISO8601_ ( test );

    assertEquals(date2.toString (), date.toString ());

    puts (date);
}

@Test
public void testIsoLongDate() {
    String test =  "1994-11-05T08:11:22-05:00";

    Date date = Dates.fromISO8601 ( test );
    Date date2 = Dates.fromISO8601_ ( test );

    assertEquals(date2.toString (), date.toString ());

    puts (date);
}

-2

আমি মনে করি অনেক লোক যা করতে চায় তা হল JSON তারিখের স্ট্রিংগুলি পার্স করা। আপনি যদি এই পৃষ্ঠায় এসে থাকেন তবে আপনি একটি জাভাস্ক্রিপ্ট JSON তারিখটিকে জাভা তারিখে রূপান্তর করতে চাইতে পারেন এমন একটি ভাল সুযোগ রয়েছে।

কোনও JSON তারিখের স্ট্রিং দেখতে কেমন তা প্রদর্শন করতে:

    var d=new Date();
    var s = JSON.stringify(d);

    document.write(s);
    document.write("<br />"+d);


    "2013-12-14T01:55:33.412Z"
    Fri Dec 13 2013 17:55:33 GMT-0800 (PST)

JSON তারিখের স্ট্রিংটি 2013-12-14T01: 55: 33.412Z।

তারিখগুলি প্রতি কথায় জেএসএন স্পেক দ্বারা আচ্ছাদিত নয়, তবে উপরেরটি একটি খুব নির্দিষ্ট আইএসও 8601 ফর্ম্যাট, যখন আইএসও_৮60০১ অনেক বড় এবং এটি খুব গুরুত্বপূর্ণ একটি সবেমাত্র সাবসেট।

দেখুন http://www.json.org দেখুন http://en.wikipedia.org/wiki/ISO_8601 দেখুন http://www.w3.org/TR/NOTE-datetime

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

/*
    var d=new Date();
    var s = JSON.stringify(d);

    document.write(s);
    document.write("<br />"+d);


    "2013-12-14T01:55:33.412Z"
    Fri Dec 13 2013 17:55:33 GMT-0800 (PST)


 */
@Test
public void jsonJavaScriptDate() {
    String test =  "2013-12-14T01:55:33.412Z";

    Date date = Dates.fromJsonDate ( test );
    Date date2 = Dates.fromJsonDate_ ( test );

    assertEquals(date2.toString (), "" + date);

    puts (date);
}

আমি আমার প্রকল্পের জন্য এটি করার দুটি উপায় লিখেছি। একটি মান, একটি দ্রুত।

আবার, জেএসওএন তারিখ স্ট্রিংটি আইএসও 8601 এর খুব নির্দিষ্ট প্রয়োগ implementation

(আমি অন্য একটিতে অন্য উত্তরে পোস্ট করেছি যা পিআইএলএসটি তারিখগুলির জন্য কাজ করা উচিত, যা ভিন্ন আইএসও 8601 ফর্ম্যাট)।

জেএসওএন তারিখটি নিম্নরূপ:

public static Date fromJsonDate_( String string ) {

    try {

        return new SimpleDateFormat ( "yyyy-MM-dd'T'HH:mm:ss.SSSXXX").parse ( string );
    } catch ( ParseException e ) {
        return Exceptions.handle (Date.class, "Not a valid JSON date", e);
    }


}

প্লিস্ট ফাইলগুলি (এএসসিআইআই নন জিএনইউএনেক্সট) এছাড়াও আইএসও 8601 ব্যবহার করে তবে কোনও মিলিসেকেন্ড তাই না ... সমস্ত আইএসও -8601 তারিখ একই নয়। (কমপক্ষে আমি মিলিস ব্যবহার করে এমন একটি এখনও খুঁজে পাইনি এবং আমি যে পার্সারটি দেখেছি তা সম্পূর্ণভাবে ওএমজি টাইমজোন এড়িয়ে যেতে পারে)।

এখন দ্রুত সংস্করণের জন্য (এটি আপনি বুনে খুঁজে পেতে পারেন)।

public static Date fromJsonDate( String string ) {

    return fromJsonDate ( Reflection.toCharArray ( string ), 0, string.length () );

}

মনে রাখবেন যে প্রতিবিম্ব. টোচারআরারি উপলভ্য থাকলে অনিরাপদ ব্যবহার করে তবে স্ট্রিং. টোচারআররে ডিফল্ট হয়।

(আপনি এটি রিফ্লেকশন. টোচারআরে (স্ট্রিং) কে স্ট্রিং.টোচারআরে ()) দিয়ে প্রতিস্থাপনের মাধ্যমে উদাহরণের বাইরে নিয়ে যেতে পারেন।

public static Date fromJsonDate( char[] charArray, int from, int to ) {

    if (isJsonDate ( charArray, from, to )) {
        int year = CharScanner.parseIntFromTo ( charArray, from + 0, from + 4 );
        int month = CharScanner.parseIntFromTo ( charArray,  from +5,  from +7 );
        int day = CharScanner.parseIntFromTo ( charArray,  from +8,  from +10 );
        int hour = CharScanner.parseIntFromTo ( charArray,  from +11,  from +13 );

        int minute = CharScanner.parseIntFromTo ( charArray,  from +14,  from +16 );

        int second = CharScanner.parseIntFromTo ( charArray,  from +17,  from +19 );

        int miliseconds = CharScanner.parseIntFromTo ( charArray,  from +20,  from +23 );

        TimeZone tz = TimeZone.getTimeZone ( "GMT" );


        return toDate ( tz, year, month, day, hour, minute, second, miliseconds );

    }   else {
        return null;
    }

}

IsJsonDate নিম্নলিখিত হিসাবে প্রয়োগ করা হয়:

public static boolean isJsonDate( char[] charArray, int start, int to ) {
    boolean valid = true;
    final int length = to -start;

    if (length != JSON_TIME_LENGTH) {
        return false;
    }

    valid &=  (charArray [ start + 19 ]  == '.');

    if (!valid) {
        return false;
    }


    valid &=  (charArray[  start +4 ]  == '-') &&
            (charArray[  start +7 ]  == '-') &&
            (charArray[  start +10 ] == 'T') &&
            (charArray[  start +13 ] == ':') &&
            (charArray[  start +16 ] == ':');

    return valid;
}

যাইহোক ... আমার অনুমান যে এখানে আসা বেশ কয়েক জন লোকই সম্ভবত জেএসএন ডেট স্ট্রিং খুঁজছেন এবং এটি একটি আইএসও -8601 তারিখ হলেও এটি খুব নির্দিষ্ট একটি নির্দিষ্ট পার্সের প্রয়োজন।

public static int parseIntFromTo ( char[] digitChars, int offset, int to ) {
    int num = digitChars[ offset ] - '0';
    if ( ++offset < to ) {
        num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
        if ( ++offset < to ) {
            num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
            if ( ++offset < to ) {
                num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                if ( ++offset < to ) {
                    num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                    if ( ++offset < to ) {
                        num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                        if ( ++offset < to ) {
                            num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                            if ( ++offset < to ) {
                                num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                                if ( ++offset < to ) {
                                    num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return num;
}

Https://github.com/RichardHightower/boon দেখুন বুনের একটি পিআইএলএসটি পার্সার (এএসসিআইআই) এবং জেএসএন পার্সার রয়েছে।

JSON পার্সার হ'ল জাভা জেএসএন পার্সার আমি জানি know

গ্যাটলিং পারফরম্যান্স ডিউড দ্বারা স্বতন্ত্রভাবে যাচাই করা হয়েছে।

https://github.com/gatling/json-parsers-benchmark

Benchmark                               Mode Thr     Count  Sec         Mean   Mean error        Units
BoonCharArrayBenchmark.roundRobin      thrpt  16        10    1   724815,875    54339,825    ops/s
JacksonObjectBenchmark.roundRobin      thrpt  16        10    1   580014,875   145097,700    ops/s
JsonSmartBytesBenchmark.roundRobin     thrpt  16        10    1   575548,435    64202,618    ops/s
JsonSmartStringBenchmark.roundRobin    thrpt  16        10    1   541212,220    45144,815    ops/s
GSONStringBenchmark.roundRobin         thrpt  16        10    1   522947,175    65572,427    ops/s
BoonDirectBytesBenchmark.roundRobin    thrpt  16        10    1   521528,912    41366,197    ops/s
JacksonASTBenchmark.roundRobin         thrpt  16        10    1   512564,205   300704,545    ops/s
GSONReaderBenchmark.roundRobin         thrpt  16        10    1   446322,220    41327,496    ops/s
JsonSmartStreamBenchmark.roundRobin    thrpt  16        10    1   276399,298   130055,340    ops/s
JsonSmartReaderBenchmark.roundRobin    thrpt  16        10    1    86789,825    17690,031    ops/s

এটিতে স্রোত, পাঠক, বাইটস [], চর [], চারসেকেন্স (স্ট্রিংবিল্ডার, ক্যারেক্টারবাফার) এবং স্ট্রিংয়ের জন্য দ্রুতগতিতে জেএসএন পার্সার রয়েছে।

আরও মানদণ্ড এখানে দেখুন:

https://github.com/RichardHightower/json-parsers-benchmark


জেএসওএন সম্পর্কে এই উত্তরটি প্রশ্ন থেকে আলাদা নয়। তদ্ব্যতীত, খুব কম JSON ডেটা ধরণের মধ্যে "JSON তারিখ" বলে কোনও জিনিস নেই বলে এই প্রশ্নটি ভুল । এবং আজকাল, এই সমস্ত কোডটি একক লাইন কলটি অন্তর্নির্মিত জাভা বৈশিষ্ট্যে পরিবর্তিত হতে পারে:Instant.parse( "2013-12-14T01:55:33.412Z" )
বেসিল বাউরক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.