Android examples for java.util:Day
Returns whether input date is the first day of Lunar year or not.
/*/*from ww w .j ava 2s.c om*/ * Copyright (C) 2011 Nguyen Hoang Ton, a.k.a Ton Nguyen - tonng86@gmail.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import java.util.Calendar; import android.util.Log; public class Main{ private static final String TAG = "LunarCalendarUtil"; private static final boolean DEBUG = false; private static final double PI = Math.PI; private static final double LOCAL_TIMEZONE = 7.0; /** * Returns whether input date is the first day of Lunar year or not. * @param today Input date to check. * @return <code>true</code> if input date was the first day of Lunar year, otherwise <code>false</code>. */ public static boolean isFirstDayOfLunarYear(Calendar today) { if (DEBUG) Log.d(TAG, "checking if " + today.get(Calendar.DAY_OF_MONTH) + "/" + today.get(Calendar.MONTH) + 1 + "/" + today.get(Calendar.YEAR) + " is FirstDayOfLunarYear"); int[] value = LunarCalendarUtil.Solar2Lunar( today.get(Calendar.DAY_OF_MONTH), today.get(Calendar.MONTH) + 1, today.get(Calendar.YEAR)); if (DEBUG) Log.d(TAG, "Lunar date: " + value[0] + "/" + value[1] + "/" + value[2]); return (value != null && value[0] == 1 && value[1] == 1); } /** * Convert Solar date to Lunar date. * @param D The value used to set the DAY_OF_MONTH calendar field. * @param M The value used to set the MONTH calendar field. Month value is 1-based. e.g., 1 for January. * @param Y The value used to set the YEAR calendar field. * @return An array of integer: [dd],[mm],[yy],[leap] (leap year = 1) */ public static int[] Solar2Lunar(int D, int M, int Y) { int yy = Y; int[][] ly = LunarYear(Y); // Please cache the result of this computation for later use!!! int[] month11 = ly[ly.length - 1]; double jdToday = LocalToJD(D, M, Y); double jdMonth11 = LocalToJD(month11[0], month11[1], month11[2]); if (jdToday >= jdMonth11) { ly = LunarYear(Y + 1); yy = Y + 1; } int i = ly.length - 1; while (jdToday < LocalToJD(ly[i][0], ly[i][1], ly[i][2])) { i--; } int dd = (int) (jdToday - LocalToJD(ly[i][0], ly[i][1], ly[i][2])) + 1; int mm = ly[i][3]; if (mm >= 11) { yy--; } return new int[] { dd, mm, yy, ly[i][4] }; } private static int[][] LunarYear(int Y) { int[][] ret = null; int[] month11A = LunarMonth11(Y - 1); double jdMonth11A = LocalToJD(month11A[0], month11A[1], month11A[2]); int k = (int) Math .floor(0.5 + (jdMonth11A - 2415021.076998695) / 29.530588853); int[] month11B = LunarMonth11(Y); double off = LocalToJD(month11B[0], month11B[1], month11B[2]) - jdMonth11A; boolean leap = off > 365.0; if (!leap) { ret = new int[13][5]; } else { ret = new int[14][5]; } ret[0] = new int[] { month11A[0], month11A[1], month11A[2], 0, 0 }; ret[ret.length - 1] = new int[] { month11B[0], month11B[1], month11B[2], 0, 0 }; for (int i = 1; i < ret.length - 1; i++) { double nm = NewMoon(k + i); int[] a = LocalFromJD(nm); ret[i] = new int[] { a[0], a[1], a[2], 0, 0 }; } for (int i = 0; i < ret.length; i++) { ret[i][3] = MOD(i + 11, 12); } if (leap) { initLeapYear(ret); } return ret; } private static double LocalToJD(int D, int M, int Y) { return UniversalToJD(D, M, Y) - LOCAL_TIMEZONE / 24.0; } private static int[] LunarMonth11(int Y) { double off = LocalToJD(31, 12, Y) - 2415021.076998695; int k = INT(off / 29.530588853); double jd = NewMoon(k); int[] ret = LocalFromJD(jd); double sunLong = SunLongitude(LocalToJD(ret[0], ret[1], ret[2])); // sun longitude at local midnight if (sunLong > 3 * PI / 2) { jd = NewMoon(k - 1); } return LocalFromJD(jd); } private static double NewMoon(int k) { double T = k / 1236.85; // Time in Julian centuries from 1900 January 0.5 double T2 = T * T; double T3 = T2 * T; double dr = PI / 180; double Jd1 = 2415020.75933 + 29.53058868 * k + 0.0001178 * T2 - 0.000000155 * T3; Jd1 = Jd1 + 0.00033 * Math.sin((166.56 + 132.87 * T - 0.009173 * T2) * dr); // Mean new moon double M = 359.2242 + 29.10535608 * k - 0.0000333 * T2 - 0.00000347 * T3; // Sun's mean anomaly double Mpr = 306.0253 + 385.81691806 * k + 0.0107306 * T2 + 0.00001236 * T3; // Moon's mean anomaly double F = 21.2964 + 390.67050646 * k - 0.0016528 * T2 - 0.00000239 * T3; // Moon's argument of latitude double C1 = (0.1734 - 0.000393 * T) * Math.sin(M * dr) + 0.0021 * Math.sin(2 * dr * M); C1 = C1 - 0.4068 * Math.sin(Mpr * dr) + 0.0161 * Math.sin(dr * 2 * Mpr); C1 = C1 - 0.0004 * Math.sin(dr * 3 * Mpr); C1 = C1 + 0.0104 * Math.sin(dr * 2 * F) - 0.0051 * Math.sin(dr * (M + Mpr)); C1 = C1 - 0.0074 * Math.sin(dr * (M - Mpr)) + 0.0004 * Math.sin(dr * (2 * F + M)); C1 = C1 - 0.0004 * Math.sin(dr * (2 * F - M)) - 0.0006 * Math.sin(dr * (2 * F + Mpr)); C1 = C1 + 0.0010 * Math.sin(dr * (2 * F - Mpr)) + 0.0005 * Math.sin(dr * (2 * Mpr + M)); double deltat; if (T < -11) { deltat = 0.001 + 0.000839 * T + 0.0002261 * T2 - 0.00000845 * T3 - 0.000000081 * T * T3; } else { deltat = -0.000278 + 0.000265 * T + 0.000262 * T2; } ; double JdNew = Jd1 + C1 - deltat; return JdNew; } private static int[] LocalFromJD(double JD) { return UniversalFromJD(JD + LOCAL_TIMEZONE / 24.0); } private static int MOD(int x, int y) { int z = x - (int) (y * Math.floor(((double) x / y))); if (z == 0) { z = y; } return z; } private static void initLeapYear(int[][] ret) { double[] sunLongitudes = new double[ret.length]; for (int i = 0; i < ret.length; i++) { int[] a = ret[i]; double jdAtMonthBegin = LocalToJD(a[0], a[1], a[2]); sunLongitudes[i] = SunLongitude(jdAtMonthBegin); } boolean found = false; for (int i = 0; i < ret.length; i++) { if (found) { ret[i][3] = MOD(i + 10, 12); continue; } double sl1 = sunLongitudes[i]; double sl2 = sunLongitudes[i + 1]; boolean hasMajorTerm = Math.floor(sl1 / PI * 6) != Math .floor(sl2 / PI * 6); if (!hasMajorTerm) { found = true; ret[i][4] = 1; ret[i][3] = MOD(i + 10, 12); } } } private static double UniversalToJD(int D, int M, int Y) { double JD; if (Y > 1582 || (Y == 1582 && M > 10) || (Y == 1582 && M == 10 && D > 14)) { JD = 367 * Y - INT(7 * (Y + INT((M + 9) / 12)) / 4) - INT(3 * (INT((Y + (M - 9) / 7) / 100) + 1) / 4) + INT(275 * M / 9) + D + 1721028.5; } else { JD = 367 * Y - INT(7 * (Y + 5001 + INT((M - 9) / 7)) / 4) + INT(275 * M / 9) + D + 1729776.5; } return JD; } }