Find Day of Week Without Using Calendar function in Java - java

I need to find the day of the week (i.e. Monday, Tuesday...) given MM-DD-YYYY. So basically what java calendar would do, but without using java calendar.

It is possible, though unusual, to compute a number that corresponds to the day of the week from a calendar date.
In brief, you will first need to calculate a serial date number from the calendar date, i.e. a number that is a continuous count of days that have elapsed since a certain fixed point in time (informally called 'the epoch'). The most commonly encountered serial date scheme encountered in modern computing is Posix Time, which has an epoch date of Jan 1, 1970 at midnight UTC.
You will need to decide what level of precision is needed for this calculation, eg. whether you will need to account for the Julian Calendar (used in most of Europe before the Gregorian Calendar reform by Pope Gregory in 1584), whether to correct for century days, etc.
Several algorithms are available to arithmetically convert a calendar date to a serial date number with a given epoch. Historically, the most commonly used epoch for these calculations has been the Julian Day number system (not to be confused with the Julian Calendar), which counts days from November 24, 4714 BC in the proleptic Gregorian calendar. Below is Java code which implements one such algorithm published by Jean Meeus in his book "Astronomical Algorithms, 2nd Ed." This algorithm computes a Julian Day number and assumes that days are exactly 86400 seconds in length, accounts for the general Gregorian Reform, and accounts for century and leap days:
public class JulianDay {
private static final int YEAR = 0;
private static final int MONTH = 1;
private static final int DAY = 2;
private static final int HOURS = 3;
private static final int MINUTES = 4;
private static final int SECONDS = 5;
private static final int MILLIS = 6;
:
:
// Converts a timestamp presented as an array of integers in the following
// order (from index 0 to 6): year,month,day,hours,minutes,seconds,millis
// month (1-12), day (1-28 or 29), hours (0-23), min/sec (0-59) to a
// Julian Day Number.
// For clarity and simplicity, the input values are assumed to be well-formed;
// error checking is not implemented in the snippet.
public static double toJD(int[] ymd_hms) {
int y = ymd_hms[YEAR];
int m = ymd_hms[MONTH];
double d = (double) ymd_hms[DAY];
d = d + ((ymd_hms[HOURS] / 24.0) +
(ymd_hms[MINUTES] / 1440.0) +
(ymd_hms[SECONDS] / 86400.0) +
(ymd_hms[MILLIS] / 86400000.0));
if (m == 1 || m == 2) {
y--;
m = m + 12;
}
double a = Math.floor(y / 100);
double b = 2 - a + Math.floor(a / 4);
return (Math.floor(365.25 * (y + 4716.0)) +
Math.floor(30.6001 * (m + 1)) +
d + b - 1524.5);
}
}
Once you have a serial date number, it is straightforward to compute the day of the week from the remainder when the date number is divided by 7 (the number of days in a week).

If you are talking about simply avoiding the Calendar Object then you could use the Date Object (deprecated) but still works and call setMonth, setYear, and setDate to get the desired date. You then have to use a DateFormatter to get your desired output. I used a SimpleDateFormat and the E specifier to get the day of the week.
Date dNow = new Date();
SimpleDateFormat ft = new SimpleDateFormat ("E");
System.out.println("Current Date: " + ft.format(dNow));
This outputs the current day of the week "Sun", "Sat", etc..
This link will help with the formatting https://www.tutorialspoint.com/java/java_date_time.htm

java.time
Using the java.time classes that supplant the troublesome old date-time classes. The LocalDate class represents a date without a time-of-day and without a time zone.
DayOfWeek dow =
LocalDate.parse(
"01-23-2016" ,
DateTimeFormatter.ofPattern( "MM-dd-uuuu" )
).getDayOfWeek()
That code returns a DayOfWeek enum object. From there you can interrogate for:
Integer number, 1-7 for Monday-Sunday
Localized name of the day.
Example code.
int dowNumber = dow.getValue() ;
String dowName = dow.getDisplayName(
TextStyle.FULL ,
Locale.CANADA_FRENCH ) ; // Or Locale.US, Locale.ITALY, etc.
TIP: Pass around the DayOfWeek objects themselves in your own code, rather than internally track the day-of-week as a number or string. This makes your code more self-documenting, ensures valid values, and provides for type-safety.

I was looking for the answer myself and found another answer based on Zeller's algorithm:
// d = day in month
// m = month (January = 1 : December = 12)
// y = 4 digit year
// Returns 0 = Sunday .. 6 = Saturday
public int dow(int d, int m, int y) {
if (m < 3) {
m += 12;
y--;
}
return (d + int((m+1)*2.6) + y + int(y/4) + 6*int(y/100) + int(y/400) + 6) % 7;
}
Source: here

Related

Java LocalDateTime minusYears for floating number of years

Java LocalDateTime minusYears takes long argument. In case, if I want to minus floating number of year eg. 2.5 years, how can I do that?
Is there any in-built support?
Note: I take both value and unit as input from the user. The above question is bit of generalization (I have same problem with respect to hours, years, weeks etc.). Sometime it can be 2.7 hours or 2.8 years or 5.3 weeks etc
You don't have any built-in support for that but you can do that easily by converting the year value in month (* 12):
float year = 2.5F;
LocalDateTime dateTime = dateTime.minusMonths((int)(year * 12);
And you can also create a util method if required:
public static LocalDateTime removeYear(LocalDateTime dateTime, float year) {
int monthToRemove = (int)(year * 12);
return dateTime.minusMonths(monthToRemove);
}
By testing it with :
public static void main(String[] args) {
LocalDateTime date = removeYear(LocalDateTime.now(), 2.5F);
System.out.println(date);
}
Output :
2016-01-31T16:33:26.755
Note that to make the method more robust you could check that year represent a float that accept only some kinds of values such as zero for the fractional part (2.0) or some fractional such as 0.5.
What about :
double years = 2.5;
long months = (long) (years * 12);// 30 month
LocalDateTime ld = LocalDateTime.now();
ld = ld.minusMonths(months);
But Note this can lose some days for example if you have :
years = 2.7
=>years * 12 > 32.400000000000006
so here you can lose 0.400000000000006 month.
So maybe if you round it, it can be more helpful :
long months = Math.round(years * 12);
Edit :
based on your comment :
Actually I take both value and unit as input. The above question is
bit of generalization. Sometime it can be 2.7 hours or 2.8 years or
5.3 weeks etc
I think you need something like this :
But be careful with months
public static LocalDateTime changeDate(LocalDateTime date, float time, String unit) {
long newTime;
switch (unit) {
case ("hour"):
newTime = Math.round(time * 60);
date = date.minusMinutes(newTime);// If hours then subtract minutes
break;
case ("day"):
newTime = Math.round(time * 24);
date = date.minusHours(newTime);// If days then subtract hours
break;
case ("week"):
newTime = Math.round(time * 7);
date = date.minusDays(newTime);// If week then subtract days
break;
case ("month"):
newTime = Math.round(time * 30);// here You have to check again
date = date.minusDays(newTime);// If month then subtract days
break;
case ("year"):
newTime = Math.round(time * 12);
date = date.minusMonths(newTime);// If days then subtract months
break;
default:
break;
}
return date;
}
You can utilise both the minusYears and minusMonth methods to do the job.
example:
LocalDateTime dateTime = LocalDateTime.now();
LocalDateTime result = dateTime.minusYears(2).minusMonths(6);
When you say "2.5" years I am assuming you mean "two years and a half" as opposed to "two years and 5 months" but yeah you can correct that anyway if need be.
There's no built in support, but you can do this, if you want to sacrifice precision:
public static void main(String[] args) {
LocalDate ld = LocalDate.of(2015, 12, 1);
System.out.println(minusFpYears(ld, 2.5f));
}
static LocalDate minusFpYears(LocalDate ld, float fpyears) {
float fpmonths = fpyears % 1;
long years = (long)(fpyears - fpmonths);
long months = (long)(12L * fpmonths);
return ld.minusYears(years).minusMonths(months);
}
Thanks for the code! Actually I take both value and unit as input. The
above question is bit of generalization. Sometime it can be 2.7 hours
or 2.8 years or 5.3 weeks etc.
Make LocalDate minusFpWeeks(LocalDate ld, float fpweeks), LocalDateTime minusFpHours(LocalDateTime ld, float fphours) etc functions, to handle that.

Java 8 calculate months between two dates

NOTE THIS IS NOT A DUPLICATE OF EITHER OF THE FOLLOWING
Calculating the difference between two Java date instances
calculate months between two dates in java [duplicate]
I have two dates:
Start date: "2016-08-31"
End date: "2016-11-30"
Its 91 days duration between the above two dates, I expected my code to return 3 months duration, but the below methods only returned 2 months. Does anyone have a better suggestion? Or do you guys think this is a bug in Java 8? 91 days the duration only return 2 months.
Thank you very much for the help.
Method 1:
Period diff = Period.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30"));
Method 2:
long daysBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30"));
Method 3:
I tried to use Joda library instead of Java 8 APIs, it works. it loos will return 3, It looks like Java duration months calculation also used days value. But in my case, i cannot use the Joda at my project. So still looking for other solutions.
LocalDate dateBefore= LocalDate.parse("2016-08-31");
LocalDate dateAfter = LocalDate.parse("2016-11-30");
int months = Months.monthsBetween(dateBefore, dateAfter).getMonths();
System.out.println(months);
Since you don't care about the days in your case. You only want the number of month between two dates, use the documentation of the period to adapt the dates, it used the days as explain by Jacob. Simply set the days of both instance to the same value (the first day of the month)
Period diff = Period.between(
LocalDate.parse("2016-08-31").withDayOfMonth(1),
LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(diff); //P3M
Same with the other solution :
long monthsBetween = ChronoUnit.MONTHS.between(
LocalDate.parse("2016-08-31").withDayOfMonth(1),
LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(monthsBetween); //3
Edit from #Olivier Grégoire comment:
Instead of using a LocalDate and set the day to the first of the month, we can use YearMonth that doesn't use the unit of days.
long monthsBetween = ChronoUnit.MONTHS.between(
YearMonth.from(LocalDate.parse("2016-08-31")),
YearMonth.from(LocalDate.parse("2016-11-30"))
)
System.out.println(monthsBetween); //3
Since Java8:
ChronoUnit.MONTHS.between(startDate, endDate);
//Backward compatible with older Java
public static int monthsBetween(Date d1, Date d2){
if(d2==null || d1==null){
return -1;//Error
}
Calendar m_calendar=Calendar.getInstance();
m_calendar.setTime(d1);
int nMonth1=12*m_calendar.get(Calendar.YEAR)+m_calendar.get(Calendar.MONTH);
m_calendar.setTime(d2);
int nMonth2=12*m_calendar.get(Calendar.YEAR)+m_calendar.get(Calendar.MONTH);
return java.lang.Math.abs(nMonth2-nMonth1);
}
The documentation of Period#between states the following:
The start date is included, but the end date is not.
Furthermore:
A month is considered if the end day-of-month is greater than or equal to the start day-of-month.
Your end day-of-month 30 is not greater than or equal to your start day-of-month 31, so a third month is not considered.
Note the parameter names:
public static Period between​(LocalDate startDateInclusive, LocalDate endDateExclusive)
To return 3 months, you can increment the endDateExclusive by a single day.
In case you want stick to java.time.Period API
As per java.time.Period documentation
Period between(LocalDate startDateInclusive, LocalDate endDateExclusive)
where
#param startDateInclusive the start date, inclusive, not null
#param endDateExclusive the end date, exclusive, not null
So it is better to adjust your implementation to make your end date inclusive and get your desired result
Period diff = Period.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30").plusDays(1));
System.out.println("Months : " + diff.getMonths());
//Output -> Months : 3
You have to be careful, never use LocalDateTime to calculate months between two dates the result is weird and incorrect, always use LocalDate !
here's is some code to prove the above:
package stack.time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class TestMonthsDateTime {
public static void main(String[] args) {
/**------------------Date Time----------------------------*/
LocalDateTime t1 = LocalDateTime.now();
LocalDateTime t2 = LocalDateTime.now().minusMonths(3);
long dateTimeDiff = ChronoUnit.MONTHS.between(t2, t1);
System.out.println("diff dateTime : " + dateTimeDiff); // diff dateTime : 2
/**-------------------------Date----------------------------*/
LocalDate t3 = LocalDate.now();
LocalDate t4 = LocalDate.now().minusMonths(3);
long dateDiff = ChronoUnit.MONTHS.between(t4, t3);
System.out.println("diff date : " + dateDiff); // diff date : 3
}
}
My 2%
This example checks to see if the second date is the end of that month. If it is the end of that month and if the first date of month is greater than the second month date it will know it will need to add 1
LocalDate date1 = LocalDate.parse("2016-08-31");
LocalDate date2 = LocalDate.parse("2016-11-30");
long monthsBetween = ChronoUnit.MONTHS.between(
date1,
date2);
if (date1.isBefore(date2)
&& date2.getDayOfMonth() == date2.lengthOfMonth()
&& date1.getDayOfMonth() > date2.getDayOfMonth()) {
monthsBetween += 1;
}
After the short investigation, still not totally fix my question, But I used a dirty solution to avoid return the incorrect duration. At least, we can get the reasonable duration months.
private static long durationMonths(LocalDate dateBefore, LocalDate dateAfter) {
System.out.println(dateBefore+" "+dateAfter);
if (dateBefore.getDayOfMonth() > 28) {
dateBefore = dateBefore.minusDays(5);
} else if (dateAfter.getDayOfMonth() > 28) {
dateAfter = dateAfter.minusDays(5);
}
return ChronoUnit.MONTHS.between(dateBefore, dateAfter);
}
The Java API response is mathematically accurate according to the calendar. But you need a similar mechanism, such as rounding decimals, to get the number of months between dates that matches the human perception of the approximate number of months between two dates.
Period period = Period.between(LocalDate.parse("2016-08-31"), LocalDate.parse("2016-11-30"));
long months = period.toTotalMonths();
if (period.getDays() >= 15) {
months++;
}

Get days between two dates?

I am trying to get the days between two values. Which is in the format of MMdd.
Ex:
First Date = 0501
Second Date = 0519
Trying to find the value of days between the two dates. In this example would be 18. Please help me with this. I tried searching around and can't find a solution. Thank you!
My Code
This is what I have so far:
Getting an error: Method days in class Project3 cannot be applied to the given type.
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
public class Project3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String name = input.next() + input.nextLine();
String car = input.next() + input.nextLine();
String key = input.next();
String firstDate = input.next(), lastDate = input.next();
double S = 1.0, C = 1.2, U = 1.4, T = 1.6, B = 2.0;
final double N = 89.22, V = (N - 11.4);
double daily, total;
String daysBetween = Project3.days();
}
public static long days(Date firstDate, Date lastDate) {
Calendar start = Calendar.getInstance();
start.setTime(firstDate);
Calendar end = Calendar.getInstance();
long daysBetween = 0;
while (start.before(end)) {
start.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
}
Using Joda Time Days:
DateTimeFormatter dtf = DateTimeFormat.forPattern("MMdd");
LocalDate day1 = dtf.parseLocalDate("0501");
LocalDate day2 = dtf.parseLocalDate("0519");
int daysBetween = Days.daysBetween(day1, day2).getDays();
Joda time is the right way to do this, but if you really have to do it with pure JDK stuff, you can calculate it yourself.
A Calendar instance has a .getTimeInMillis() method that tells you the number of milliseconds since some fixed start point. You can take two dates, put them into Calendar instances, and then calculate the difference between the two getTimeInMillis() values.
Then divide by 1000 to get seconds; by 60 to get minutes; by 60 to get hours; by 24 to get days. And cross your fingers and hope for the best with regard to daylight saving time.
You have one other issue to get round, which is that since you've only got a day and a month, but not a year, there isn't a unique answer. The difference in days between 28 Feb and 1 Mar is one day in most years, but two days in a leap year. If you want to assume Feb has only 28 days, just choose any non-leap year you like (e.g., 2014).
This is a method for calculating the number of days between two dates. It keeps rolling the day forward, while the start date is before the end date. It works regardless of differences in time due to daylight saving time.
public static long days(Date startDate, Date endDate) {
Calendar start = Calendar.getInstance();
start.setTime(startDate);
Calendar end = Calendar.getInstance();
long daysBetween = 0;
while(start.before(end)) {
start.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}

How to calculate the total hour worked between two dates?

I have two dates, hiring 11/19/2013 and endhiring 10/01/2014, both are converted to total hours, without considering the weekends, but they have different years and because of this the output says: the total hours worked was -1200:
private int calculateTimeInternship(Vacancy peoplevacancy){
int hourWorked = 0;
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
date1.setTime(peoplevacancy.getDthiring());
date2.setTime(peoplevacancy.getDtendhiring());
int initiation = date1.get(Calendar.DAY_OF_YEAR);
int end = date2.get(Calendar.DAY_OF_YEAR);
int amountDay = (initiation - end) + 1;
for (; initiation <= end; inicio++){
if (date1.get(Calendar.DAY_OF_WEEK) == 1 || date1.get(Calendar.DAY_OF_WEEK) == 7)
amountDay--;
date1.add(Calendar.DATE, 1);
}
hourWorked = amountDay * 4 //4 hour per day;
return hourWorked ;
}
Joda can help you, but I'm never able to use it because of its license.
If like me, Joda is not appropriate for you, you can solve this problem as follows:
initialize endDate object
initialize startDate object
initialize weeksBetween as
milliseconds between end&start/milliseconds per day, divided by seven (integer floor).
//may need to normalize dates and set them to be both midnight or noon or some common time
initialize daysBetween = weeksBetween*5 // in any continuous 7 days, 5 are weekdays.
initialize curDay=startDate + weeksBetween*7 days
while(curDay is not endDate)
add a day to curDay
if(curDay is not weekend)
daysBetween++
output daysBetween* 4
You can get the milliseconds between them by converting the calendars to Date (Calendar has such a method to do this)
You are already looping through every day of the internship, so why not simply count workdays?
int amountDay = 0;
while (date1.compareTo(date2) <= 0) {
if (date1.get(Calendar.DAY_OF_WEEK) != 1
&& date1.get(Calendar.DAY_OF_WEEK) != 7)
amountDay++;
date1.add(Calendar.DATE, 1);
}
By the way, your original code has a subtle "off by one" bug. The subtraction for the total amountDays excludes the end day, but the loop includes the end day when deducting weekends.
Why so complicated?
private int calculateTimeInternship(Vacancy vacancy) {
return 4 * ((int)(vacancy.getDtendhiring().getTime() / 86400000L - vacancy.getDthiring().getTime() / 86400000L) + 1);
}
By dividing by 86400000 first, then subtracting, it doesn't matter what time of day each date have.
FYI 86400000 is the number of milliseconds in a day.

How do I use Julian Day Numbers with the Java Calendar API?

Julian Day Numbers are a means of representing timestamps as a continuous count of days (and fractional days) since noon UTC, January 1, 4713 B.C. The Java 7 SE API does not contain support for this format. Developers who have used the SQLite database may have used the native Julian Day support provided by the strftime() functions.
The advantages of representing timestamps as Julian Day Numbers include:
A date and time can be represented to millisecond precision in a primitive data type (double)
Days in a year are somewhat more concrete than seconds in a day
Circumvents the problem of "leap seconds" if this degree of precision is unimportant
Days between dates arithmetic is trivial; sorting precedence is easily determined
Very lightweight
Disadvantages
The Java Date/Time API does not have built-in support for JDN's
Unsuitable for very precise time measurements
Only defined for UTC and must be mapped from UTC to local time
Unsuitable for display to end-users; must be converted/formatted before display
Julian Day Numbers are commonly used in astronomical calculations and their definition is highly standardized and accepted. Similarly, Modified Julian Day Numbers (which count from midnight UTC, 17 November 1858) are standardly defined and used in aerospace applications (see http://tycho.usno.navy.mil/mjd.html).
For applications that make extensive use of date/time arithmetic or chronological sorting (or if persisting lightweight primitives is more appealing than persisting timestamps), internally representing dates and times as JDN's or MJD's may make sense for you.
The following code defines functions that facilitate using either Julian Day Numbers or Modified Julian Day Numbers with the Java Date/Time/Calendar API. The code is based on algorithms published in Jean Meeus's "Astronomical Algorithms", 1st ed., 1991.
public class JulianDay {
private static final int YEAR = 0;
private static final int MONTH = 1;
private static final int DAY = 2;
private static final int HOURS = 3;
private static final int MINUTES = 4;
private static final int SECONDS = 5;
private static final int MILLIS = 6;
:
:
// Converts a timestamp presented as an array of integers in the following
// order (from index 0 to 6): year,month,day,hours,minutes,seconds,millis
// month (1-12), day (1-28 or 29), hours (0-23), min/sec (0-59) to a
// Modified Julian Day Number.
// For clarity and simplicity, the input values are assumed to be well-formed;
// error checking is not implemented in the snippet.
public static double toMJD(int[] ymd_hms) {
int y = ymd_hms[YEAR];
int m = ymd_hms[MONTH];
double d = (double) ymd_hms[DAY];
d = d + ((ymd_hms[HOURS] / 24.0) +
(ymd_hms[MINUTES] / 1440.0) +
(ymd_hms[SECONDS] / 86400.0) +
(ymd_hms[MILLIS] / 86400000.0));
if (m == 1 || m == 2) {
y--;
m = m + 12;
}
double a = Math.floor(y / 100);
double b = 2 - a + Math.floor(a / 4);
return (Math.floor(365.25 * (y + 4716.0)) +
Math.floor(30.6001 * (m + 1)) +
d + b - 1524.5) - 2400000.5; // for Julian Day omit the 2400000.5 term
}
// Converts an Modified Julian Day Number (double) to an integer array representing
// a timestamp (year,month,day,hours,mins,secs,millis). Works for all positive JDN
public static int[] toTimestamp(double mjd) {
int ymd_hms[] = { -1, -1, -1, -1, -1, -1, -1 };
int a, b, c, d, e, z;
double jd = mjd + 2400000.5 + 0.5; // if a JDN is passed as argument,
// omit the 2400000.5 term
double f, x;
z = (int) Math.floor(jd);
f = jd - z;
if (z >= 2299161) {
int alpha = (int) Math.floor((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - (int) Math.floor(alpha / 4);
} else {
a = z;
}
b = a + 1524;
c = (int) Math.floor((b - 122.1) / 365.25);
d = (int) Math.floor(365.25 * c);
e = (int) Math.floor((b - d) / 30.6001);
ymd_hms[DAY] = b - d - (int) Math.floor(30.6001 * e);
ymd_hms[MONTH] = (e < 14)
? (e - 1)
: (e - 13);
ymd_hms[YEAR] = (ymd_hms[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 = Math.floor(f);
ymd_hms[i] = (int) x;
f = f - x;
}
return ymd_hms;
}
}
This answer has been provided here as well: How can I convert between a Java Date and Julian day number?. In the current post, references for the algorithm are provided along with some more discussion. The implementation of algorithms above also contains no Java API dependencies (aside from Math functions).
java.time
The java.time framework built into Java 8 and later supplants the old date-time classes bundled with the earliest versions of Java. See Oracle Tutorial. Much of the functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The java.time classes include the java.time.temporal.JulianFields. This class provides three implementations of TemporalField to give limited support for Julian date-only values (no time-of-day). So you can get whole number of days, not the double requested in the Question. Read that class doc closely to be sure it behaves to your expectations. Note that unlike most other java.time classes, these Julian classes ignore any offset-from-UTC or time zone information (always treated as a local date).
JULIAN_DAY → Count of whole days since day 0, which is January 1, 4713 BCE in the Julian calendar ( -4713-11-24 Gregorian ).
MODIFIED_JULIAN_DAY → Like JULIAN_DAY but subtracting 2_400_000.5 (basically dropping the first two digits of Julian date number). Note that results here are one fewer (-1) than Julian date number of item above.
RATA_DIE → Similar to the two items above in that it is a count of days from an epoch. But here the epoch is the ISO 8601 date of 0001-01-01.
In this example we start with the ISO 8601 date of 1970-01-01.
LocalDate localDate = LocalDate.of ( 1970 , 1 , 1 );
long julianDate = JulianFields.JULIAN_DAY.getFrom ( localDate );
long modifiedJulianDate = JulianFields.MODIFIED_JULIAN_DAY.getFrom ( localDate );
long rataDie = JulianFields.RATA_DIE.getFrom ( localDate );
localDate: 1970-01-01 | julianDate: 2440588 | modifiedJulianDate: 40587 | rataDie: 719163
ThreeTen-Extra
The ThreeTen-Extra project is the experimental proving grounds for possible future additions to java.time. The name comes from the JSR 310 that defines java.time.
This library includes additional support for Julian dates in its Julian calendar system (Chronology). Like the support in Java 8, this library is limited to date-only values (no partial days or time-of-day).
With this library you can instantiate JulianDate objects.
Many methods and features for you to examine there.
I know that this is not a Java Calendar API, but maybe you should try Jodd tool.
JulianDateStamp julianStamp = new JulianDateStamp(julianDays);
JDateTime jdate = new JDateTime(julianStamp);
Date date = new Date(jdate.getTimeInMillis());
This works perfect for:
2113488,2746855323 -> 1074.06.01 18:35
2453479,5866961805 -> 2005.04.19 02:04
Read more.
If you are willing to move outside the core JDK classes, then Joda can be a solution.
Joda supports the Julian calendar system. From their doc page:
Chronology julianChrono = JulianChronology.getInstance();
DateTime dt = new DateTime(1066, 10, 14, 0, 0, 0, julianChrono);
That would be the Battle of Hastings 1066 in the Julian Calendar system.

Categories

Resources