Jitl.java :  » GPS » adhanalarm » net » sourceforge » jitl » Android Open Source

Android Open Source » GPS » adhanalarm 
adhanalarm » net » sourceforge » jitl » Jitl.java
package net.sourceforge.jitl;

import java.util.GregorianCalendar;

import net.sourceforge.jitl.astro.Astro;
import net.sourceforge.jitl.astro.AstroLib;
import net.sourceforge.jitl.astro.SimpleDate;
import net.sourceforge.jitl.astro.Dms;
import net.sourceforge.jitl.astro.Location;
import net.sourceforge.jitl.astro.Utils;

/**
 * This the main class of the JITL library. You can use static methods
 * to do qibla calculation but you will need to create a Jitl instance
 * to calculate prayer times for a specific location, using a specified method.
 * 
 */
public class Jitl {
  
  /**
   * minor version of jitl
   */
  static final int VERSION_MINOR = 0;
  
  /**
   * major version of jitl
   */
  static final int VERSION_MAJOR = 1;
  
  
  /* This is Used for storing some formulae results between
   * multiple getPrayerTimes calls*/
  private Astro astroCache = new Astro();
  
  
  private Location loc;
  
  private Method method;

  
  /**
   * Creates the jitl main class
   * @param loc the location
   * @param method the method used in the calculation. You can use
   *  predefined methods for example <code>Method.MUSLIM_LEAGUE</code> or creates
   *  your own personalized method.
   */
  public Jitl(Location loc, Method method) {
    this.loc = loc;
    this.method = method;
  }
  
  /**
   * changes the location
   * @param loc the new location
   */
  public void setLocation(Location loc) {
    this.loc = loc;
  }
  
  /**
   * changes the method
   * @param method the new method
   */
  public void setMethod(Method method) {
    this.method = method;
  }
    
  /**
   * generates prayer times
   * @param date the date of prayers
   * @return a DayPrayers object containing time of different
   * prayers 
   */
  public DayPrayers getPrayerTimes(final GregorianCalendar date) {
    return getPrayerTimes(new SimpleDate(date));
  }
  
  /**
   * Generate prayer times from a GregorianCalendar date
   * @param date the date of prayers
   * @param pt instance of a DayPrayers object
   */
  public void getPrayerTimes(final GregorianCalendar date, DayPrayers pt) {
    getPrayerTimes(new SimpleDate(date), pt);
  }
  
  /**
   * Create a DayPrayers instance and fill it with prayer times
   * @param date SimpleDate object
   * @return a DayPrayers instance containing prayer times
   */
  public DayPrayers getPrayerTimes(final SimpleDate date) {
    DayPrayers dp = new DayPrayers();
    getPrayerTimes(date, dp);
    
    return dp;
  }
  
  /**
   * Generate prayer times from a SimpleDate date
   * @param date SimpleDate object
   * @param pt instance of a DayPrayers object
   */
  public void getPrayerTimes(final SimpleDate date, DayPrayers pt) {
    DayCouple dc;
    
    dc = getDayInfo(date, loc.getGmtDiff());
    getPrayerTimesByDay(dc, pt, PrayerTime.FAJR);
  }
  
  void getPrayerTimesByDay(DayCouple dc, DayPrayers pt, PrayerTime type) {
    getPrayerTimesByDay(method, dc, pt, type);
  }
  
  void getPrayerTimesByDay(Method method, DayCouple dc, DayPrayers pt,
      PrayerTime type) {
    int i, invalid;
    double th, sh, mg, fj, is, ar;
    double lat, lon, dec;
    double tempPrayer[] = new double[6];
    Astro tAstro = new Astro();
    
    lat = loc.getDegreeLat();
    lon = loc.getDegreeLong();
    invalid = 0;
    
    /* Start by filling the tAstro structure with the appropriate astronomical
     * values for this day. We also pass the cache structure to update and check
     * if the actual values are already available. */
    AstroLib
    .getAstroValuesByDay(dc.getJulianDay(), loc, astroCache, tAstro);
    dec = Utils.DEG_TO_RAD(tAstro.getDec()[1]);
    
    /* Get Prayer Times formulae results for this day of year and this
     * location. The results are NOT the actual prayer times */
    fj = getFajIsh(lat, dec, method.getFajrAng());
    sh = getShoMag(loc, tAstro, PrayerTime.SHUROOQ);
    th = getThuhr(lon, tAstro);
    ar = getAssr(lat, dec, method.getMathhab());
    mg = getShoMag(loc, tAstro, PrayerTime.MAGHRIB);
    is = getFajIsh(lat, dec, method.getIshaaAng());
    
    /* Calculate all prayer times as Base-10 numbers in Normal circumstances */
    /* Fajr */
    if (fj == 99) {
      tempPrayer[0] = 99;
      invalid = 1;
    } else {
      tempPrayer[0] = th - fj;
    }
    
    if (sh == 99) {
      invalid = 1;
    }
    
    tempPrayer[1] = sh;
    tempPrayer[2] = th;
    tempPrayer[3] = th + ar;
    tempPrayer[4] = mg;
    
    if (mg == 99) {
      invalid = 1;
    }
    
    /* Ishaa */
    if (is == 99) {
      tempPrayer[5] = 99;
      invalid = 1;
    } else {
      tempPrayer[5] = th + is;
    }
    
    /* Calculate all prayer times as Base-10 numbers in Extreme Latitudes (if
     * needed) */
    
    /* Reset status of extreme switches */
    pt.setAllExtreme(false);
    
    if ((method.getExtremeLatitude() != ExtremeLatitude.NONE_EX)
        && !((method.getExtremeLatitude() == ExtremeLatitude.GOOD_INVALID
            || method.getExtremeLatitude() == ExtremeLatitude.LAT_INVALID
            || method.getExtremeLatitude() == ExtremeLatitude.SEVEN_NIGHT_INVALID
            || method.getExtremeLatitude() == ExtremeLatitude.SEVEN_DAY_INVALID || method
            .getExtremeLatitude() == ExtremeLatitude.HALF_INVALID) && (invalid == 0))) {
      double exdecPrev, exdecNext;
      double exTh = 99, exFj = 99, exIs = 99, exAr = 99, exSh = 99, exMg = 99;
      //exIm=99
      
      double portion = 0;
      double nGoodDay = 0;
      int exinterval = 0;
      Location exLoc = loc.copy();
      Astro exAstroPrev;
      Astro exAstroNext;
      ExtremeLatitude ext = method.getExtremeLatitude();
      
      /* Nearest Latitude (Method.nearestLat) */
      if(ext == ExtremeLatitude.LAT_ALL || ext == ExtremeLatitude.LAT_ALWAYS || ext == ExtremeLatitude.LAT_INVALID) {
      /*
      case LAT_ALL:
      case LAT_ALWAYS:
      case LAT_INVALID:
      */
        
        /* xxxthamer: we cannot compute this when interval is set because
         * angle==0 . Only the if-invalid methods would work */
        exLoc.setDegreeLat(method.getNearestLat());
        exFj = getFajIsh(method.getNearestLat(), dec, method
            .getFajrAng());
        //exIm = getFajIsh(method.getNearestLat(), dec, method.getImsaakAng());
        exIs = getFajIsh(method.getNearestLat(), dec, method
            .getIshaaAng());
        exAr = getAssr(method.getNearestLat(), dec, method.getMathhab());
        exSh = getShoMag(exLoc, tAstro, PrayerTime.SHUROOQ);
        exMg = getShoMag(exLoc, tAstro, PrayerTime.MAGHRIB);
        
        //switch (ext) {
        if(ext == ExtremeLatitude.LAT_ALL) {
          //case LAT_ALL:      
          tempPrayer[0] = th - exFj;
          tempPrayer[1] = exSh;
          tempPrayer[3] = th + exAr;
          tempPrayer[4] = exMg;
          tempPrayer[5] = th + exIs;
          pt.setAllExtreme(true);
        } else if (ext == ExtremeLatitude.LAT_ALWAYS) {
          tempPrayer[0] = th - exFj;
          tempPrayer[5] = th + exIs;
          pt.fajr().setExtreme(true);
          pt.ishaa().setExtreme(true);
        } else if (ext == ExtremeLatitude.LAT_INVALID) {          
          if (tempPrayer[0] == 99) {
            tempPrayer[0] = th - exFj;
            pt.fajr().setExtreme(true);
          }
          if (tempPrayer[5] == 99) {
            tempPrayer[5] = th + exIs;
            pt.ishaa().setExtreme(true);
          }
        }
        
      } else if (ext == ExtremeLatitude.GOOD_ALL || ext == ExtremeLatitude.GOOD_INVALID 
          || ext == ExtremeLatitude.GOOD_DIF) {  
        /* Nearest Good Day */        
        exAstroPrev = astroCache;
        exAstroNext = astroCache;
        
        /* Start by getting last or next nearest Good Day */
        for (i = 0; i <= dc.getLastDay(); i++) {
          
          /* last closest day */
          nGoodDay = dc.getJulianDay() - i;
          AstroLib.getAstroValuesByDay(nGoodDay, loc, exAstroPrev,
              tAstro);
          exdecPrev = Utils.DEG_TO_RAD(tAstro.getDec()[1]);
          exFj = getFajIsh(lat, exdecPrev, method.getFajrAng());
          
          if (exFj != 99) {
            exIs = getFajIsh(lat, exdecPrev, method.getIshaaAng());
            if (exIs != 99) {
              exTh = getThuhr(lon, tAstro);
              exSh = getShoMag(loc, tAstro, PrayerTime.SHUROOQ);
              exMg = getShoMag(loc, tAstro, PrayerTime.MAGHRIB);
              exAr = getAssr(lat, exdecPrev, method.getMathhab());
              break;
            }
          }
          
          /* Next closest day */
          nGoodDay = dc.getJulianDay() + i;
          AstroLib.getAstroValuesByDay(nGoodDay, loc, exAstroNext,
              tAstro);
          exdecNext = Utils.DEG_TO_RAD(tAstro.getDec()[1]);
          exFj = getFajIsh(lat, exdecNext, method.getFajrAng());
          if (exFj != 99) {
            exIs = getFajIsh(lat, exdecNext, method.getIshaaAng());
            if (exIs != 99) {
              exTh = getThuhr(lon, tAstro);
              exSh = getShoMag(loc, tAstro, PrayerTime.SHUROOQ);
              exMg = getShoMag(loc, tAstro, PrayerTime.MAGHRIB);
              exAr = getAssr(lat, exdecNext, method.getMathhab());
              break;
            }
          }
        }
        
        if(ext == ExtremeLatitude.GOOD_ALL) {
          tempPrayer[0] = exTh - exFj;
          tempPrayer[1] = exSh;
          tempPrayer[2] = exTh;
          tempPrayer[3] = exTh + exAr;
          tempPrayer[4] = exMg;
          tempPrayer[5] = exTh + exIs;
          pt.setAllExtreme(true);
          
        } else if (ext == ExtremeLatitude.GOOD_INVALID) {
          if (tempPrayer[0] == 99) {
            tempPrayer[0] = exTh - exFj;
            pt.fajr().setExtreme(true);
          }
          if (tempPrayer[5] == 99) {
            tempPrayer[5] = exTh + exIs;
            pt.ishaa().setExtreme(true);
          }
        } else if (ext == ExtremeLatitude.GOOD_DIF) {          
          /* Nearest Good Day: Different good days for Fajr and Ishaa (Not
           * implemented) */
        }
      } else if (ext == ExtremeLatitude.SEVEN_NIGHT_ALWAYS || ext == ExtremeLatitude.SEVEN_NIGHT_INVALID
          || ext == ExtremeLatitude.SEVEN_DAY_ALWAYS || ext == ExtremeLatitude.SEVEN_DAY_INVALID
          || ext == ExtremeLatitude.HALF_ALWAYS || ext == ExtremeLatitude.HALF_INVALID) {
        
        
        /* xxxthamer: For clarity, we may need to move the HALF_* methods
         * into their own separate case statement. */
        
        if(ext == ExtremeLatitude.SEVEN_NIGHT_ALWAYS || ext == ExtremeLatitude.SEVEN_NIGHT_INVALID) {
          portion = (24 - (tempPrayer[4] - tempPrayer[1]))
          * (1 / 7.0);
        } else if (ext == ExtremeLatitude.SEVEN_DAY_ALWAYS || ext == ExtremeLatitude.SEVEN_DAY_INVALID) {
          portion = (tempPrayer[4] - tempPrayer[1]) * (1 / 7.0);
        } else if (ext == ExtremeLatitude.HALF_ALWAYS || ext == ExtremeLatitude.HALF_INVALID) {
          portion = (24 - tempPrayer[4] - tempPrayer[1]) * (1 / 2.0);
        }
        
        if (method.getExtremeLatitude() == ExtremeLatitude.SEVEN_NIGHT_INVALID
            || method.getExtremeLatitude() == ExtremeLatitude.SEVEN_DAY_INVALID
            || method.getExtremeLatitude() == ExtremeLatitude.HALF_INVALID) {
          if (tempPrayer[0] == 99) {
            if (method.getExtremeLatitude() == ExtremeLatitude.HALF_INVALID)
              tempPrayer[0] = portion
              - (method.getFajrInv() / 60.0);
            else
              tempPrayer[0] = tempPrayer[1] - portion;
            pt.fajr().setExtreme(true);
          }
          if (tempPrayer[5] == 99) {
            if (method.getExtremeLatitude() == ExtremeLatitude.HALF_INVALID)
              tempPrayer[5] = portion
              + (method.getIshaaInv() / 60.0);
            else
              tempPrayer[5] = tempPrayer[4] + portion;
            pt.ishaa().setExtreme(true);
          }
        } else { /* for the always methods */
          
          if (method.getExtremeLatitude() == ExtremeLatitude.HALF_ALWAYS) {
            tempPrayer[0] = portion - (method.getFajrInv() / 60.0);
            tempPrayer[5] = portion + (method.getIshaaInv() / 60.0);
          }
          
          else {
            tempPrayer[0] = tempPrayer[1] - portion;
            tempPrayer[5] = tempPrayer[4] + portion;
          }
          pt.fajr().setExtreme(true);
          pt.ishaa().setExtreme(true);
        }
      } else if (ext == ExtremeLatitude.MIN_ALWAYS) {  
        /* Do nothing here because this is implemented through fajrInv and
         * ishaaInv structure members */
        tempPrayer[0] = tempPrayer[1];
        tempPrayer[5] = tempPrayer[4];
        pt.fajr().setExtreme(true);
        pt.ishaa().setExtreme(true);
      } else if (ext == ExtremeLatitude.MIN_INVALID) {        
        if (tempPrayer[0] == 99) {
          exinterval = (int) ((double) method.getFajrInv() / 60.0);
          tempPrayer[0] = tempPrayer[1] - exinterval;
          pt.fajr().setExtreme(true);
        }
        if (tempPrayer[5] == 99) {
          exinterval = (int) ((double) method.getIshaaInv() / 60.0);
          tempPrayer[5] = tempPrayer[4] + exinterval;
          pt.ishaa().setExtreme(true);
        }
      } /* end switch */
    } /* end extreme */
    
    /* Apply intervals if set */
    if (method.getExtremeLatitude() != ExtremeLatitude.MIN_INVALID
        && method.getExtremeLatitude() != ExtremeLatitude.HALF_INVALID
        && method.getExtremeLatitude() != ExtremeLatitude.HALF_ALWAYS) {
      if (method.getFajrInv() != 0)
        tempPrayer[0] = tempPrayer[1] - (method.getFajrInv() / 60.0);
      if (method.getIshaaInv() != 0)
        tempPrayer[5] = tempPrayer[4] + (method.getIshaaInv() / 60.0);
    }
    
    /* Final Step: Fill the Prayer array by doing decimal degree to
     * Prayer structure conversion*/
    if (type == PrayerTime.IMSAAK || type == PrayerTime.NEXTFAJR) {
      base6hm(tempPrayer[0], method, pt.fajr(), type);
    } else {
      Prayer[] pArray = pt.getPrayers();
      PrayerTime[] timeArray = { PrayerTime.FAJR, PrayerTime.SHUROOQ,
          PrayerTime.THUHR, PrayerTime.ASSR, PrayerTime.MAGHRIB,
          PrayerTime.ISHAA };
      
      for (i = 0; i < 6; i++) {
        base6hm(tempPrayer[i], method, pArray[i], timeArray[i]);
      }
    }
    
  }
  
  void base6hm(double bs, Method method, Prayer pt, PrayerTime type) {
    double min, sec;
    
    if (bs == 99) {
      pt.setHour(99);
      pt.setMinute(99);
      pt.setSecond(0);
      return;
    }
    
    /* Add offsets */
    if (method.getOffset()) {
      if (type == PrayerTime.IMSAAK || type == PrayerTime.NEXTFAJR)
        bs += (method.getFajrOffset() / 60.0);
      else
        bs += (method.getOffset(type) / 60.0);
    }
    
    /* Fix after minus offsets before midnight */
    if (bs < 0) {
      while (bs < 0)
        bs = 24 + bs;
    }
    
    min = (bs - Math.floor(bs)) * 60;
    sec = (min - Math.floor(min)) * 60;
    
    /* Add rounding minutes */
    if (method.getRound() == Rounding.NORMAL) {
      if (sec >= Utils.DEFAULT_ROUND_SEC)
        bs += 1 / 60.0;
      /* compute again */
      min = (bs - Math.floor(bs)) * 60;
      sec = 0;
      
    } else if (method.getRound() == Rounding.SPECIAL || method.getRound() == Rounding.AGRESSIVE) {
      if (type == PrayerTime.FAJR || type == PrayerTime.THUHR
          || type == PrayerTime.ASSR || type == PrayerTime.MAGHRIB
          || type == PrayerTime.ISHAA || type == PrayerTime.NEXTFAJR) {
        if (method.getRound() == Rounding.SPECIAL) {
          if (sec >= Utils.DEFAULT_ROUND_SEC) {
            bs += 1 / 60.0;
            min = (bs - Math.floor(bs)) * 60;
          }
        } else if (method.getRound() == Rounding.AGRESSIVE) {
          if (sec >= Utils.AGGRESSIVE_ROUND_SEC) {
            bs += 1 / 60.0;
            min = (bs - Math.floor(bs)) * 60;
          }
        }
        sec = 0;
      } else {
        //case Prayer.SHUROOQ:
        //case Prayer.IMSAAK:
        sec = 0;
      }
    }
    
    /* Add daylight saving time and fix after midnight times */
    bs += loc.getDst();
    if (bs >= 24) {
      bs = Math.IEEEremainder(bs, 24);
    }
    
    pt.setHour((int) bs);
    pt.setMinute((int) min);
    pt.setSecond((int) sec);
    
  }
  
  /**
   * Generate imsaak time
   * @param date GregorianCalendar date
   * @return imsaak time
   */
  public Prayer getImsaak(GregorianCalendar date) {
    return getImsaak(new SimpleDate(date));
  }
  
  /**
   * Generate imsaak time
   * @param date SimpleDate date
   * @return imsaak time
   */
  public Prayer getImsaak(SimpleDate date) {
    
    Method tmpConf;
    DayCouple dc;
    DayPrayers temp = new DayPrayers();
    
    tmpConf = method.copy();
    
    if (method.getFajrInv() != 0) {
      if (method.getImsaakInv() == 0)
        tmpConf
        .setFajrInv((int) (tmpConf.getFajrInv() + Utils.DEF_IMSAAK_INTERVAL));
      else
        tmpConf.setFajrInv((int) (tmpConf.getFajrInv() + method
            .getImsaakInv()));
      
    } else if (method.getImsaakInv() != 0) {
      /* use an inv even if al-Fajr is computed (Indonesia?) */
      tmpConf.setFajrOffset(tmpConf.getFajrOffset()
          + (method.getImsaakInv() * -1));
      tmpConf.setOffset(true);
    } else {
      tmpConf.setFajrAng(tmpConf.getFajrAng() + method.getImsaakAng());
    }
    
    dc = getDayInfo(date, loc.getGmtDiff());
    getPrayerTimesByDay(tmpConf, dc, temp, PrayerTime.IMSAAK);
    
    /* xxxthamer: We probably need to check whether it's possible to compute
     * Imsaak normally for some extreme methods first */
    /* In case of an extreme Fajr time calculation use intervals for Imsaak and
     * compute again */
    if (temp.fajr().isExtreme()) {
      tmpConf = method.copy();
      if (method.getImsaakInv() == 0) {
        tmpConf.setFajrOffset(tmpConf.getFajrOffset()
            - Utils.DEF_IMSAAK_INTERVAL);
        tmpConf.setOffset(true);
      } else {
        tmpConf.setFajrOffset(tmpConf.getFajrOffset()
            - method.getImsaakInv());
        tmpConf.setOffset(true);
      }
      getPrayerTimesByDay(tmpConf, dc, temp, PrayerTime.IMSAAK);
    }
    
    return temp.fajr();
  }
  
  /**
   * Generate next day imsaak time
   * @param date GregorianCalendar date
   * @return next day imsaak time
   */
  public Prayer getNextDayImsaak(GregorianCalendar date) {
    return getNextDayImsaak(new SimpleDate(date));
  }
  
  /**
   * Generate next day imsaak time
   * @param date SimpleDate date
   * @return next day imsaak time
   */
  public Prayer getNextDayImsaak(SimpleDate date) {
    /* Copy the date structure and increment for next day.*/
    SimpleDate tempd = date.copy();
    tempd.setDay(tempd.getDay() + 1);
    
    return getImsaak(tempd);
  }
  
  /**
   * Generate next day fajr time
   * @param date GregorianCalendar date
   * @return next day fajr time
   */
  public Prayer getNextDayFajr(GregorianCalendar date) {
    return getNextDayFajr(new SimpleDate(date));
  }
  
  /**
   * Generate next day fajr time
   * @param date SimpleDate date
   * @return next day fajr time
   */
  public Prayer getNextDayFajr(SimpleDate date) {
    
    DayPrayers temp = new DayPrayers();
    DayCouple dc;
    
    dc = getDayInfo(date, loc.getGmtDiff());
    dc.setJulianDay(dc.getJulianDay() + 1);
    getPrayerTimesByDay(dc, temp, PrayerTime.NEXTFAJR);
    return temp.fajr().copy();
  }
  
  static double getFajIsh(double Lat, double dec, double Ang) {
    
    double part1 = Math.cos(Utils.DEG_TO_RAD(Lat)) * Math.cos(dec);
    double part2 = -Math.sin(Utils.DEG_TO_RAD(Ang))
    - Math.sin(Utils.DEG_TO_RAD(Lat)) * Math.sin(dec);
    
    double part3 = part2 / part1;
    if (part3 <= Utils.INVALID_TRIGGER) {
      return 99;
    }
    
    return Utils.DEG_TO_10_BASE * Utils.RAD_TO_DEG(Math.acos(part3));
    
  }
  
  static double getShoMag(Location loc, Astro astro, PrayerTime type) {
    double lhour, M, sidG, ra0 = astro.getRa()[0], ra2 = astro.getRa()[2];
    double A, B, H, sunAlt, R, tH;
    
    double part1 = Math.sin(Utils.DEG_TO_RAD(loc.getDegreeLat()))
    * Math.sin(Utils.DEG_TO_RAD(astro.getDec()[1]));
    double part2a = Utils.CENTER_OF_SUN_ANGLE;
    double part2 = Math.sin(Utils.DEG_TO_RAD(part2a)) - part1;
    double part3 = Math.cos(Utils.DEG_TO_RAD(loc.getDegreeLat()))
    * Math.cos(Utils.DEG_TO_RAD(astro.getDec()[1]));
    
    double part4 = part2 / part3;
    
    if (part4 <= -1 || part4 >= 1)
      return 99;
    
    lhour = AstroLib.limitAngle180((Utils.RAD_TO_DEG(Math.acos(part4))));
    M = ((astro.getRa()[1] - loc.getDegreeLong() - astro.getSid()[1]) / 360.0);
    
    if (type == PrayerTime.SHUROOQ)
      M = M - (lhour / 360.0);
    if (type == PrayerTime.MAGHRIB)
      M = M + (lhour / 360.0);
    
    M = AstroLib.limitAngle111(M);
    
    sidG = AstroLib.limitAngle(astro.getSid()[1] + 360.985647 * M);
    
    ra0 = astro.getRa()[0];
    ra2 = astro.getRa()[2];
    
    if (astro.getRa()[1] > 350 && astro.getRa()[2] < 10)
      ra2 += 360;
    if (astro.getRa()[0] > 350 && astro.getRa()[1] < 10)
      ra0 = 0;
    
    A = astro.getRa()[1]
                      + (M
                          * ((astro.getRa()[1] - ra0) + (ra2 - astro.getRa()[1]) + ((ra2 - astro
                              .getRa()[1]) - (astro.getRa()[1] - ra0))
                              * M) / 2.0);
    
    B = astro.getDec()[1]
                       + (M
                           * ((astro.getDec()[1] - astro.getDec()[0])
                               + (astro.getDec()[2] - astro.getDec()[1]) + ((astro
                                   .getDec()[2] - astro.getDec()[1]) - (astro
                                       .getDec()[1] - astro.getDec()[0]))
                                       * M) / 2.0);
    
    H = AstroLib.limitAngle180between(sidG + loc.getDegreeLong() - A);
    
    tH = H - Utils.RAD_TO_DEG(astro.getDra()[1]);
    
    sunAlt = Utils.RAD_TO_DEG(Math.asin(Math.sin(Utils.DEG_TO_RAD(loc
        .getDegreeLat()))
        * Math.sin(Utils.DEG_TO_RAD(B))
        + Math.cos(Utils.DEG_TO_RAD(loc.getDegreeLat()))
        * Math.cos(Utils.DEG_TO_RAD(B))
        * Math.cos(Utils.DEG_TO_RAD(tH))));
    
    sunAlt += AstroLib.getRefraction(loc, sunAlt);
    
    R = (M + ((sunAlt - Utils.CENTER_OF_SUN_ANGLE + (Utils.ALTITUDE_REFRACTION * Math
        .pow(loc.getSeaLevel(), 0.5))) / (360.0
            * Math.cos(Utils.DEG_TO_RAD(B))
            * Math.cos(Utils.DEG_TO_RAD(loc.getDegreeLat())) * Math
            .sin(Utils.DEG_TO_RAD(tH)))));
    
    return (R * 24.0);
    
  }
  
  static double getThuhr(double lon, Astro astro) {
    
    double M, sidG;
    double ra0 = astro.getRa()[0], ra2 = astro.getRa()[2];
    double A, H;
    
    M = ((astro.getRa()[1] - lon - astro.getSid()[1]) / 360.0);
    M = AstroLib.limitAngle111(M);
    sidG = astro.getSid()[1] + 360.985647 * M;
    
    if (astro.getRa()[1] > 350 && astro.getRa()[2] < 10)
      ra2 += 360;
    if (astro.getRa()[0] > 350 && astro.getRa()[1] < 10)
      ra0 = 0;
    
    A = astro.getRa()[1]
                      + (M
                          * ((astro.getRa()[1] - ra0) + (ra2 - astro.getRa()[1]) + ((ra2 - astro
                              .getRa()[1]) - (astro.getRa()[1] - ra0))
                              * M) / 2.0);
    
    H = AstroLib.limitAngle180between(sidG + lon - A);
    
    return 24.0 * (M - H / 360.0);
  }
  
  static double getAssr(double Lat, double dec, Mathhab mathhab) {
    double part1, part2, part3, part4, ndec;
    int mathhabValue = (mathhab == Mathhab.SHAAFI ? 1 : 2);
    double rlat = Utils.DEG_TO_RAD(Lat);
    
    /* Reverse if at or near the southern hemisphere - Modified by Imran, copied from libitl-0.7.0 */
    ndec = dec;
    if (Lat < 0.0) {
      ndec = -dec;
    }
    part1 = mathhabValue + Math.tan(rlat - ndec);
    if (part1 < 1.0) {
      part1 = mathhabValue - Math.tan(rlat - ndec);
    }
    
    part2 = (Utils.PI / 2.0) - Math.atan(part1);
    /* Compute the hour angle - Modified by Imran, copied from libitl-0.7.0 */
    part3 = Math.sin(part2) - (Math.sin(rlat) * Math.sin(ndec));
    part4 = (part3 / (Math.cos(rlat) * Math.cos(ndec)));
    
    /*  if (part4 > 1) */
    /*      return 99; */
    
    return Utils.DEG_TO_10_BASE * Utils.RAD_TO_DEG(Math.acos(part4));
  }
  
  static int getDayofYear(int year, int month, int day) {
    int i;
    int isLeap = (((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0)) ? 1
        : 0;
    
    char dayList[][] = {
        { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
        { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
    
    for (i = 1; i < month; i++)
      day += dayList[isLeap][i];
    
    return day;
  }
  
  static DayCouple getDayInfo(SimpleDate date, double gmt) {
    int ld;
    double jd;
    ld = getDayofYear(date.getYear(), 12, 31);
    jd = AstroLib.getJulianDay(date, gmt);
    return new DayCouple(ld, jd);
  }
  
  /* Obtaining the direction of the shortest distance towards Qibla by uMath.sing the
   * great circle formula */
  
  /**
   * generate qibla direction
   * @param loc location where to calculate
   * @return a Dms object containg qibla direction 
   */
  static public Dms getNorthQibla(Location loc) {
    /* xxxthamer: reduce Utils.DEG_TO_RAD usage */
    double num, denom;
    num = Math.sin(Utils.DEG_TO_RAD(loc.getDegreeLong())
        - Utils.DEG_TO_RAD(Utils.KAABA_LONG));
    denom = (Math.cos(Utils.DEG_TO_RAD(loc.getDegreeLat())) * Math
        .tan(Utils.DEG_TO_RAD(Utils.KAABA_LAT)))
        - (Math.sin(Utils.DEG_TO_RAD(loc.getDegreeLat())) * ((Math
            .cos((Utils.DEG_TO_RAD(loc.getDegreeLong()) - Utils
                .DEG_TO_RAD(Utils.KAABA_LONG))))));
    return new Dms(Utils.RAD_TO_DEG(Math.atan2(num, denom)));
    
  }
  
  /**
   * generate qibla direction
   * @return a Dms object containing qibla direction for the current location
   */
  public Dms getNorthQibla() {
    return getNorthQibla(loc);
  }
  
  /**
   *  Major version of Jitl
   * @return Jitl major version
   */
  public static int getMajorVersion() {
    return VERSION_MAJOR;
  }
  
  /**
   *  Minor version of Jitl
   * @return Jitl minor version
   */
  public static int getMinorVersion() {
    return VERSION_MINOR;
  }
  
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.