SHIDHIN TS
SHIDHIN TS

Reputation: 1665

How to show native Islamic(hijri) Calendar?

I want to show the date picker Dialog on Android. Now I can choose only Normal Date. How I can convert it to hijri(islamic) Calendar? Here is the code I am using to show the Dialog,

Code to Show Date-picker Dialog

private void showDOBPickerDialog(Context context, String DateString) {
    try {
        String defaltDate = getCurrentDate_MMDDYYYY();
        if (DateString == null || DateString.isEmpty() || DateString.length() < 10)
            DateString = defaltDate;

        int monthOfYear, dayOfMonth, year;
        monthOfYear = Integer.parseInt(DateString.substring(0, DateString.indexOf("/"))) - 1;
        dayOfMonth = Integer.parseInt(DateString.substring(DateString.indexOf("/") + 1, DateString.lastIndexOf("/")));
        year = Integer.parseInt(DateString.substring(DateString.lastIndexOf("/") + 1));

        DatePickerDialog datePickerDialog = new DatePickerDialog(context, new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                monthOfYear = monthOfYear + 1;
                String Month = String.valueOf(monthOfYear), Day = String.valueOf(dayOfMonth);
                if (monthOfYear < 10)
                    Month = "0" + monthOfYear;

                if (dayOfMonth < 10)
                    Day = "0" + dayOfMonth;
                String selectedDate = Month + "/" + Day + "/" + year;
                edtTxtDateOfId.setText(selectedDate);
            }
        }, year, monthOfYear, dayOfMonth);
        datePickerDialog.setTitle("Select Date");
        datePickerDialog.show();
    } catch (Exception e) {
    }
}

To get the Current Date,

public static String getCurrentDate_MMDDYYYY() {
    String DATE_FORMAT_NOW = "MM/dd/yyyy";
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
    Calendar cal = GregorianCalendar.getInstance(Locale.FRANCE);
    cal.setTime(new Date());
    return sdf.format(cal.getTime());
}

Upvotes: 1

Views: 8836

Answers (3)

Sel&#231;uk Aslantaş
Sel&#231;uk Aslantaş

Reputation: 39

Convert current date to hijri date

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
   Date date = new Date();

   sdf.applyPattern("dd");
   int dayOfMonth = Integer.parseInt(sdf.format(date));
   sdf.applyPattern("MM");
   int monthOfYear = Integer.parseInt(sdf.format(date));
   sdf.applyPattern("yyyy");
   int year = Integer.parseInt(sdf.format(date));

   // Now
   LocalDate dt = LocalDate.of(year, monthOfYear, dayOfMonth);
   // convert to hijrah
   HijrahDate hijrahDate = HijrahDate.from(dt);
   // format to MM/DD/YYYY
   DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMMM yyyy");

Upvotes: 0

Meno Hochschild
Meno Hochschild

Reputation: 44071

Taking into account your statement given in one comment that you only want a native solution and reject any extra library, I would advise to use ICU4J-class IslamicCalendar.

Sure, you have then to accept two major disadvantages:

  • API-level 24 (not so widespread on mobile phones)
  • Old-fashioned API-style (for example not immutable)

Another disadvantage (which is only relevant if you are also interested in the clock time) is the fact that ICU4J does not support the start of Islamic day in the evening at sunset on previous day. This feature is only supported in my lib Time4J, nowhere else. But you have probably no need for this feature in a date picker dialog.

Advantages:

  • API-style similar to what is "traditional" in package java.util, so I assume that you are got accustomed to it (but many/most people see the style rather as negative, you have to make your own decision)
  • at least umalqura-variant-variant of Saudi-Arabia is offered (note: other libs like Threeten-BP or Joda-Time-Android do NOT offer that variant)
  • acceptable or even good degree of internationalization (also better than in ThreetenBP or Joda-Time-Android)

For completeness, if you are willing to restrict your Android app to level 26 or higher only then you can also use java.time.chrono.HijrahChronology. But I think this is still too early in year 2018 because the support of mobile phones for level 26 is actually very small. And while it does offer the Umalqura variant (of Saudi-Arabia), it does not offer any other variant.

Else there are no native solutions available. And to use only native solutions is a restriction, too, IMHO.

Upvotes: 1

roisnd
roisnd

Reputation: 73

As you don't want a library and need only native code, you can take a look at the source code of this implementation: https://github.com/ThreeTen/threetenbp/tree/master/src/main/java/org/threeten/bp/chrono

Take a look at the HijrahChronology, HijrahDate and HijrahEra classes, perhaps you can get some ideas and see how all the math is done to convert between this calendar and ISO8601 calendar.

But honestly, IMO calendars implementations are too complex and in most cases are not worth the trouble to do it by yourself. That's one of the cases where adding a library is totally worth it.

Using the ThreeTen-Backport lib - and configuring it to use with Android - will give you an easy way to convert the dates and also to format them:

// get ISO8601 date (the "normal" date)
int dayOfMonth = 20;
int monthOfYear = 3;
int year = 2018;
// March 20th 2018
LocalDate dt = LocalDate.of(year, monthOfYear, dayOfMonth);

// convert to hijrah
HijrahDate hijrahDate = HijrahDate.from(dt);

// format to MM/DD/YYYY
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
String formatted = formatter.format(hijrahDate); // 07/03/1439

You can also call HijrahDate.now() to directly get the current date.

And you can convert the hijrahDate back to a "normal" date with LocalDate.from(hijrahDate).


You can also use time4j:

// get ISO8601 date (the "normal" date)
int dayOfMonth = 20;
int monthOfYear = 3;
int year = 2018;
PlainDate dt = PlainDate.of(year, monthOfYear, dayOfMonth);

// convert to Hijri, using different variants
HijriCalendar hijriDateUmalqura = dt.transform(HijriCalendar.class, HijriCalendar.VARIANT_UMALQURA);
HijriCalendar hijriDateWest = dt.transform(HijriCalendar.class, HijriAlgorithm.WEST_ISLAMIC_CIVIL);

// format to MM/DD/YYYY
ChronoFormatter<HijriCalendar> fmt = ChronoFormatter.ofPattern("MM/dd/yyyy", PatternType.CLDR, Locale.ENGLISH, HijriCalendar.family());
String formatted = fmt.format(hijriDateUmalqura); // 07/03/1439

// get current date
HijriCalendar now = HijriCalendar.nowInSystemTime(HijriCalendar.VARIANT_UMALQURA, StartOfDay.MIDNIGHT);

// convert back to "normal" date
PlainDate date = hijriDateUmalqura.transform(PlainDate.class);

Upvotes: 3

Related Questions