問題描述
儒略日數(shù)是一種將時間戳表示為自 UTC 時間(公元前 4713 年 1 月 1 日中午)以來的連續(xù)天數(shù)(和小數(shù)天數(shù))的方法.Java 7 SE API 不包含對這種格式的支持.使用過 SQLite 數(shù)據(jù)庫的開發(fā)者可能使用過 strftime() 函數(shù)提供的原生 Julian Day 支持.
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.
將時間戳表示為儒略日數(shù)的優(yōu)點包括:
The advantages of representing timestamps as Julian Day Numbers include:
- 可以在原始數(shù)據(jù)類型(雙精度)中以毫秒精度表示日期和時間
- 一年中的幾天比一天中的幾秒鐘更具體
- 如果這種精度不重要,則可以繞過閏秒"問題
- 日期之間的天數(shù)算術(shù)是微不足道的;排序優(yōu)先級很容易確定
- 非常輕量級
缺點
- Java 日期/時間 API 沒有對 JDN 的內(nèi)置支持
- 不適合非常精確的時間測量
- 僅為 UTC 定義,必須從 UTC 映射到本地時間
- 不適合向最終用戶展示;必須在顯示前轉(zhuǎn)換/格式化
儒略日數(shù)字常用于天文計算,其定義高度標準化并被接受.同樣,修改后的儒略日數(shù)(從 UTC 時間 1858 年 11 月 17 日午夜開始計算)是標準定義并用于航空航天應(yīng)用(參見 http://tycho.usno.navy.mil/mjd.html).
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).
對于廣泛使用日期/時間算術(shù)或時間排序的應(yīng)用程序(或者如果持久化輕量級原語比持久化時間戳更有吸引力),在內(nèi)部將日期和時間表示為 JDN 或 MJD 可能對您有意義.
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.
以下代碼定義了有助于使用 Java 日期/時間/日歷 API 的儒略日數(shù)字或修改的儒略日數(shù)字的函數(shù).該代碼基于 Jean Meeus 的Astronomical Algorithms",1991 年第 1 版中發(fā)表的算法.
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;
}
}
這里也提供了這個答案:如何在 Java 日期和儒略日數(shù)之間進行轉(zhuǎn)換?.在當前帖子中,提供了該算法的參考資料以及更多討論.上述算法的實現(xiàn)也不包含 Java API 依賴項(除了數(shù)學(xué)函數(shù)).
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 日歷 API,但也許你應(yīng)該試試 Jodd 工具.
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());
這非常適合:
- 2113488,2746855323 -> 1074.06.01 18:35
- 2453479,5866961805 -> 2005.04.19 02:04
閱讀更多.
這篇關(guān)于如何在 Java 日歷 API 中使用儒略日數(shù)?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!