java - जावा में जलाली कैलेंडर के लिए एक अच्छी तारीख कनवर्टर?




date localization calendar jalali-calendar (6)

मैं एक जावा ऐप विकसित कर रहा हूं और मेरे पास एक timeStamp ( long ) है। मैं इसे आसानी से ग्रेगोरियन तिथि में बदलने के लिए इस कोड का उपयोग कर सकता हूं:

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

लेकिन मुझे जलाली कैलेंडर में तारीख की जरूरत है। मैंने खोज की लेकिन कोई अच्छी लाइब्रेरी नहीं मिली। क्या आप timeStamp से (या जलाली प्रारूप में दिनांक बनाने के लिए) एक विश्वसनीय और अच्छी लाइब्रेरी जानते हैं? मुझे एक कार्यान्वयन या एक एल्गोरिथ्म की आवश्यकता नहीं है, क्योंकि यह समस्या बहुत छोटी है और इसमें बहुत सारे नियम हैं, मुझे एक विश्वसनीय समाधान की आवश्यकता है


Answers

जीथुब पर एक अच्छा पुस्तकालय है, जिसमें एक बहुत ही साधारण एपीआई है और इसमें बहुत सारी क्षमताएं हैं और यह मावन केंद्र पर भी उपलब्ध है:

https://github.com/razeghi71/JalaliCalendar


आप एक चित्रमय जावा-आधारित जलाली कैलेंडर प्राप्त कर सकते हैं जिसे persain-calendar कहा जाता है। यहाँ फ़ारसी-कैलेंडर का एक स्क्रीनशॉट है।


बेहतर स्थानीयकरण और भाषा समर्थन के लिए, आईबीएम से ICU (यूनिकोड के लिए अंतर्राष्ट्रीय घटक) पुस्तकालय का उपयोग करना अक्सर सुविधाजनक होता है।

एपीआई मानक जावा एपीआई के समान हैं, लेकिन स्थानीयकरण और अंतर्राष्ट्रीयकरण (जैसे समय और कैलेंडर के मुद्दों, छँटाई, नियमों को प्रारूपित करना और उचित यूनिकोड समर्थन के साथ एक regex कार्यान्वयन) के लिए अतिरिक्त समर्थन जोड़ते हैं।

फ़ारसी कैलेंडर बनाने और फ़ारसी में स्वरूपित तारीख को आउटपुट करने के लिए, आप कुछ ऐसा करना चाहेंगे:

import com.ibm.icu.text.DateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;

...

ULocale locale = new ULocale("[email protected]=persian");

Calendar calendar = Calendar.getInstance(locale);
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, locale);

System.out.println(df.format(calendar));

यह आउटपुट होगा:

چهارشنبه ۱۰ اردیبهشت ه ه'.ش


आप JalCal उपयोग कर सकते हैं कि जलाली (फारसी) जावा में कैलेंडर कन्वर्टर:

<dependency>
    <groupId>com.github.sbahmani</groupId>
    <artifactId>jalcal</artifactId>
    <version>1.0</version>
</dependency>

1. जलाली टू ग्रेगोरियन

  Calendar expected4 = Calendar.getInstance(TimeZone.getDefault());
  expected4.set(2014, 7, 5, 1, 23, 1);
  assertThat(JalCal.jalaliToGregorian(1393, 5, 14, 1, 23, 1).toString()).isEqualTo(expected4.getTime().toString());

2. ग्रेगोरियन से जलाली

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.DAY_OF_MONTH, 5);
    cal.set(Calendar.MONTH, 6);
    cal.set(Calendar.YEAR, 2014);
    cal.set(Calendar.HOUR_OF_DAY, 10);
    cal.set(Calendar.MINUTE, 25);
    cal.set(Calendar.SECOND, 1);
    cal.set(Calendar.MILLISECOND, 0);
    assertThat(JalCal.gregorianToJalali(cal.getTime(), true)).isEqualTo("14/04/1393   10:25:01");
    assertThat(JalCal.gregorianToJalali(new Date(1426883400000l), true)).isEqualTo("01/01/1394   00:00:00");

मैंने अपने पुस्तकालय Time4J भीतर जावा में अपना फारसी (जलाली) कैलेंडर Time4J । कार्यान्वयन बोरकोव्स्की के एल्गोरिथ्म को Borkowski (कम से कम जब तक ग्रेगोरियन वर्ष 2129 तक - कोई 2025-बग नहीं)।

ओपी की ठोस समस्या का समाधान:

// conversion from jalali to gregorian by constructed input
PersianCalendar jalali = PersianCalendar.of(1394, 11, 5);
// or use a safe enum instead of the month number:
// PersianCalendar jalali = PersianCalendar.of(1394, PersianMonth.BAHMAN, 5);

PlainDate gregorian = jalali.transform(PlainDate.class); 
System.out.println(gregorian); // 2016-01-25

// conversion to millis-since-unix (timezone-dependent)
Moment moment1 = gregorian.atStartOfDay().inTimezone(ASIA.TEHRAN);
long millisSinceUnix = TemporalType.MILLIS_SINCE_UNIX.from(moment1);
System.out.println(millisSinceUnix); // 1453667400000L

// conversion of millis-since-unix to jalali (timezone-dependent)
Moment moment2 = TemporalType.MILLIS_SINCE_UNIX.translate(millisSinceUnix);
PlainDate gregorian2 = moment2.toZonalTimestamp(ASIA.TEHRAN).toDate();
System.out.println(gregorian2.transform(PersianCalendar.class)); // AP-1394-11-05

// formatting and parsing in Farsi language using full style
ChronoFormatter<PersianCalendar> f1 = 
    ChronoFormatter.ofStyle(DisplayMode.FULL, new Locale("fa"), PersianCalendar.axis());
System.out.println(f1.format(jalali)); // ه‍.ش. ۱۳۹۴ بهمن ۵, دوشنبه
System.out.println(f1.parse("ه‍.ش. ۱۳۹۴ بهمن ۵, دوشنبه")); // AP-1394-11-05

// formatting in English language using custom pattern
ChronoFormatter<PersianCalendar> f2 = 
    ChronoFormatter.ofPattern(
        "d. MMMM yyyy", PatternType.CLDR, Locale.ENGLISH, PersianCalendar.axis());
System.out.println(f2.format(jalali)); // 5. Bahman 1394

बेशक, कैलेंडर में तारीख अंकगणित (दिनों या महीनों को जोड़ने, दिनों, महीनों आदि में डेल्टा की गणना) या फ़ील्ड / तत्व-जोड़तोड़ (महीने के अंतिम दिन तक आसान) जैसी अधिक सुविधाएँ प्रदान की जाती हैं।

अब तक प्रस्तावित अन्य पुस्तकालयों के बारे में साइड नोट्स:

पुस्तकालयों amirmehdizadeh / JalaliCalendar के साथ-साथ ICU4J दोनों शून्य-आधारित महीनों का उपयोग करते हैं। यह बेहद भ्रामक हो सकता है। गैर-सहज ज्ञान युक्त उदाहरण का उपयोग कर अमीरहिद्ज़ादेह का पुस्तकालय:

YearMonthDate jalali = new YearMonthDate(1394, 10, 5); // really month 11 (Bahman)
YearMonthDate gregorian = JalaliCalendar.jalaliToGregorian(jalali);
System.out.println(gregorian); // 2016/0/25 => really month 1 (January)

अंतर्राष्ट्रीयकरण के बारे में, मुझे नहीं लगता कि ICU4J फारसी कैलेंडर के क्षेत्र पर Time4J से अधिक की पेशकश करता है क्योंकि बाद वाला नवीनतम CLDR- संस्करण v28 पर आधारित है। Time4J वास्तव में फारसी महीनों और युगों (फारसी और पश्तो सहित) के लिए लगभग 25 भाषाओं का समर्थन करता है।


जावा 1.7 या बाद में , ऐसा करने का मानक तरीका इस प्रकार है:

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);

प्रासंगिक जावाडोक देखें। इस दृष्टिकोण का एक java.util.Random उदाहरण को स्पष्ट रूप से प्रारंभ करने की आवश्यकता नहीं है, जो गलत तरीके से उपयोग किए जाने पर भ्रम और त्रुटि का स्रोत हो सकता है।

हालांकि, इसके विपरीत बीज को स्पष्ट रूप से सेट करने का कोई तरीका नहीं है, इसलिए उन परिस्थितियों में परिणाम पुन: उत्पन्न करना मुश्किल हो सकता है जहां यह उपयोगी है जैसे खेल राज्यों या इसी तरह की जांच या सहेजना। उन परिस्थितियों में, नीचे दिखाए गए पूर्व-जावा 1.7 तकनीक का उपयोग किया जा सकता है।

जावा 1.7 से पहले , ऐसा करने का मानक तरीका इस प्रकार है:

import java.util.Random;

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max) {

    // NOTE: This will (intentionally) not run as written so that folks
    // copy-pasting have to think about how to initialize their
    // Random instance.  Initialization of the Random instance is outside
    // the main scope of the question, but some decent options are to have
    // a field that is initialized once and then re-used as needed or to
    // use ThreadLocalRandom (if using at least Java 1.7).
    // 
    // In particular, do NOT do 'Random rand = new Random()' here or you
    // will get not very good / not very random results.
    Random rand;

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

प्रासंगिक जावाडोक देखें। अभ्यास में, java.util.Random क्लास java.lang.Math.random() लिए अक्सर बेहतर है।

विशेष रूप से, कार्य को पूरा करने के लिए मानक लाइब्रेरी के भीतर सीधी एपीआई होने पर यादृच्छिक पूर्णांक पीढ़ी के पहिये को फिर से शुरू करने की कोई आवश्यकता नहीं है।





java date localization calendar jalali-calendar