title: Accurately calculate moon phases
body: <p>For a new project I like to calculate the moon phases. So far I haven't seen any code that does that. I don't want to rely on online-services for this.</p>
  
  <p>I have tried some functions, but they are not 100% reliable. Functions I have tried:</p>
  
  <pre><code>NSInteger r = iYear % 100;
  
      r %= 19;
      if (r&gt;9){ r -= 19;}
      r = ((r * 11) % 30) + iMonth + iDay;
      if (iMonth&lt;3){r += 2;}
      r -= ((iYear&lt;2000) ? 4 : 8.3);
      r = floor(r+0.5);
  </code></pre>
  
  <p>other one:</p>
  
  <pre><code>float n = floor(12.37 * (iYear -1900 + ((1.0 * iMonth - 0.5)/12.0)));
      float RAD = 3.14159265/180.0;
      float t = n / 1236.85;
      float t2 = t * t;
      float as = 359.2242 + 29.105356 * n;
      float am = 306.0253 + 385.816918 * n + 0.010730 * t2;
      float xtra = 0.75933 + 1.53058868 * n + ((1.178e-4) - (1.55e-7) * t) * t2;
      xtra = xtra + (0.1734 - 3.93e-4 * t) * sin(RAD * as) - 0.4068 * sin(RAD * am);
      float i = (xtra &gt; 0.0 ? floor(xtra) :  ceil(xtra - 1.0));
      float j1 = [self julday:iYear iMonth:iMonth iDay:iDay];
      float jd = (2415020 + 28 * n) + i;
      jd = fmodf((j1-jd + 30), 30);
  </code></pre>
  
  <p>and last one</p>
  
  <pre><code>        NSInteger thisJD = [self julday:iYear iMonth:iMonth iDay:iDay];
      float degToRad = 3.14159265 / 180;
      float K0, T, T2, T3, J0, F0, M0, M1, B1, oldJ = 0.0;
      K0 = floor((iYear-1900)*12.3685);
      T = (iYear-1899.5) / 100;
      T2 = T*T; T3 = T*T*T;
      J0 = 2415020 + 29*K0;
      F0 = 0.0001178*T2 - 0.000000155*T3 + (0.75933 + 0.53058868*K0) - (0.000837*T + 0.000335*T2);
      M0 = 360*[self getFrac:((K0*0.08084821133)) + 359.2242 - 0.0000333*T2 - 0.00000347*T3];
      M1 = 360*[self getFrac:((K0*0.07171366128)) + 306.0253 + 0.0107306*T2 + 0.00001236*T3];
      B1 = 360*[self getFrac:((K0*0.08519585128)) + 21.2964 - (0.0016528*T2) - (0.00000239*T3)];
      NSInteger phase = 0;
      NSInteger jday = 0;
      while (jday &lt; thisJD) {
          float F = F0 + 1.530588*phase;
          float M5 = (M0 + phase*29.10535608)*degToRad;
          float M6 = (M1 + phase*385.81691806)*degToRad;
          float B6 = (B1 + phase*390.67050646)*degToRad;
          F -= 0.4068*sin(M6) + (0.1734 - 0.000393*T)*sin(M5);
          F += 0.0161*sin(2*M6) + 0.0104*sin(2*B6);
          F -= 0.0074*sin(M5 - M6) - 0.0051*sin(M5 + M6);
          F += 0.0021*sin(2*M5) + 0.0010*sin(2*B6-M6);
          F += 0.5 / 1440; 
          oldJ=jday;
          jday = J0 + 28*phase + floor(F);
          phase++;
      }
      float jd = fmodf((thisJD-oldJ), 30);
  </code></pre>
  
  <p>All are working more and less, but none is really giving the correct dates of full moon for 2017 and 2018.</p>
  
  <p>Does anyone have a function that will calculate the moon phases correctly - also based on time zone?</p>
  
  <p>EDIT:
  I only want the function for the Moonphases. SwiftAA offers a lot more and only produces not needed overhead in the app.</p>