I want to convert from Gregorian to Hijri(Islamic) date and I need a java class for this converting. I want to give it an Gregorian date in format of "yyyy/mm/dd" as string and it give me the Hijri date in the same format. can anyone help me?
Firstly, separate out the conversion part from the formatting/parsing part. You can deal with those easily later - and there are lots of questions on Stack Overflow about that.
Personally I'd use Joda Time, which typically makes life much simpler. For example:
import org.joda.time.Chronology;
import org.joda.time.LocalDate;
import org.joda.time.chrono.IslamicChronology;
import org.joda.time.chrono.ISOChronology;
public class Test {
public static void main(String[] args) throws Exception {
Chronology iso = ISOChronology.getInstanceUTC();
Chronology hijri = IslamicChronology.getInstanceUTC();
LocalDate todayIso = new LocalDate(2013, 3, 31, iso);
LocalDate todayHijri = new LocalDate(todayIso.toDateTimeAtStartOfDay(),
hijri);
System.out.println(todayHijri); // 1434-05-19
}
}
(It feels like there should be a cleaner way of converting dates between chronologies, but I couldn't find one immediately.)
Java 8 is built-in supporting Hejrah Date
example:
import java.time.*;
import java.time.chrono.HijrahChronology;
Date date = new Date(); // Gregorian date
Calendar cl=Calendar.getInstance();
cl.setTime(date);
HijrahDate islamyDate = HijrahChronology.INSTANCE.date(LocalDate.of(cl.get(Calendar.YEAR),cl.get(Calendar.MONTH)+1, cl.get(Calendar.DATE)));
//OUTPUT: Hijrah-umalqura AH 1436-02-03
just use Google for example here copied from the link given:
import java.util.Calendar;
/**
* Gregorian-Hijri Dates Converter
*
*
* This Code is used to convert Gregorian dates to Hijri Dates
*
*
*/
public class DateHigri {
static double gmod(double n,double m) {
return ((n % m) + m) % m;
}
static double[] kuwaiticalendar(boolean adjust) {
Calendar today = Calendar.getInstance();
int adj=0;
if(adjust){
adj=0;
}else{
adj=1;
}
if (adjust) {
int adjustmili = 1000 * 60 * 60 * 24 * adj;
long todaymili = today.getTimeInMillis() + adjustmili;
today.setTimeInMillis(todaymili);
}
double day = today.get(Calendar.DAY_OF_MONTH);
double month = today.get(Calendar.MONTH);
double year = today.get(Calendar.YEAR);
double m = month + 1;
double y = year;
if (m < 3) {
y -= 1;
m += 12;
}
double a = Math.floor(y / 100.);
double b = 2 - a + Math.floor(a / 4.);
if (y < 1583)
b = 0;
if (y == 1582) {
if (m > 10)
b = -10;
if (m == 10) {
b = 0;
if (day > 4)
b = -10;
}
}
double jd = Math.floor(365.25 * (y + 4716)) + Math.floor(30.6001 * (m + 1)) + day
+ b - 1524;
b = 0;
if (jd > 2299160) {
a = Math.floor((jd - 1867216.25) / 36524.25);
b = 1 + a - Math.floor(a / 4.);
}
double bb = jd + b + 1524;
double cc = Math.floor((bb - 122.1) / 365.25);
double dd = Math.floor(365.25 * cc);
double ee = Math.floor((bb - dd) / 30.6001);
day = (bb - dd) - Math.floor(30.6001 * ee);
month = ee - 1;
if (ee > 13) {
cc += 1;
month = ee - 13;
}
year = cc - 4716;
double wd = gmod(jd + 1, 7) + 1;
double iyear = 10631. / 30.;
double epochastro = 1948084;
double epochcivil = 1948085;
double shift1 = 8.01 / 60.;
double z = jd - epochastro;
double cyc = Math.floor(z / 10631.);
z = z - 10631 * cyc;
double j = Math.floor((z - shift1) / iyear);
double iy = 30 * cyc + j;
z = z - Math.floor(j * iyear + shift1);
double im = Math.floor((z + 28.5001) / 29.5);
if (im == 13)
im = 12;
double id = z - Math.floor(29.5001 * im - 29);
double[] myRes = new double[8];
myRes[0] = day; // calculated day (CE)
myRes[1] = month - 1; // calculated month (CE)
myRes[2] = year; // calculated year (CE)
myRes[3] = jd - 1; // julian day number
myRes[4] = wd - 1; // weekday number
myRes[5] = id; // islamic date
myRes[6] = im - 1; // islamic month
myRes[7] = iy; // islamic year
return myRes;
}
static String writeIslamicDate() {
String[] wdNames = {"Ahad", "Ithnin", "Thulatha", "Arbaa", "Khams",
"Jumuah", "Sabt"};
String[] iMonthNames = {"Muharram", "Safar", "Rabi'ul Awwal",
"Rabi'ul Akhir", "Jumadal Ula", "Jumadal Akhira", "Rajab",
"Sha'ban", "Ramadan", "Shawwal", "Dhul Qa'ada", "Dhul Hijja"};
// This Value is used to give the correct day +- 1 day
boolean dayTest=true;
double[] iDate = kuwaiticalendar(dayTest);
String outputIslamicDate = wdNames[(int) iDate[4]] + ", " + iDate[5] + " "
+ iMonthNames[(int) iDate[6]] + " " + iDate[7] + " AH";
return outputIslamicDate;
}
}
Try ummalqura-calendar which implements java.util.Calendar.
Using this calendar you can convert from Umm Al-Qura to Gregorian and vice versa,
and also you can use java.text.SimpleDateFormat to format dates.
sample way to convert date on android platform import
import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.chrono.ISOChronology;
import org.joda.time.chrono.IslamicChronology;
import org.joda.time.LocalDate;
then
implements HijriDatePickerDialog.OnDateSetListener
on onDateSet method
#Override
public void onDateSet(HijriDatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
Chronology iso = ISOChronology.getInstanceUTC();
Chronology hijri = IslamicChronology.getInstanceUTC();
DateTime dtHijri = new DateTime(year,monthOfYear,monthOfYear,dayOfMonth,dayOfMonth,hijri);
DateTime dtIso = new DateTime(dtHijri, iso);
Log.i("converted date" ,String.valueOf(dtIso));
}
For android API 26 and above you can use
import java.time.chrono.HijrahDate
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
HijrahDate.now()
}
It is a build-in class in Java.
Related
Can't find the calculation issue within my easter calculator program. If the input is 2019, the month output is 4, and day is -2 for some reason. 4 would be April which is correct but the day is wrong. Advice to make the code more efficient and solution?
import java.util.*;
import java.lang.Math;
class Main {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
System.out.println("\nWelcome to the Easter Calculator. Please enter the current year below.");
double y = userInput.nextInt();
double p = y/100;
double q = y - (19*(y/19));
double r = (p-17)/25;
double s = p - (p/4) - ((p-r)/3) + (19*q) + 15;
s = s - (30*(s/30));
s = s - ((s/28)*(1-((s/28)*(29/(2+1))*((21-q)/11))));
double t = y + (y/4) + s + 2 - p + (p/4);
t = t - (7*(t/7));
double u = s - t;
double m = 3 + ((u+40)/44);
double d = u + 28 - (31*(m/4));
System.out.println("Year = "+Math.round(y));
System.out.println("Month = "+Math.round(m));
System.out.println("Day = "+Math.round(d));
}
}
In the third line of s calculation
s = s - ((s / 28) * (1 - ((s / 28) * (29 / (2 + 1)) * ((21 - q) / 11))));
you have phrase (29 / (2 + 1) which is itself suspicuous and does not correspond to the notes you've attached. There should be (29 / (s + 1) instead.
Constructions like
y - (19 * (y / 19))
t - (7 * (t / 7))
s - (30 * (s / 30))
will always produce practical 0 been calculated in double all through.
There should be an integer division in brackets.
Is there any note to the page you quoted?
If we assume here we calculate sort of scaled operational margin, and use int division like this
y - (19 * (((int)y) / 19)) or y - (19 * (int)(y / 19)) (which delivers smaller delta)
in all these places, we'll get 17-th of April for 2019. Looks valid data, but not valid Easter date for the year (not sure about that, actually).
Turns out the solution was to simply convert all variable types from doubles to integers. Thanks for the help.
import java.util.*;
import java.lang.Math;
class Main {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
System.out.println("\nWelcome to the Easter Calculator. Please enter the current year below.");
int y = userInput.nextInt();
int p = y/100;
int q = y - (19*(y/19));
int r = (p-17)/25;
int s = p - (p/4) - ((p-r)/3) + (19*q) + 15;
s = s - (30*(s/30));
s = s - ((s/28)*1-((s/28)*(29/(s+1))*((21-q)/11)));
int t = y + (y/4) + s + 2 - p + (p/4);
t = t - (7*(t/7));
int u = s - t;
int m = 3 + ((u+40)/44);
int d = u + 28 - (31*(m/4));
System.out.println("Year = "+Math.round(y));
System.out.println("Month = "+Math.round(m));
System.out.println("Day = "+Math.round(d));
}
}
I am using System.currentTimeMillis() to get number of milliseconds since 1970, I am able to get current Hour, Minute, seconds and year. For example I am getting Year using following formula and it returns 2015:
((((currTimeInMilliSec / 1000) / 3600) / 24) / 365) + 1970
But how can I calculate Month from milliseconds keeping in considering Leap Year and different number of days in different months like 28,29,30,31.
Note: For some reason, I need to use only currentTimeMillis function to calculate and I don't want to use other functions or external libraries. Also I have gone through related posts but didn't find exact answer.
Use GregorianCalendar.
GregorianCalendar c = new GregorianCalendar();
c.setTimeInMillis(1l);
int month = c.get(Calendar.MONTH);
This returns 0, that is January. Imagine an array with the 12 months of the year.
Yes, this is possible.
There are astronomical algorithms that enable the numerical translation between a Julian Day Number and a date-time stamp. The algorithm with which I am familiar was published by J. Meeus in his Astronomical Algorithms, 2nd Ed. This algorithm will convert a Julian Day Number to a vector of integers representing the corresponding:
YEAR
MONTH_IN_YEAR (1-12)
DAY_IN_MONTH (1-28,29,30,31 as appropriate)
HOUR_IN_DAY (0-23)
MINUTE_IN_HOUR (0-59)
SECOND_IN_MINUTE (0-59)
MILLISECOND_IN_SECOND (0-999)
Because both POSIX time and Julian Day Numbers are date serials (counts of consecutive time units) they are trivial to interconvert. Thus, the 1st step for using this algorithm would be to convert POSIX time (millis since midnight Jan 1, 1970) to a Julian Day Number (count of days since November 24, 4714 BC, in the proleptic Gregorian calendar). This is trivial to do since you simply convert from millis to days and adjust the epoch.
Here are the constants:
/** Accessor index for year field from a date/time vector of ints. */
public static final int YEAR = 0;
/** Accessor index for month-in-year field from a date/time vector of ints */
public static final int MONTH = 1;
/** Accessor index for day-in-month field from a date/time vector of ints */
public static final int DAY = 2;
/** Accessor index for hour-in-day field from a date/time vector of ints */
public static final int HOURS = 3;
/** Accessor index for minute-in-hour field from a date/time vector of ints */
public static final int MINUTES = 4;
/** Accessor index for second-in-minute field from a date/time vector of ints */
public static final int SECONDS = 5;
/** Accessor index for millis-in-second field from a date/time vector of ints */
public static final int MILLIS = 6;
/** The POSIX Epoch represented as a modified Julian Day number */
public static final double POSIX_EPOCH_AS_MJD = 40587.0d;
And here is the method for the algorithm that converts a Julian Day Number (supplied as a double) to a vector of integers. In the code below, you can substitute the trunc() function with Math.floor() and retain the correct behavior:
public static int[] toVectorFromDayNumber(double julianDay) {
int[] ymd_hmsm = {YEAR, MONTH, DAY, HOURS, MINUTES, SECONDS, MILLIS};
int a, b, c, d, e, z;
double f, x;
double jd = julianDay + 0.5;
z = (int) trunc(jd);
f = (jd - z) + (0.5 / (86400.0 * 1000.0));
if (z >= 2299161) {
int alpha = (int) trunc((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - (alpha / 4);
} else {
a = z;
}
b = a + 1524;
c = (int) trunc((b - 122.1) / 365.25);
d = (int) trunc(365.25 * c);
e = (int) trunc((b - d) / 30.6001);
ymd_hmsm[DAY] = b - d - (int) trunc(30.6001 * e);
ymd_hmsm[MONTH] = (e < 14)
? (e - 1)
: (e - 13);
ymd_hmsm[YEAR] = (ymd_hmsm[MONTH] > 2)
? (c - 4716)
: (c - 4715);
for (int i = HOURS; i <= MILLIS; i++) {
switch (i) {
case HOURS:
f = f * 24.0;
break;
case MINUTES: case SECONDS:
f = f * 60.0;
break;
case MILLIS:
f = f * 1000.0;
break;
}
x = trunc(f);
ymd_hmsm[i] = (int) x;
f = f - x;
}
return ymd_hmsm;
}
For example, if the function is called with the Julian Day Number 2457272.5, it would return the following vector of integers representing midnight, Sept 7, 2015 (Labor Day) in UTC:
[ 2015, 9, 7, 0, 0, 0, 0 ]
Edit: A remarkable thing about the Meeus algorithm is that it correctly accounts for both Leap Years and century days (including the century day exception). It uses only integer and floating point arithmetic and is very likely to be more performant than solutions which require object instantiations from the Java Calendar or Date-Time APIs.
My variant:
public class Main {
public static class MyDate {
int month;
int day;
public MyDate(int month, int day) {
this.month = month;
this.day = day;
}
}
public static final int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public static void main(String[] args) {
long millis = System.currentTimeMillis();
long days = millis / 86400000;
long millisToday = millis % 86400000;
int yearsPassedApprox = (int) days / 365;
int daysPassedThisYear = (int) (days - (yearsPassedApprox * 365 + leapYearsCount(yearsPassedApprox)));
int year = yearsPassedApprox + 1970;
MyDate myDate = getMonthAndDay(year, daysPassedThisYear);
int hours = (int) (millisToday / 3600000);
int minutes = (int) ((millisToday % 3600000) / 60000);
int seconds = (int) ((millisToday % 60000) / 1000);
System.out.println("Year: " + year);
System.out.println("Month: " + myDate.month);
System.out.println("Day: " + myDate.day);
System.out.println("Hour: " + hours);
System.out.println("Minutes: " + minutes);
System.out.println("Seconds: " + seconds);
}
public static MyDate getMonthAndDay(int year, int daysPassedThisYear) {
int i;
int daysLeft = daysPassedThisYear;
boolean leapYear = isLeapYear(year);
for (i = 0; i < daysInMonth.length; i++) {
int days = daysInMonth[i];
if (leapYear && i == 1) {
days++;
}
if (days <= daysLeft) {
daysLeft -= days;
} else {
break;
}
}
return new MyDate(i + 1, daysLeft + 1);
}
public static int leapYearsCount(long yearsPassed) {
int count = 0;
for (int i = 1970; i < 1970 + yearsPassed ; i++) {
if (isLeapYear(i)) {
count++;
}
}
return count;
}
public static boolean isLeapYear(int year) {
return (year % 4 == 0 && !(year % 100 == 0)) || year % 400 == 0;
}
}
This question already has answers here:
Calculating the difference between two Java date instances
(45 answers)
Closed 9 years ago.
hello I am trying to calculate how many days are left in a pregnancy term but I think my algorithm is incorrect
public int getDaysPregnantRemainder_new() {
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
long diffDays = 280 - ((getDueDate().getTime() - calendar.getTime()
.getTime()) / (24 * 60 * 60 * 1000));
return (int) Math.abs((diffDays) % 7);
}
I am basing it off of a 280 day term, getDueDate() is a Date object and getTime() returns millisecond unix time
On some real world days the number reported is off by one, sometimes, and I am starting to think my algorithm is just wrong, or the millisecond time get gradually further and further off, or the millisecond time is not precise enough, or the gregorian calendar function rounds weird.
All in all I'm not sure, any insight appreciated
I don't know about your algorithm, but this (is basically) the one I used while tracking my wife's pregency...nerds...
Save yourself a lot of "guess" work and get hold of Joda-Time
public class TestDueDate {
public static final int WEEKS_IN_PREGNANCY = 40;
public static final int DAYS_IN_PREGNANCY = WEEKS_IN_PREGNANCY * 7;
public static void main(String[] args) {
DateTime dueDate = new DateTime();
dueDate = dueDate.plusDays(DAYS_IN_PREGNANCY);
System.out.println("dueDate = " + dueDate);
DateTime today = DateTime.now();
Days d = Days.daysBetween(today, dueDate);
int daysRemaining = d.getDays();
int daysIn = DAYS_IN_PREGNANCY - daysRemaining;
int weekValue = daysIn / 7;
int weekPart = daysIn % 7;
String week = weekValue + "." + weekPart;
System.out.println("Days remaining = " + daysRemaining);
System.out.println("Days In = " + daysIn);
System.out.println("Week = " + week);
}
}
This will output...
dueDate = 2014-02-25T14:14:31.159+11:00
Days remaining = 279
Days In = 1
Week = 0.1
I have written a function but it does not give an actual O/P...
public int date(Object O) {
if (O instanceof Date) {
Date d1 = (Date) O;
Calendar cal = Calendar.getInstance();
cal.setTime(d1);
int dd, mm, yy;
dd = cal.get(Calendar.DAY_OF_MONTH);
mm = cal.get(Calendar.MONTH);
yy = cal.get(Calendar.YEAR);
if (dd == 29 && mm == 02 && yy == 1900)
return 60;
long nSerialDate = ((1461 * (yy + 4800 + ((mm - 14) / 12))) / 4)
+ ((367 * (mm - 2 - 12 * ((mm - 14) / 12))) / 12)
- ((3 * (((yy + 4900 + ((mm - 14) / 12)) / 100))) / 4) + dd
- 2415019 - 32075;
if (nSerialDate < 60) {
// Because of the 29-02-1900 bug, any serial date
// under 60 is one off... Compensate.
nSerialDate--;
}
return (int) nSerialDate;
}
return -1;
}
Main class
p s v main(String args[]){
CommonFunctionsImpl cmp= new CommonFunctionsImpl();
Date date1 = null;
try {
date1 = new SimpleDateFormat("MM/dd/yy").parse("05/18/2008");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("date-----"+cmp.date(date1));
}
Output date-----39556
In Excel DATE(2008,5,18) = 39586.00
My program O/P doesn't actually match with Excel O/P.
The right algorithm is already implemented in Apache POI.
Take a look at class org.apache.poi.ss.usermodel.DateUtil.
Also this description could be useful: http://support.microsoft.com/kb/214094/en-us
The problem in the program is :
In the program, variable mm(month) is coming as 4 and O/P is coming for 4th month only.
(The first month of the year is 0)
To Solve this, you need to increase the month value.
dd = cal.get(Calendar.DAY_OF_MONTH);
mm = cal.get(Calendar.MONTH);
yy = cal.get(Calendar.YEAR);
//Solution for the issue
mm++;
if (dd == 29 && mm == 02 && yy == 1900)
return 60;
long nSerialDate = ((1461 * (yy + 4800 + ((mm - 14) / 12))) / 4)
+ ((367 * (mm - 2 - 12 * ((mm - 14) / 12))) / 12)
- ((3 * (((yy + 4900 + ((mm - 14) / 12)) / 100))) / 4) + dd
- 2415019 - 32075;
Try this:
Date begin = new Date(0, 0, 1); // 1900 based date
Date date = new Date(108, 4, 18); // your date
// There is 2 days offset from the calculated date and what you
// expect so I added it on the result
System.out.println(2+(date.getTime()-begin.getTime())/(1000*60*60*24));
See java.util.Date JavaDoc && Excel Date Function Guide
How do I convert a 7-digit julian date into a format like MM/dd/yyy?
Found a useful site: http://www.rgagnon.com/javadetails/java-0506.html
This should do the trick:
public static int[] fromJulian(double injulian) {
int jalpha,ja,jb,jc,jd,je,year,month,day;
double julian = julian + HALFSECOND / 86400.0;
ja = (int) julian;
if (ja>= JGREG) {
jalpha = (int) (((ja - 1867216) - 0.25) / 36524.25);
ja = ja + 1 + jalpha - jalpha / 4;
}
jb = ja + 1524;
jc = (int) (6680.0 + ((jb - 2439870) - 122.1) / 365.25);
jd = 365 * jc + jc / 4;
je = (int) ((jb - jd) / 30.6001);
day = jb - jd - (int) (30.6001 * je);
month = je - 1;
if (month > 12) month = month - 12;
year = jc - 4715;
if (month > 2) year--;
if (year <= 0) year--;
return new int[] {year, month, day};
}
Starting with Java 8, this becomes a one-liner to get the LocalDate:
LocalDate.MIN.with(JulianFields.JULIAN_DAY, julianDay)
.format(DateTimeFormatter.ofPattern("MM/dd/yyyy"));
Where julianDay is your 7-digit number.
simple way is here and this will return approx 100% accurate information.
String getDobInfo(double doubleString){
SweDate sweDate = new SweDate(doubleString);
int year = sweDate.getYear();
int month = sweDate.getMonth();
int day = sweDate.getDay();
// getting hour,minute and sec from julian date
int hour = (int) Math.floor(sweDate.getHour());
int min = (int) Math
.round((sweDate.getHour() - Math.floor(hour)) * 60.0);
int sec = (int) (((sweDate.getHour() - Math.floor(hour)) * 60.0 - Math
.floor(min)) * 60.0);
return "DOB:(DD:MM:YY) "+day+":"+month+":"+year+" TOB:(HH:MM:SS) "+hour+":"+min+":"+sec;
}
download the Swiss Ephemeris library and enjoy coding!!!
Do you really mean a Julian date, like astronomers use? Ordinal dates, which are specified as a year (four digits) and the day within that year (3 digits), are sometimes incorrectly called Julian dates.
static String formatOrdinal(int year, int day) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.DAY_OF_YEAR, day);
Date date = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
return formatter.format(date);
}
This will give you the date at 00:00 local time; you may want to set the timezone on the calendars to GMT instead, depending on the application.
I see there are enough answers already provided. But any calendar related question is only half answered without mentioning joda-time ;-). Here is how simple it is with this library
// setup date object for the Battle of Hastings in 1066
Chronology chrono = JulianChronology.getInstance();
DateTime dt = new DateTime(1066, 10, 14, 10, 0, 0, 0, chrono);