I\'m running into a situation where I would like to convert from a Julian date to an java.time.Instant (if that makes sense), or some Java time that can be more easily under
I am going to assume that you have a numeric timestamp that is a kind of modified Julian Day Number, i.e. a continuous count of days since a defined epoch.
For example, the definition of a "Modified Julian Day Number" is a continuous count of days since midnight on Nov 17, 1858. I believe what you are asking is:
How do I convert a continuous count of days in England since the Gregorian Calendar was officially adopted to an Instant?
I'm not certain where the Gregorian Epoch officially began after the New Style Calendar act. I will assume that it is January 1, 1752, i.e. the number 95906.276 is a continuous count of days since then.
METHOD1: Here is an algorithm for processing a day number to an integer array representation in year, month(1-12), day(1-31), hours(0-23), min(0-59), sec(0-59), millis:
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;
public static int[] toTimeStampArray(double yourEpochDayNumber) {
int ymd_hms[] = { -1, -1, -1, -1, -1, -1, -1 };
int a, b, c, d, e, z;
// convert from your epoch (1/1/1752) to Julian Day Number
double jd = yourEpochDayNumber + 2360965.5 + 0.5;
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;
}
Algorithm is adapted from Meeus J., Astronomical Algorithms, 2nd Ed.
From these data, you can create a LocalDateTime instance. You can combine that with a ZoneId instance to create a ZonedDateTime and get an Instant.
METHOD 2. If your day number is already reckoned in GMT/UTC and does not require any offsets for time zone or daylight savings, then you can convert directly from a day number (in your epoch) to an Instant as follows:
public Instant dayNumberToInstant(double dayNumber) {
long millisFromPosixEpoch;
final double POSIX_EPOCH_AS_DAYNUM = 79622.0
millisFromPosixEpoch = (long) ((dayNumber - POSIX_EPOCH_AS_DAYNUM) *
(86400.0 * 1000.0));
return Instant.ofEpochMillis(millisFromPosixEpoch);
}