content: package com.alirezaafkar.sundatepicker.components;
  
  import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.Calendar;
  import java.util.Date;
  import java.util.GregorianCalendar;
  import java.util.Locale;
  
  public class JDF {
  
      /**
       * Main: The default constructor uses the current Gregorian date to
       * initialize the other private memebers of the class (Iranian and Julian
       * dates).
       */
      public JDF() {
          Calendar calendar = new GregorianCalendar();
          setGregorianDate(calendar.get(Calendar.YEAR),
                  calendar.get(Calendar.MONTH) + 1,
                  calendar.get(Calendar.DAY_OF_MONTH));
      }
  
      public JDF(GregorianCalendar calendar) {
          setGregorianDate(calendar.get(Calendar.YEAR),
                  calendar.get(Calendar.MONTH) + 1,
                  calendar.get(Calendar.DAY_OF_MONTH));
      }
  
      public JDF(Calendar calendar) {
          setGregorianDate(calendar.get(Calendar.YEAR),
                  calendar.get(Calendar.MONTH) + 1,
                  calendar.get(Calendar.DAY_OF_MONTH));
      }
  
      /**
       * Main: This constructor receives a Iranian date and initializes the
       * other private members of the class accordingly.
       *
       * @param year  int
       * @param month int
       * @param day   int
       * @return
       */
      public JDF(int year, int month, int day) {
          this();
          setIranianDate(year, month, day);
      }
  
      /**
       * getIranianYear: Returns the 'year' part of the Iranian date.
       *
       * @return int
       */
      public int getIranianYear() {
          return irYear;
      }
  
      /**
       * getIranianMonth: Returns the 'month' part of the Iranian date.
       *
       * @return int
       */
      public int getIranianMonth() {
          return irMonth;
      }
  
      /**
       * getGregorianCalendar: gets Iranian date and returns Gregorian calendar
       *
       * @return calendar
       */
      public GregorianCalendar getGregorianCalendar(int year, int month, int day)
              throws ParseException {
  
          setIranianDate(year, month, day);
  
          SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/M/d",
                  Locale.US);
          Date myDate = dateFormat.parse(getGregorianDate());
          GregorianCalendar calendar = new GregorianCalendar();
          calendar.setTime(myDate);
          calendar.add(Calendar.MONTH, 1);
  
          return calendar;
      }
  
      public long getTimeInMillis(){
          try {
              return getGregorianCalendar(irYear, irMonth, irDay).getTimeInMillis();
          } catch (ParseException e) {
              return 0;
          }
      }
  
      /**
       * getIranianDayName: Returns the number of Iranian day of week
       *
       * @return int
       */
      public int getIranianDay(int year, int month, int day)
              throws ParseException {
  
          setIranianDate(year, month, day);
  
          SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/M/d",
                  Locale.US);
          Date myDate = dateFormat.parse(getGregorianDate());
          Calendar calendar = Calendar.getInstance();
          calendar.setTime(myDate);
  
          int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
  
          if (Calendar.SATURDAY == dayOfWeek) {
              dayOfWeek = 0;
          } else if (Calendar.SUNDAY == dayOfWeek) {
              dayOfWeek = 1;
          } else if (Calendar.MONDAY == dayOfWeek) {
              dayOfWeek = 2;
          } else if (Calendar.TUESDAY == dayOfWeek) {
              dayOfWeek = 3;
          } else if (Calendar.WEDNESDAY == dayOfWeek) {
              dayOfWeek = 4;
          } else if (Calendar.THURSDAY == dayOfWeek) {
              dayOfWeek = 5;
          } else if (Calendar.FRIDAY == dayOfWeek) {
              dayOfWeek = 6;
          }
  
          return dayOfWeek;
      }
  
      /**
       * getIranianDay: Returns the 'day' part of the Iranian date.
       *
       * @return int
       */
      public int getIranianDay() {
          return irDay;
      }
  
      /**
       * getGregorianYear: Returns the 'year' part of the Gregorian date.
       *
       * @return int
       */
      public int getGregorianYear() {
          return gYear;
      }
  
      /**
       * getGregorianMonth: Returns the 'month' part of the Gregorian date.
       *
       * @return int
       */
      public int getGregorianMonth() {
          return gMonth;
      }
  
      /**
       * getGregorianDay: Returns the 'day' part of the Gregorian date.
       *
       * @return int
       */
      public int getGregorianDay() {
          return gDay;
      }
  
      /**
       * getJulianYear: Returns the 'year' part of the Julian date.
       *
       * @return int
       */
      public int getJulianYear() {
          return juYear;
      }
  
      /**
       * getJulianMonth: Returns the 'month' part of the Julian date.
       *
       * @return int
       */
      public int getJulianMonth() {
          return juMonth;
      }
  
      /**
       * getJulianDay() Returns the 'day' part of the Julian date.
       *
       * @return int
       */
      public int getJulianDay() {
          return juDay;
      }
  
      /**
       * getIranianDate: Returns a string version of Iranian date
       *
       * @return String
       */
      public String getIranianDate() {
          return (irYear + "/" + irMonth + "/" + irDay);
      }
  
      /**
       * getGregorianDate: Returns a string version of Gregorian date
       *
       * @return String
       */
      public String getGregorianDate() {
          return (gYear + "/" + gMonth + "/" + gDay);
      }
  
      /**
       * getJulianDate: Returns a string version of Julian date
       *
       * @return String
       */
      public String getJulianDate() {
          return (juYear + "/" + juMonth + "/" + juDay);
      }
  
      /**
       * getWeekDayStr: Returns the week day name.
       *
       * @return String
       */
      public String getWeekDayStr() {
          String weekDayStr[] = {"Monday", "Tuesday", "Wednesday", "Thursday",
                  "Friday", "Saturday", "Sunday"};
          return (weekDayStr[getDayOfWeek()]);
      }
  
      /**
       * toString: Overrides the default toString() method to return all dates.
       *
       * @return String
       */
      @Override
      public String toString() {
          return (getWeekDayStr() + ", Gregorian:[" + getGregorianDate()
                  + "], Julian:[" + getJulianDate() + "], Iranian:["
                  + getIranianDate() + "]");
      }
  
      /**
       * getDayOfWeek: Returns the week day number. Monday=0..Sunday=6;
       *
       * @return int
       */
      public int getDayOfWeek() {
          return (JDN % 7);
      }
  
      /**
       * nextDay: Go to next julian day number (JDN) and adjusts the other dates.
       */
      public void nextDay() {
          JDN++;
          JDNToIranian();
          JDNToJulian();
          JDNToGregorian();
      }
  
      /**
       * nextDay: Overload the nextDay() method to accept the number of days to go
       * ahead and adjusts the other dates accordingly.
       *
       * @param days int
       */
      public void nextDay(int days) {
          JDN += days;
          JDNToIranian();
          JDNToJulian();
          JDNToGregorian();
      }
  
      /**
       * previousDay: Go to previous julian day number (JDN) and adjusts the otehr
       * dates.
       */
      public void previousDay() {
          JDN--;
          JDNToIranian();
          JDNToJulian();
          JDNToGregorian();
      }
  
      /**
       * previousDay: Overload the previousDay() method to accept the number of
       * days to go backward and adjusts the other dates accordingly.
       *
       * @param days int
       */
      public void previousDay(int days) {
          JDN -= days;
          JDNToIranian();
          JDNToJulian();
          JDNToGregorian();
      }
  
      /**
       * setIranianDate: Sets the date according to the Iranian calendar and
       * adjusts the other dates.
       *
       * @param year  int
       * @param month int
       * @param day   int
       */
      public JDF setIranianDate(int year, int month, int day) {
          irYear = year;
          irMonth = month;
          irDay = day;
          JDN = IranianDateToJDN();
          JDNToIranian();
          JDNToJulian();
          JDNToGregorian();
          return this;
      }
  
      /**
       * setGregorianDate: Sets the date according to the Gregorian calendar and
       * adjusts the other dates.
       *
       * @param year  int
       * @param month int
       * @param day   int
       */
      public void setGregorianDate(int year, int month, int day) {
          gYear = year;
          gMonth = month;
          gDay = day;
          JDN = gregorianDateToJDN(year, month, day);
          JDNToIranian();
          JDNToJulian();
          JDNToGregorian();
      }
  
      /**
       * setJulianDate: Sets the date according to the Julian calendar and adjusts
       * the other dates.
       *
       * @param year  int
       * @param month int
       * @param day   int
       */
      public void setJulianDate(int year, int month, int day) {
          juYear = year;
          juMonth = month;
          juDay = day;
          JDN = julianDateToJDN(year, month, day);
          JDNToIranian();
          JDNToJulian();
          JDNToGregorian();
      }
  
      /**
       * IranianCalendar: This method determines if the Iranian (Jalali) year is
       * leap (366-day long) or is the common year (365 days), and finds the day
       * in March (Gregorian Calendar)of the first day of the Iranian year
       * ('irYear').Iranian year (irYear) ranges from (-61 to 3177).This method
       * will set the following private data members as follows: leap: Number of
       * years since the last leap year (0 to 4) Gy: Gregorian year of the
       * begining of Iranian year march: The March day of Farvardin the 1st (first
       * day of jaYear)
       */
      private void IranianCalendar() {
          // Iranian years starting the 33-year rule
          int Breaks[] = {-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210,
                  1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178};
          int jm, N, leapJ, leapG, jp, j, jump;
          gYear = irYear + 621;
          leapJ = -14;
          jp = Breaks[0];
          // Find the limiting years for the Iranian year 'irYear'
          j = 1;
          do {
              jm = Breaks[j];
              jump = jm - jp;
              if (irYear >= jm) {
                  leapJ += (jump / 33 * 8 + (jump % 33) / 4);
                  jp = jm;
              }
              j++;
          } while ((j < 20) && (irYear >= jm));
          N = irYear - jp;
          // Find the number of leap years from AD 621 to the begining of the
          // current
          // Iranian year in the Iranian (Jalali) calendar
          leapJ += (N / 33 * 8 + ((N % 33) + 3) / 4);
          if (((jump % 33) == 4) && ((jump - N) == 4))
              leapJ++;
          // And the same in the Gregorian date of Farvardin the first
          leapG = gYear / 4 - ((gYear / 100 + 1) * 3 / 4) - 150;
          march = 20 + leapJ - leapG;
          // Find how many years have passed since the last leap year
          if ((jump - N) < 6)
              N = N - jump + ((jump + 4) / 33 * 33);
          leap = (((N + 1) % 33) - 1) % 4;
          if (leap == -1)
              leap = 4;
      }
  
      /**
       * IranianDateToJDN: Converts a date of the Iranian calendar to the Julian
       * Day Number. It first invokes the 'IranianCalender' private method to
       * convert the Iranian date to Gregorian date and then returns the Julian
       * Day Number based on the Gregorian date. The Iranian date is obtained from
       * 'irYear'(1-3100),'irMonth'(1-12) and 'irDay'(1-29/31).
       *
       * @return long (Julian Day Number)
       */
      private int IranianDateToJDN() {
          IranianCalendar();
          return (gregorianDateToJDN(gYear, 3, march) + (irMonth - 1) * 31
                  - irMonth / 7 * (irMonth - 7) + irDay - 1);
      }
  
      /**
       * JDNToIranian: Converts the current value of 'JDN' Julian Day Number to a
       * date in the Iranian calendar. The caller should make sure that the
       * current value of 'JDN' is set correctly. This method first converts the
       * JDN to Gregorian calendar and then to Iranian calendar.
       */
      private void JDNToIranian() {
          JDNToGregorian();
          irYear = gYear - 621;
          IranianCalendar(); // This invocation will update 'leap' and 'march'
          int JDN1F = gregorianDateToJDN(gYear, 3, march);
          int k = JDN - JDN1F;
          if (k >= 0) {
              if (k <= 185) {
                  irMonth = 1 + k / 31;
                  irDay = (k % 31) + 1;
                  return;
              } else
                  k -= 186;
          } else {
              irYear--;
              k += 179;
              if (leap == 1)
                  k++;
          }
          irMonth = 7 + k / 30;
          irDay = (k % 30) + 1;
      }
  
      /**
       * julianDateToJDN: Calculates the julian day number (JDN) from Julian
       * calendar dates. This integer number corresponds to the noon of the date
       * (i.e. 12 hours of Universal Time). This method was tested to be good
       * (valid) since 1 March, -100100 (of both calendars) up to a few millions
       * (10^6) years into the future. The algorithm is based on D.A.Hatcher,
       * Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by K.M. Borkowski,
       * Post.Astron. 25(1987), 275-279.
       *
       * @param year  int
       * @param month int
       * @param day   int
       * @return int
       */
      private int julianDateToJDN(int year, int month, int day) {
          return (year + (month - 8) / 6 + 100100) * 1461 / 4
                  + (153 * ((month + 9) % 12) + 2) / 5 + day - 34840408;
      }
  
      /**
       * JDNToJulian: Calculates Julian calendar dates from the julian day number
       * (JDN) for the period since JDN=-34839655 (i.e. the year -100100 of both
       * calendars) to some millions (10^6) years ahead of the present. The
       * algorithm is based on D.A. Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55
       * slightly modified by K.M. Borkowski, Post.Astron. 25(1987), 275-279).
       */
      private void JDNToJulian() {
          int j = 4 * JDN + 139361631;
          int i = ((j % 1461) / 4) * 5 + 308;
          juDay = (i % 153) / 5 + 1;
          juMonth = ((i / 153) % 12) + 1;
          juYear = j / 1461 - 100100 + (8 - juMonth) / 6;
      }
  
      /**
       * gergorianDateToJDN: Calculates the julian day number (JDN) from Gregorian
       * calendar dates. This integer number corresponds to the noon of the date
       * (i.e. 12 hours of Universal Time). This method was tested to be good
       * (valid) since 1 March, -100100 (of both calendars) up to a few millions
       * (10^6) years into the future. The algorithm is based on D.A.Hatcher,
       * Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by K.M. Borkowski,
       * Post.Astron. 25(1987), 275-279.
       *
       * @param year  int
       * @param month int
       * @param day   int
       * @return int
       */
      private int gregorianDateToJDN(int year, int month, int day) {
          int jdn = (year + (month - 8) / 6 + 100100) * 1461 / 4
                  + (153 * ((month + 9) % 12) + 2) / 5 + day - 34840408;
          jdn = jdn - (year + 100100 + (month - 8) / 6) / 100 * 3 / 4 + 752;
          return (jdn);
      }
  
      public static boolean isLeapYear(int year) {
          double a = 0.025;
          int b = 266;
          double leapDays0;
          double leapDays1;
          if (year > 0) {
              leapDays0 = ((year + 38) % 2820) * 0.24219 + a;
              leapDays1 = ((year + 39) % 2820) * 0.24219 + a;
          } else if (year < 0) {
              leapDays0 = ((year + 39) % 2820) * 0.24219 + a;
              leapDays1 = ((year + 40) % 2820) * 0.24219 + a;
          } else
              return false;
  
          int frac0 = (int) ((leapDays0 - (int) (leapDays0)) * 1000);
          int frac1 = (int) ((leapDays1 - (int) (leapDays1)) * 1000);
  
          return frac0 <= b && frac1 > b;
      }
  
      /**
       * JDNToGregorian: Calculates Gregorian calendar dates from the julian day
       * number (JDN) for the period since JDN=-34839655 (i.e. the year -100100 of
       * both calendars) to some millions (10^6) years ahead of the present. The
       * algorithm is based on D.A. Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55
       * slightly modified by K.M. Borkowski, Post.Astron. 25(1987), 275-279).
       */
      private void JDNToGregorian() {
          int j = 4 * JDN + 139361631;
          j = j + (((((4 * JDN + 183187720) / 146097) * 3) / 4) * 4 - 3908);
          int i = ((j % 1461) / 4) * 5 + 308;
          gDay = (i % 153) / 5 + 1;
          gMonth = ((i / 153) % 12) + 1;
          gYear = j / 1461 - 100100 + (8 - gMonth) / 6;
      }
  
      private int irYear; // Year part of a Iranian date
      private int irMonth; // Month part of a Iranian date
      private int irDay; // Day part of a Iranian date
      private int gYear; // Year part of a Gregorian date
      private int gMonth; // Month part of a Gregorian date
      private int gDay; // Day part of a Gregorian date
      private int juYear; // Year part of a Julian date
      private int juMonth; // Month part of a Julian date
      private int juDay; // Day part of a Julian date
      private int leap; // Number of years since the last leap year (0 to 4)
      private int JDN; // Julian Day Number
      private int march; // The march day of Farvardin the first (First day of
      // jaYear)
  }
  