Qt库里CBSDate类的内部实现用_jd成员进行计算、比较等操作,而这个变量是通过static inline uint32 greg2jul(const int32 y, const int32 m, const int32 d)函数计算出来的。对于这个变量具体代表的含义,我弄不明白,在java里似乎也没发现直接对应的方法。尤其最终的计算表达式:
1721119 + day + (146097*c)/4 + (1461*ya)/4 + (153*month+2)/5;
这么多常数是什么含义???google了一下请教了朋友,大致明白了
这个计算,是算出一个日期对应的儒略日(Julian Date)。
儒略日是一种不用年和月的长期纪日法,计算距一个7980年周期的开始已逝去的天数,这个周期是1583年Joseph Scaliger发明的。这个系统的目的是要使计算一个日历日期和另一个日历日期之间的整数差变得容易。而7980年的周期是从取多个传统时间周期(太阳的,月亮的,还有一个很特殊的罗马的征税周期)的公倍数而得来的。第一个Julian周期的开始点是在儒略历的公元前4713年的一月一号格林尼治平午(即该地民用时12时,而不是平常的子夜开始),此时为“0”日的开始,至次日格林尼治平午为“1”日的开始,由此顺数而下,延续不断地记下来。第一个周期结束于3268年1月22号。接下来的那天就是第二个儒略日周期(7980年的周期)的第一天。
例如:
2451919.3423000001348555,它意味着距儒略周期的开始已经逝去了2451919天。“.3423000001348555”代表这天的时间(“15:12:54 EST”)。
儒略日的计算和使用:
公历转换为干支历
先看年干支的计算。在y年,如2005年则是y=2005;而公元前的年代要转为负号年代,如公元前2070年则为y=-2069。计算a值:a=y-4;再计算gz值:gz=a-[a/60]*60,其中[ ]表明是取整运算,如[8.75]=8。如果gz值为负,则gz=gz+60,使其为正值。这个gz值就是六十甲子的编号。例如,对2005年,y=2005,a=2001,a/60=33.35,[a/60]=33,gz=21,而21就是乙酉,说明2005年是乙酉年。对公元前2070年,y= -2069,a= -2073,a/60= -34.55,[a/60]= -34,gz= -33,gz= -33+60=27,则前2070年为辛卯年。
也可以从a值分别计算年天干或年地支。天干值为:g=a-[a/10]*10,若g是负数则g=g+10。地支值为:z=a-[a/12]*12,若z是负数则z=z+12。例如,公元前2070年,a= -2073,g = -3,g=7,z= -9,z=3。g值为7对应天干的“辛”,z值为3对应地支的“卯”,因此前2070年为辛卯年。
再看日干支的计算,主要是先将公历日期转换为儒略日,再由儒略日来计算日干支。因为儒略日是以正午开始新的一天,这里我们不妨约定某日的儒略日是对应于该日正午的。而计算儒略日的方法有很多种,这里只选一种适于编程的方法(括号内的是举例):
1)对于y年m月d日。(如2005年2月9日12时,则y = 2005,m = 2,d=9)
2)如果是1月和2月(m=1和m=2)则:m=m+12,y=y-1。(因m=2,则m=14,y=2004)
3)计算a值:a=[30.6001*(m+1)] 。(a=[30.6001*(14+1)]=[459.0015]=459)
4)计算b值:在1582年10月4日以前(含),b=0;在1582年10月15日以后(含),b=2-[y/100]+[y/400]。(因在1582年之后,b=2-[2004/100]+[2004/400]=2-20+5= -13)
5)计算c值:如果y<0,c=[365.25*y-0.75]-694025;如果y=0,c=[365.25*y-0.75]-694025;如果y>0,c=[365.25*y]-694025。(因y>0,c=[365.25*2004]-694025=731961-694025=37936)
6)计算约化儒略日mjd值(以1900年1月0.5日起算的天数):mjd=a+b+c+d。(mjd=459-13+37936+9=38391)
7)计算儒略日jd值: jd=mjd+2415020。(jd=38391+2415020=2453411)
从举例来看,2005年2月9日12时的儒略日为2453411,或略去12时而称2005年2月9日的儒略日为2453411。在计算儒略日时,对于公元前的年代,同样要注意先将其转为负号年代。
而将儒略日转换为日干支就非常简单了。对于儒略日jd值,计算ad值:ad=jd-11;再计算gz值:gz=ad-[ad/60]*60,这就是干支编号。例如儒略日为2453411,则ad=2453400,gz=0,对应干支为甲子,表明该日为甲子日。也可以从ad值分别计算日天干或日地支。天干值为:g=ad-[ad/10]*10,地支值为:z=ad-[ad/12]*12。
顺便提一句,用儒略日来计算星期几也很容易。对于儒略日jd值,计算ax值,ax=jd+1;再计算xq值:xq=ax-[ax/7]*7,xq值为0时是星期日,其余的值是几就是星期几。如2005年2月9日的儒略日为2453411,ax=2453412,xq=3,则该日为星期三。
而在java中,没有直接对应的计算儒略日的方法。。。java内部是使用unix的习惯,以1970年1月1日零时起经过的毫秒数来计算的。一般计算两个时间之间相隔天数,是
long beginTime = beginDate.getTime();
long endTime2 = endDate.getTime();
long betweenDays = (long)((endTime - beginTime) / (1000 * 60 * 60 *24) + 0.5);
转者注:我要用的类库需要mjd时间。不得不google下了。
btw:儒略历转公历的算法。
double jd = mjd;//+2400000.5;
//计算year month,date
int Y,M,D,hour,min,sec;
int l= (int)jd + 68569;
int N = ( 4 * l ) / 146097;
l = l - ( 146097 *N + 3 ) / 4;
int I = ( 4000 * ( l + 1 ) ) / 1461001;
l = l - ( 1461 * I ) / 4 + 31;
int J = ( 80 * l) / 2447;
D = l - ( 2447 * J ) / 80;
l = J / 11;
M = J +2 - ( 12 *l );
Y = 100 * ( N - 49 ) + I + l;
//计算hour minute second
double hms = jd - (int)jd;
hour = (int)(hms*24.0);
min = (int)((hms - hour/24.0)*1440.0);
sec = (int)((hms-hour/24.0-min/1444.0)*86400.0);
实现代码:
package com.easy.utils; /** * Collected methods which allow easy implementation of <code>hashCode()</code>. * Based on items #7 and #8 from "Effective Java" book. * <p> * Usage scenario:<br> * <pre> * int result = HashCodeUtil.SEED; * result = HashCodeUtil.hash(result, fIsDecrepit); * ... * return result; * </pre> */ public class HashCode { /** * An initial hash code value to which is added contributions from fields. * Using a non-zero value decreases collisions of hash code values. */ public static final int SEED = 173; public static final int PRIME = 37; // ---------------------------------------------------------------- boolean /** * Calculates hash code for booleans. */ public static int hash(int seed, boolean aBoolean) { return (PRIME * seed) + (aBoolean ? 1231 : 1237); } /** * Calculates hash code for boolean array. */ public static int hash(int seed, boolean[] booleanArray) { if (booleanArray == null) { return 0; } for (boolean aBoolean : booleanArray) { seed = hash(seed, aBoolean); } return seed; } /** * Calculates hash code for boolean array. */ public static int hashBooleanArray(int seed, boolean... booleanArray) { return hash(seed, booleanArray); } // ---------------------------------------------------------------- char /** * Calculates hash code for chars. */ public static int hash(int seed, char aChar) { return (PRIME * seed) + (int) aChar; } /** * Calculates hash code for char array. */ public static int hash(int seed, char[] charArray) { if (charArray == null) { return 0; } for (char aChar : charArray) { seed = hash(seed, aChar); } return seed; } /** * Calculates hash code for char array. */ public static int hashCharArray(int seed, char... charArray) { return hash(seed, charArray); } // ---------------------------------------------------------------- ints /** * Calculates hash code for ints. */ public static int hash(int seed, int anInt) { return (PRIME * seed) + anInt; } /** * Calculates hash code for int array. */ public static int hash(int seed, int[] intArray) { if (intArray == null) { return 0; } for (int anInt : intArray) { seed = hash(seed, anInt); } return seed; } /** * Calculates hash code for int array. */ public static int hashIntArray(int seed, int... intArray) { return hash(seed, intArray); } /** * Calculates hash code for short array. */ public static int hash(int seed, short[] shortArray) { if (shortArray == null) { return 0; } for (short aShort : shortArray) { seed = hash(seed, aShort); } return seed; } /** * Calculates hash code for short array. */ public static int hashShortArray(int seed, short... shortArray) { return hash(seed, shortArray); } /** * Calculates hash code for byte array. */ public static int hash(int seed, byte[] byteArray) { if (byteArray == null) { return 0; } for (byte aByte : byteArray) { seed = hash(seed, aByte); } return seed; } /** * Calculates hash code for byte array. */ public static int hashByteArray(int seed, byte... byteArray) { return hash(seed, byteArray); } // ---------------------------------------------------------------- long /** * Calculates hash code for longs. */ public static int hash(int seed, long aLong) { return (PRIME * seed) + (int) (aLong ^ (aLong >>> 32)); } /** * Calculates hash code for long array. */ public static int hash(int seed, long[] longArray) { if (longArray == null) { return 0; } for (long aLong : longArray) { seed = hash(seed, aLong); } return seed; } /** * Calculates hash code for long array. */ public static int hashLongArray(int seed, long... longArray) { return hash(seed, longArray); } // ---------------------------------------------------------------- float /** * Calculates hash code for floats. */ public static int hash(int seed, float aFloat) { return hash(seed, Float.floatToIntBits(aFloat)); } /** * Calculates hash code for float array. */ public static int hash(int seed, float[] floatArray) { if (floatArray == null) { return 0; } for (float aFloat : floatArray) { seed = hash(seed, aFloat); } return seed; } /** * Calculates hash code for float array. */ public static int hashFloatArray(int seed, float... floatArray) { return hash(seed, floatArray); } // ---------------------------------------------------------------- double /** * Calculates hash code for doubles. */ public static int hash(int seed, double aDouble) { return hash(seed, Double.doubleToLongBits(aDouble)); } /** * Calculates hash code for double array. */ public static int hash(int seed, double[] doubleArray) { if (doubleArray == null) { return 0; } for (double aDouble : doubleArray) { seed = hash(seed, aDouble); } return seed; } /** * Calculates hash code for double array. */ public static int hashDoubleArray(int seed, double... doubleArray) { return hash(seed, doubleArray); } // ---------------------------------------------------------------- object /** * Calculates hash code for Objects. Object is a possibly-null object field, and possibly an array. * <p> * If <code>aObject</code> is an array, then each element may be a primitive * or a possibly-null object. */ public static int hash(int seed, Object aObject) { int result = seed; if (aObject == null) { result = hash(result, 0); } else if (aObject.getClass().isArray() == false) { result = hash(result, aObject.hashCode()); } else { Object[] objects = (Object[]) aObject; int length = objects.length; for (int idx = 0; idx < length; ++idx) { result = hash(result, objects[idx]); } } return result; } }
package com.easy.utils; import static com.easy.utils.HashCode.hash; import java.io.Serializable; import java.math.BigDecimal; /** * Julian Date stamp, for high precision calculations. Julian date is a real * number and it basically consist of two parts: integer and fraction. Integer * part carries date information, fraction carries time information. * * <p> * The Julian day or Julian day number (JDN) is the (integer) number of days that * have elapsed since Monday, January 1, 4713 BC in the proleptic Julian calendar 1. * That day is counted as Julian day zero. Thus the multiples of 7 are Mondays. * Negative values can also be used. * * <p> * The Julian Date (JD) is the number of days (with decimal fraction of the day) that * have elapsed since 12 noon Greenwich Mean Time (UT or TT) of that day. * Rounding to the nearest integer gives the Julian day number. * <p> * For calculations that will have time precision of 1e-3 seconds, both * fraction and integer part must have enough digits in it. The problem is * that integer part is big and, on the other hand fractional is small, and * since final julian date is a sum of this two values, some fraction * numerals may be lost. Therefore, for higher precision both * fractional and integer part of julian date real number has to be * preserved. * <p> * This class stores the unmodified fraction part, but not all digits * are significant! For 1e-3 seconds precision, only 8 digits after * the decimal point are significant. * * @see TimeUtil * @see JDateTime * @see DateTimeStamp */ public class JulianDateStamp implements Serializable, Cloneable { /** * Integer part of the Julian Date (JD). */ protected int integer; /** * Returns integer part of the Julian Date (JD). */ public int getInteger() { return integer; } /** * Fraction part of the Julian Date (JD). * Should be always in [0.0, 1.0) range. */ protected double fraction; /** * Returns the fraction part of Julian Date (JD). * Returned value is always in [0.0, 1.0) range. */ public double getFraction() { return fraction; } /** * Calculates and returns significant fraction only as an int. */ public int getSignificantFraction() { return (int) (fraction * 100000000); } /** * Returns JDN. Note that JDN is not equal to {@link #integer}. It is calculated by * rounding to the nearest integer. */ public int getJulianDayNumber() { if (fraction >= 0.5) { return integer + 1; } return integer; } // ---------------------------------------------------------------- ctors /** * Default empty constructor. */ public JulianDateStamp() { } /** * Creates JD from a <code>double</code>. */ public JulianDateStamp(double jd) { set(jd); } /** * Creates JD from both integer and fractional part using normalization. * Normalization occurs when fractional part is out of range. * * @see #set(int, double) * * @param i integer part * @param f fractional part should be in range [0.0, 1.0) */ public JulianDateStamp(int i, double f) { set(i, f); } /** * Creates JD from <code>BigDecimal</code>. */ public JulianDateStamp(BigDecimal bd) { double d = bd.doubleValue(); integer = (int) d; bd = bd.subtract(new BigDecimal(integer)); fraction = bd.doubleValue(); } // ---------------------------------------------------------------- conversion /** * Returns <code>double</code> value of JD. * <b>CAUTION</b>: double values may not be suit for precision math due to * loss of precision. */ public double doubleValue() { return (double)integer + fraction; } /** * Returns <code>BigDecimal</code> value of JD. */ @SuppressWarnings({"UnpredictableBigDecimalConstructorCall"}) public BigDecimal toBigDecimal() { BigDecimal bd = new BigDecimal(integer); return bd.add(new BigDecimal(fraction)); } /** * Returns string representation of JD. * * @return julian integer as string */ @Override public String toString() { String s = Double.toString(fraction); int i = s.indexOf('.'); s = s.substring(i); return integer + s; } // ---------------------------------------------------------------- math /** * Adds a JD to current instance. */ public JulianDateStamp add(JulianDateStamp jds) { int i = this.integer + jds.integer; double f = this.fraction + jds.fraction; set(i, f); return this; } /** * Adds a double to current instance. */ public JulianDateStamp add(double delta) { set(this.integer, this.fraction + delta); return this; } /** * Subtracts a JD from current instance. */ public JulianDateStamp sub(JulianDateStamp jds) { int i = this.integer - jds.integer; double f = this.fraction -jds.fraction; set(i, f); return this; } /** * Subtracts a double from current instance. */ public JulianDateStamp sub(double delta) { set(this.integer, this.fraction - delta); return this; } /** * Sets integer and fractional part with normalization. * Normalization means that if double is out of range, * values will be correctly fixed. */ public void set(int i, double f) { integer = i; int fi = (int) f; f -= fi; integer += fi; if (f < 0) { f += 1; integer--; } this.fraction = f; } public void set(double jd) { integer = (int)jd; fraction = jd - (double)integer; } // ---------------------------------------------------------------- between /** * Calculates the number of days between two dates. Returned value is always positive. */ public int daysBetween(JulianDateStamp otherDate) { int difference = daysSpan(otherDate); return difference >= 0 ? difference : -difference; } /** * Returns span between two days. Returned value may be positive (when this date * is after the provided one) or negative (when comparing to future date). */ public int daysSpan(JulianDateStamp otherDate) { int now = getJulianDayNumber(); int then = otherDate.getJulianDayNumber(); return now - then; } // ---------------------------------------------------------------- equals & hashCode @Override public boolean equals(Object object) { if (this == object) { return true; } if (!(object instanceof JulianDateStamp)) { return false; } JulianDateStamp stamp = (JulianDateStamp) object; return (stamp.integer == this.integer) && (Double.compare(stamp.fraction, this.fraction) == 0); } @Override public int hashCode() { int result = HashCode.SEED; result = hash(result, integer); result = hash(result, fraction); return result; } // ---------------------------------------------------------------- clone @Override protected JulianDateStamp clone() { return new JulianDateStamp(this.integer, this.fraction); } // ---------------------------------------------------------------- conversion /** * Returns Reduced Julian Date (RJD), used by astronomers. * RJD = JD 鈭�2400000 */ public JulianDateStamp getReducedJulianDate() { return new JulianDateStamp(integer - 2400000, fraction); } public void setReducedJulianDate(double rjd) { set(rjd + 2400000); } /** * Returns Modified Julian Date (MJD), where date starts from midnight rather than noon. * RJD = JD 鈭�2400000.5 */ public JulianDateStamp getModifiedJulianDate() { return new JulianDateStamp(integer - 2400000, fraction - 0.5); } public void setModifiedJulianDate(double mjd) { set(mjd + 2400000.5); } /** * Returns Truncated Julian Day (TJD), introduced by NASA for the space program. * TJD began at midnight at the beginning of May 24, 1968 (Friday). */ public JulianDateStamp getTruncatedJulianDate() { return new JulianDateStamp(integer - 2440000, fraction - 0.5); } public void setTruncatedJulianDate(double tjd) { set(tjd + 2440000.5); } }
相关推荐
在VB(Visual Basic)环境中,有时候我们需要将日期转换为朱利安日(Julian Date),这是一种特殊的日期表示方式,主要用于天文学和气象学,但也在软件开发中有所应用。朱利安日是从公元前4713年1月1日中午12点...
在信息技术领域,我们经常遇到需要处理日期和时间的问题,尤其是在天文计算、科学数据处理以及各种需要精确时间间隔计算的应用中。朱利安日期(Julian Date,简称JD)是一种全球统一的时间表示方式,它以连续的整数...
在IT行业中,理解和使用这种日期格式对于处理时间序列数据或进行时间计算时非常有用。 描述中提到这是一个简单的Shell脚本,表明这个工具是基于Unix/Linux shell编程语言编写的,适用于命令行环境。shell脚本是编写...
首先,这是一个儒略日和公历相互转化的java程序源码文件,可以被用于科研计算中日期的处理与前后端日期数据的转换处理等方面。 因为在科研数值计算的过程中,常常会遇到需要将日期转化为儒略日(一年中的第几天)的...
**MJD(Modified Julian Date)**,即修改后的儒略日,是天文学中常用的一种时间表示方式。它从儒略日(Julian Day)的基础上做了调整,将儒略日的起始点从公元前4713年1月1日中午12点移到了公元1858年11月17日的...
function julianDate = jl_date(dateVec) % 创建基准日期 基准日期 = datetime('004713-01-01', 'InputFormat', 'yyyy-MM-dd'); % 将输入日期向量转换为datetime对象 inputDate = datetime(dateVec, '...
为了实现跨世纪的日期查询,可以结合DateTime和Calendar类,编写一个通用函数,接受任何年份、月份和日期,返回对应的星期几: ```csharp public DayOfWeek GetDayOfWeek(int year, int month, int day) { ...
而儒略日期则是一种在天文学和气象学中普遍采用的连续日期系统,能够方便地进行日期计算和时间跨度比较。在MATLAB编程环境中,处理这两种日期格式的转换对于数据分析和计算具有重要意义。 本项目提供的MATLAB程序...
本文将详细介绍如何在MATLAB中实现格里高利历、儒略日、GPS时间和年积日之间的相互转换。 首先,格里高利历是我们日常生活中最常用的时间表示方式,它是由教宗格里高利十三世于1582年推行的,取代了之前的儒略历。...
首先,我们需要计算当前日期对应的儒略日(Julian Day),然后根据经纬度找出该地点的天文方位角,最后确定日出、日中和日落的具体时刻。 JavaScript作为Web开发的主要语言,也可以轻松实现这一功能。在浏览器环境...
例如,如果我们有一个日期`myDate = datetime('2022-01-01')`,我们可以用`julianDate = date2julian(myDate)`来得到对应的儒略日期。 接下来,展示日历通常会涉及使用`calendar`函数。此函数可以生成一个二维数组...
viewer.clock.stopTime = Cesium.JulianDate.addSeconds(viewer.clock.startTime, 60 * 60 * 24); // 设置24小时后停止 viewer.clock.currentTime = viewer.clock.startTime; viewer.clock.multiplier = 1; // 时间...
在Java中,日期和时间的处理通常会用到`java.util.Date`、`java.time.LocalDate`等类,但此代码实现可能自定义了类来处理特定的日期和时间计算,例如文档中的`SolarTerm`类。 5. **天文算法**: 实现万年历需要...
而`JulianDate.java`则可能是一个 julian 日历(儒略日)类,用于辅助进行日期转换,因为在中国农历和公历之间转换时,儒略日是一种常见的中间计算工具。 在实际的源码实现中,`LunarCalendar`可能会包含以下方法:...
### 卫星导航电文格式及卫星位置计算 #### 一、时间系统 **1.... - **定义**: TAI是一种...这些时间系统在卫星导航领域中发挥着至关重要的作用,不仅用于准确地记录和描述时间,还对于实现高精度的位置确定至关重要。
标题“matlab开发-转换juliandatetonormaldate”指的是一个MATLAB程序,它能够将儒略日期(Julian Date)转换为普通日期(Normal Date)。儒略日期是一种国际上广泛使用的连续日计数系统,起源于公元前4713年1月1日...
julianDate = julian(currentDateTime); ``` 5. **日期标签**:在数据可视化中,我们可能需要将日期作为轴标签,`datetick`函数可以帮助我们实现这一目标: ```matlab plot(1:365, rand(1, 365)); % 假设这是一年...
儒略日(Julian Day Number, JDN)是一个连续的日数系统,从公元前4713年1月1日中午12点开始计算,这个日期在格里高利历(公历)中被称为儒略历的起点。儒略日是一种无歧义的日期表示方式,对于跨文化、跨历法的数据...
在安卓开发中,我们可以利用现有的开源库或者自己编写算法来实现农历和节气的计算。例如,开源库`androidx.core.utils.CalendarUtils`虽然不直接支持农历和节气计算,但可以作为基础工具处理日期和时间。如果需要...
"julian.m"文件则很可能是一个实现朱利安日期(Julian Date)转换的函数。朱利安日期是一种在天文学中广泛使用的连续时间尺度,便于处理跨越世纪的日期和时间。 最后,"demo_nut2000a.m"是一个演示脚本,用于展示...