📄 bigdate.java
字号:
}
/**
* Returns a BigDate object initialised to today's local date. It depends on Java's default Timezone being
* configured, and your system clock accurately set to UTC time. Experiment setting your system date/time to various
* values and making sure you are getting the expected results. Note the date in the created object does not keep
* updating every time you reference it with methods like getOrdinal or getDD. You always get the date the object
* was created. It is quite a production to get the local date. Best to ask once and save the today object.
*
* @return BigDate object initialised to today, local time.
* @see #today #see #UTCToday
*/
public static BigDate localToday()
{
return today( TimeZone.getDefault() );
}// end localToday
/**
* Get 3-char abbreviation of a given month of the year.
*
* @param mm month number jan = 1
* @return abbreviation for month, e.g. "Jan"
*/
public static String monthAbbr( int mm )
{
return monthAbbr[ mm ];
}
/**
* Get full name of a given month of the year.
*
* @param mm month number jan = 1
* @return name of month e.g. "January"
*/
public static String monthName( int mm )
{
return monthName[ mm ];
}
/**
* Find the first monday in a given month, the 3rd monday or the last Thursday...
*
* @param which 1=first 2=second 3=third 4=fourth 5=last (might be 4th or 5th)
* @param dayOfWeek 0=Sunday 1=Monday 2=Tuesday 3=Wednesday 4=Thursday 5=Friday 6=Saturday WARNING: not compatible
* with 1=Calendar.SUNDAY.
* @param yyyy year of interest.
* @param mm month 1 to 12 (not 0 to 11 as in Sun's Date), no lead 0.
* @return day of month 1..31
*/
public static int nthXXXDay( int which, int dayOfWeek, int yyyy, int mm )
{
int dayOfWeekOf1st = BigDate
.dayOfWeek( BigDate.toOrdinal( yyyy, mm, 1 ) );
int dayOfMonthOfFirstDesiredDay =
( dayOfWeek - dayOfWeekOf1st + 7 ) % 7 + 1;
int dayOfMonthOfNthDesiredDay =
dayOfMonthOfFirstDesiredDay + ( which - 1 ) * 7;
if ( which >= 5 && dayOfMonthOfNthDesiredDay > daysInMonth( mm, yyyy ) )
{
dayOfMonthOfNthDesiredDay -= 7;
}
return dayOfMonthOfNthDesiredDay;
}// end nthXXXDay
/**
* Find the first monday in a given month, the 3rd monday or the last Thursday...
*
* @param which 1=first 2=second 3=third 4=fourth 5=last (might be 4th or 5th)
* @param dayOfWeek 0=Sunday 1=Monday 2=Tuesday 3=Wednesday 4=Thursday 5=Friday 6=Saturday WARNING: not compatible
* with 1=Calendar.SUNDAY.
* @param yyyy year of interest.
* @param mm month 1 to 12 (not 0 to 11 as in Sun's Date), no lead 0.
* @return day of month 1..31
*/
public static int ordinalOfnthXXXDay( int which,
int dayOfWeek,
int yyyy,
int mm )
{
int dayOfMonthOfNthDesiredDay = nthXXXDay( which, dayOfWeek, yyyy, mm );
return BigDate.toOrdinal( yyyy, mm, dayOfMonthOfNthDesiredDay );
}// end ordinalOfnthXXXDay
/**
* Convert date in form YYYY MM DD into days since the 1970 Jan 01. This method lets you convert directly from
* Gregorian to ordinal without creating a BigDate object. yyyy mm dd must be a valid date.
*
* @param yyyy -999,999 (BC) to +999,999 (AD)
* @param mm month 1 to 12 (not 0 to 11 as in Sun's Date), no lead 0.
* @param dd day 1 to 31, no lead 0.
* @return ordinal, days since 1970 Jan 01.
*/
public static int toOrdinal( int yyyy, int mm, int dd )
{
// treat null date as a special case
if ( ( yyyy == 0 ) && ( mm == 0 ) && ( dd == 0 ) )
{
return NULL_ORDINAL;
}
// jan01OfYear handles missing day adjustment for years > 1582
// We only need to handle year = 1582 here.
int missingDayAdjust =
( yyyy == OJC_lastYYYY && ( ( mm == OJC_lastMM
&& dd > OJC_lastDD )
|| mm > OJC_lastMM ) )
? missingDays
: 0;
return jan01OfYear( yyyy ) + daysInYearPriorToMonth( mm,
isLeap( yyyy ) )
- missingDayAdjust + dd - 1;
}// end toOrdinal
/**
* Returns a BigDate object initialised to the date right now in the given timezone. It depends on your system clock
* accurately set to UTC time. Experiment setting your system date/time to various values and making sure you are
* getting the expected results. Note the date in the created object does not keep updating every time you reference
* it with methods like getOrdinal or getDD. You always get the date the object was created. It is quite a
* production to get the this date. Best to ask once and save the today object.
*
* @param timeZone in which we want to know the today's date.
* @return BigDate object initialised to today at given timezone.
* @see #localToday
* @see #UTCToday
*/
public static BigDate today( TimeZone timeZone )
{
BigDate d = new BigDate();
d.setDateAtTime( System.currentTimeMillis(), timeZone );
return d;
}// end today
// -------------------------- PUBLIC INSTANCE METHODS --------------------------
// don't move this up with other publics since it requires privates
// for its definition.
// c o n s t r u c t o r s
/**
* Constructor for the null date. Gets set to null date, NOT current date like Java Date!!. BigDate.localToday()
* will create an object initialised to today's date.
*
* @see #localToday
* @see #UTCToday
* @see #today
*/
public BigDate()
{
}
/**
* Construct a BigDate object given the Proleptic Julian day number. The Proleptic Julian calendar that astronomers
* use starts with 0 at noon on 4713 BCE January 1. In contrast, BigDate's Ordinal base is 1970 Jan 1.
*
* @param prolepticJulianDay days since 4713 BC Jan 1 noon. Such numbers usually arise in astronomical calculation.
* You don't need to concern yourself with the strangeness of the Julian calendar, just
* its simple day numbering. BEWARE! after adjusting for noon, fractional parts are
* discarded. BigDate tracks only dates, not dates and times. e.g. 2000-03-20 noon is
* 2,451,624 in proleptic day numbers. 1970-1-1 is 2,440,588 1600-1-1 is 2,305,448
* 1500-1-1 is 2,268,933 0001-1-1 is 1,721,424 -0001-12-31 is 1,721,423 -0006-1-1 is
* 1,719,232 -4713-1-1 is 0
*/
public BigDate( double prolepticJulianDay )
{
setOrdinal( ( int ) ( ( long ) ( prolepticJulianDay + 0.5/*
* noon adjust,
* .5 or bigger
* really part
* of next day
*/ ) - 2440588L/*
* i.e. diff in base epochs of calendars
*/ ) );
}// end BigDate constructor
/**
* Ordinal constructor. The ordinal must be NULL_ORDINAL or in the range -365968798 to 364522971 i.e. 999,999 BC to
* 999,999 AD
*
* @param ordinal days since 1970 Jan 01.
*/
public BigDate( int ordinal )
{
// save ordinal field and compute Gregorian equivalent
set( ordinal );
}// end BigDate constructor
/**
* Create a BigDate object from a String of the form: yyyy-mm-dd must have 4-digit years, and use dashes between the
* number and no sign Does extensive checks considering leap years, missing days etc.
*
* @param yyyy_mm_dd string of form "yyyy-mm-dd".
*/
public BigDate( String yyyy_mm_dd )
{
try
{
if ( yyyy_mm_dd.length() != 10 )
{
throw new IllegalArgumentException( "invalid date: "
+ yyyy_mm_dd );
}
int yyyy = Integer.parseInt( yyyy_mm_dd.substring( 0, 4 ) );
int mm = Integer.parseInt( yyyy_mm_dd.substring( 5, 7 ) );
int dd = Integer.parseInt( yyyy_mm_dd.substring( 8, 10 ) );
set( yyyy, mm, dd, CHECK );
}
catch ( NumberFormatException e )
{
throw new IllegalArgumentException( "invalid date: " + yyyy_mm_dd );
}
}
// end BigDate constructor
/**
* Copy constructor
*
* @param b an existing BigDate object to use as a model for cloning another.
*/
public BigDate( BigDate b )
{
this.ordinal = b.ordinal;
this.yyyy = b.yyyy;
this.mm = b.mm;
this.dd = b.dd;
}
/**
* Constructor from Date, loses time information.
*
* @param utc Date ( UTC date/time stamp )
* @param timeZone Which timeZone do you want to know the date for that UTC time. e.g. TimeZone.getDefault(), new
* TimeZone("GMT")
*/
public BigDate( Date utc, TimeZone timeZone )
{
setDateAtTime( utc.getTime(), timeZone );
}
/**
* Construct a BigDate object given a Gregorian date yyyy, mm, dd; always rejects invalid dates. A null date is
* yyyy,mm,dd=0. BEWARE! In Java a lead 0 on an integer implies OCTAL.
*
* @param yyyy -999,999 (BC) to +999,999 (AD)
* @param mm month 1 to 12 (not 0 to 11 as in Sun's Date), no lead 0.
* @param dd day 1 to 31, no lead 0.
* @throws IllegalArgumentException for invalid yyyy mm dd
*/
public BigDate( int yyyy, int mm, int dd )
{
set( yyyy, mm, dd, CHECK );
}// end BigDate constructor
/**
* Construct a BigDate object given a Gregorian date yyyy, mm, dd; allows control of how invalid dates are handled.
* A null date is yyyy,mm,dd=0. BEWARE! In Java a lead 0 on an integer implies OCTAL.
*
* @param yyyy -999,999 (BC) to +999,999 (AD)
* @param mm month 1 to 12 (not 0 to 11 as in Sun's Date), no lead 0.
* @param dd day 1 to 31, no lead 0.
* @param how one of CHECK BYPASSCHECK NORMALIZE NORMALISE
*/
public BigDate( int yyyy, int mm, int dd, int how )
{
// save yyyy, mm, dd, and compete the ordinal equivalent
set( yyyy, mm, dd, how );
}// end BigDate constructor
/**
* increment this date by a number of days.
*
* @param days positive or negative, -1 gets day before this one.
*/
public final void addDays( int days )
{
if ( days == 0 )
{
return;
}
this.ordinal += days;
toGregorian();
}// end addDays
/**
* Get day of week for this BigDate. It is one-based starting with Sunday.
*
* @return day of week 1=Sunday 2=Monday 3=Tuesday 4=Wednesday 5=Thursday 6=Friday 7=Saturday Compatible with Sun's
* 1=Calendar.SUNDAY Not compatible with BigDate.getDayOfWeek.
* @see #isoDayOfWeek
* @see #dayOfWeek
* @see #getCalendarDayOfWeek
*/
public int calendarDayOfWeek()
{
return calendarDayOfWeek( this.ordinal );
}
/**
* Defines Natural Order for the BigDate class. Determines if this date comes after some other date. Conceptually
* returns (this - anotherBigDate). compareTo() == 0 is faster than equals().
*
* @param anotherBigDate date to compare against
* @return a positive number if this date > (after) anotherBigDate.<br/> zero if this date = anotherBigDate.<br/> a
* negative number if this date < (before) anotherBigDate.
*/
public final int compareTo( Object anotherBigDate )
{
return this.ordinal - ( ( BigDate ) anotherBigDate ).ordinal;
}
/**
* Get day of week for this BigDate. Is it zero-based starting with Sunday.
*
* @return day of week 0=Sunday 1=Monday 2=Tuesday 3=Wednesday 4=Thursday 5=Friday 6=Saturday WARNING: not
* compatible with 1=Calendar.SUNDAY
* @see #calendarDayOfWeek
* @see #isoDayOfWeek
* @see #getDayOfWeek
*/
public int dayOfWeek()
{
return dayOfWeek( this.ordinal );
}
/**
* Compares with another BigDate to see if they refer to the same date.
*
* @param d other BigDate to compare with this one.
* @return true if BigDate d refers to the same date
*/
public final boolean equals( Object d )
{
return d == this || d instanceof BigDate && ( ordinal == ( ( BigDate ) d ).getOrdinal() );
}
/**
* Get day of week for this BigDate. Is it one-based starting with Sunday.
*
* @return day of week 1=Sunday 2=Monday 3=Tuesday 4=Wednesday 5=Thursday 6=Friday 7=Saturday Compatible with Sun's
* 1=Calendar.SUNDAY Not compatible with BigDate.getDayOfWee
* @see #getISODayOfWeek
* @see #getDayOfWeek
* @see #calendarDayOfWeek
*/
public final int getCalendarDayOfWeek()
{
return calendarDayOfWeek( ordinal );
}
/**
* get day of month for this BigDate.
*
* @return day 1 to 31, 0 for null date.
*/
public final int getDD()
{
return dd;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -