use of sun.util.calendar.BaseCalendar in project j2objc by google.
the class GregorianCalendar method getActualMaximum.
/**
* Returns the maximum value that this calendar field could have,
* taking into consideration the given time value and the current
* values of the
* {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
* {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
* {@link #getGregorianChange() getGregorianChange} and
* {@link Calendar#getTimeZone() getTimeZone} methods.
* For example, if the date of this instance is February 1, 2004,
* the actual maximum value of the <code>DAY_OF_MONTH</code> field
* is 29 because 2004 is a leap year, and if the date of this
* instance is February 1, 2005, it's 28.
*
* <p>This method calculates the maximum value of {@link
* Calendar#WEEK_OF_YEAR WEEK_OF_YEAR} based on the {@link
* Calendar#YEAR YEAR} (calendar year) value, not the <a
* href="#week_year">week year</a>. Call {@link
* #getWeeksInWeekYear()} to get the maximum value of {@code
* WEEK_OF_YEAR} in the week year of this {@code GregorianCalendar}.
*
* @param field the calendar field
* @return the maximum of the given field for the time value of
* this <code>GregorianCalendar</code>
* @see #getMinimum(int)
* @see #getMaximum(int)
* @see #getGreatestMinimum(int)
* @see #getLeastMaximum(int)
* @see #getActualMinimum(int)
* @since 1.2
*/
@Override
public int getActualMaximum(int field) {
final int fieldsForFixedMax = ERA_MASK | DAY_OF_WEEK_MASK | HOUR_MASK | AM_PM_MASK | HOUR_OF_DAY_MASK | MINUTE_MASK | SECOND_MASK | MILLISECOND_MASK | ZONE_OFFSET_MASK | DST_OFFSET_MASK;
if ((fieldsForFixedMax & (1 << field)) != 0) {
return getMaximum(field);
}
GregorianCalendar gc = getNormalizedCalendar();
BaseCalendar.Date date = gc.cdate;
BaseCalendar cal = gc.calsys;
int normalizedYear = date.getNormalizedYear();
int value = -1;
switch(field) {
case MONTH:
{
if (!gc.isCutoverYear(normalizedYear)) {
value = DECEMBER;
break;
}
// January 1 of the next year may or may not exist.
long nextJan1;
do {
nextJan1 = gcal.getFixedDate(++normalizedYear, BaseCalendar.JANUARY, 1, null);
} while (nextJan1 < gregorianCutoverDate);
BaseCalendar.Date d = (BaseCalendar.Date) date.clone();
cal.getCalendarDateFromFixedDate(d, nextJan1 - 1);
value = d.getMonth() - 1;
}
break;
case DAY_OF_MONTH:
{
value = cal.getMonthLength(date);
if (!gc.isCutoverYear(normalizedYear) || date.getDayOfMonth() == value) {
break;
}
// Handle cutover year.
long fd = gc.getCurrentFixedDate();
if (fd >= gregorianCutoverDate) {
break;
}
int monthLength = gc.actualMonthLength();
long monthEnd = gc.getFixedDateMonth1(gc.cdate, fd) + monthLength - 1;
// Convert the fixed date to its calendar date.
BaseCalendar.Date d = gc.getCalendarDate(monthEnd);
value = d.getDayOfMonth();
}
break;
case DAY_OF_YEAR:
{
if (!gc.isCutoverYear(normalizedYear)) {
value = cal.getYearLength(date);
break;
}
// Handle cutover year.
long jan1;
if (gregorianCutoverYear == gregorianCutoverYearJulian) {
BaseCalendar cocal = gc.getCutoverCalendarSystem();
jan1 = cocal.getFixedDate(normalizedYear, 1, 1, null);
} else if (normalizedYear == gregorianCutoverYearJulian) {
jan1 = cal.getFixedDate(normalizedYear, 1, 1, null);
} else {
jan1 = gregorianCutoverDate;
}
// January 1 of the next year may or may not exist.
long nextJan1 = gcal.getFixedDate(++normalizedYear, 1, 1, null);
if (nextJan1 < gregorianCutoverDate) {
nextJan1 = gregorianCutoverDate;
}
assert jan1 <= cal.getFixedDate(date.getNormalizedYear(), date.getMonth(), date.getDayOfMonth(), date);
assert nextJan1 >= cal.getFixedDate(date.getNormalizedYear(), date.getMonth(), date.getDayOfMonth(), date);
value = (int) (nextJan1 - jan1);
}
break;
case WEEK_OF_YEAR:
{
if (!gc.isCutoverYear(normalizedYear)) {
// Get the day of week of January 1 of the year
CalendarDate d = cal.newCalendarDate(TimeZone.NO_TIMEZONE);
d.setDate(date.getYear(), BaseCalendar.JANUARY, 1);
int dayOfWeek = cal.getDayOfWeek(d);
// Normalize the day of week with the firstDayOfWeek value
dayOfWeek -= getFirstDayOfWeek();
if (dayOfWeek < 0) {
dayOfWeek += 7;
}
value = 52;
int magic = dayOfWeek + getMinimalDaysInFirstWeek() - 1;
if ((magic == 6) || (date.isLeapYear() && (magic == 5 || magic == 12))) {
value++;
}
break;
}
if (gc == this) {
gc = (GregorianCalendar) gc.clone();
}
int maxDayOfYear = getActualMaximum(DAY_OF_YEAR);
gc.set(DAY_OF_YEAR, maxDayOfYear);
value = gc.get(WEEK_OF_YEAR);
if (internalGet(YEAR) != gc.getWeekYear()) {
gc.set(DAY_OF_YEAR, maxDayOfYear - 7);
value = gc.get(WEEK_OF_YEAR);
}
}
break;
case WEEK_OF_MONTH:
{
if (!gc.isCutoverYear(normalizedYear)) {
CalendarDate d = cal.newCalendarDate(null);
d.setDate(date.getYear(), date.getMonth(), 1);
int dayOfWeek = cal.getDayOfWeek(d);
int monthLength = cal.getMonthLength(d);
dayOfWeek -= getFirstDayOfWeek();
if (dayOfWeek < 0) {
dayOfWeek += 7;
}
// # of days in the first week
int nDaysFirstWeek = 7 - dayOfWeek;
value = 3;
if (nDaysFirstWeek >= getMinimalDaysInFirstWeek()) {
value++;
}
monthLength -= nDaysFirstWeek + 7 * 3;
if (monthLength > 0) {
value++;
if (monthLength > 7) {
value++;
}
}
break;
}
// Cutover year handling
if (gc == this) {
gc = (GregorianCalendar) gc.clone();
}
int y = gc.internalGet(YEAR);
int m = gc.internalGet(MONTH);
do {
value = gc.get(WEEK_OF_MONTH);
gc.add(WEEK_OF_MONTH, +1);
} while (gc.get(YEAR) == y && gc.get(MONTH) == m);
}
break;
case DAY_OF_WEEK_IN_MONTH:
{
// may be in the Gregorian cutover month
int ndays, dow1;
int dow = date.getDayOfWeek();
if (!gc.isCutoverYear(normalizedYear)) {
BaseCalendar.Date d = (BaseCalendar.Date) date.clone();
ndays = cal.getMonthLength(d);
d.setDayOfMonth(1);
cal.normalize(d);
dow1 = d.getDayOfWeek();
} else {
// Let a cloned GregorianCalendar take care of the cutover cases.
if (gc == this) {
gc = (GregorianCalendar) clone();
}
ndays = gc.actualMonthLength();
gc.set(DAY_OF_MONTH, gc.getActualMinimum(DAY_OF_MONTH));
dow1 = gc.get(DAY_OF_WEEK);
}
int x = dow - dow1;
if (x < 0) {
x += 7;
}
ndays -= x;
value = (ndays + 6) / 7;
}
break;
case YEAR:
/* The year computation is no different, in principle, from the
* others, however, the range of possible maxima is large. In
* addition, the way we know we've exceeded the range is different.
* For these reasons, we use the special case code below to handle
* this field.
*
* The actual maxima for YEAR depend on the type of calendar:
*
* Gregorian = May 17, 292275056 BCE - Aug 17, 292278994 CE
* Julian = Dec 2, 292269055 BCE - Jan 3, 292272993 CE
* Hybrid = Dec 2, 292269055 BCE - Aug 17, 292278994 CE
*
* We know we've exceeded the maximum when either the month, date,
* time, or era changes in response to setting the year. We don't
* check for month, date, and time here because the year and era are
* sufficient to detect an invalid year setting. NOTE: If code is
* added to check the month and date in the future for some reason,
* Feb 29 must be allowed to shift to Mar 1 when setting the year.
*/
{
if (gc == this) {
gc = (GregorianCalendar) clone();
}
// Calculate the millisecond offset from the beginning
// of the year of this calendar and adjust the max
// year value if we are beyond the limit in the max
// year.
long current = gc.getYearOffsetInMillis();
if (gc.internalGetEra() == CE) {
gc.setTimeInMillis(Long.MAX_VALUE);
value = gc.get(YEAR);
long maxEnd = gc.getYearOffsetInMillis();
if (current > maxEnd) {
value--;
}
} else {
CalendarSystem mincal = gc.getTimeInMillis() >= gregorianCutover ? gcal : getJulianCalendarSystem();
CalendarDate d = mincal.getCalendarDate(Long.MIN_VALUE, getZone());
long maxEnd = (cal.getDayOfYear(d) - 1) * 24 + d.getHours();
maxEnd *= 60;
maxEnd += d.getMinutes();
maxEnd *= 60;
maxEnd += d.getSeconds();
maxEnd *= 1000;
maxEnd += d.getMillis();
value = d.getYear();
if (value <= 0) {
assert mincal == gcal;
value = 1 - value;
}
if (current < maxEnd) {
value--;
}
}
}
break;
default:
throw new ArrayIndexOutOfBoundsException(field);
}
return value;
}
use of sun.util.calendar.BaseCalendar in project j2objc by google.
the class GregorianCalendar method setGregorianChange.
private void setGregorianChange(long cutoverTime) {
gregorianCutover = cutoverTime;
gregorianCutoverDate = CalendarUtils.floorDivide(cutoverTime, ONE_DAY) + EPOCH_OFFSET;
// a pure Julian calendar. (See 4167995)
if (cutoverTime == Long.MAX_VALUE) {
gregorianCutoverDate++;
}
BaseCalendar.Date d = getGregorianCutoverDate();
// Set the cutover year (in the Gregorian year numbering)
gregorianCutoverYear = d.getYear();
BaseCalendar julianCal = getJulianCalendarSystem();
d = (BaseCalendar.Date) julianCal.newCalendarDate(TimeZone.NO_TIMEZONE);
julianCal.getCalendarDateFromFixedDate(d, gregorianCutoverDate - 1);
gregorianCutoverYearJulian = d.getNormalizedYear();
if (time < gregorianCutover) {
// The field values are no longer valid under the new
// cutover date.
setUnnormalized();
}
}
use of sun.util.calendar.BaseCalendar in project j2objc by google.
the class SimpleTimeZone method getOffset.
/**
* Returns the difference in milliseconds between local time and
* UTC, taking into account both the raw offset and the effect of
* daylight saving, for the specified date and time. This method
* assumes that the start and end month are distinct. It also
* uses a default {@link GregorianCalendar} object as its
* underlying calendar, such as for determining leap years. Do
* not use the result of this method with a calendar other than a
* default <code>GregorianCalendar</code>.
*
* <p><em>Note: In general, clients should use
* <code>Calendar.get(ZONE_OFFSET) + Calendar.get(DST_OFFSET)</code>
* instead of calling this method.</em>
*
* @param era The era of the given date.
* @param year The year in the given date.
* @param month The month in the given date. Month is 0-based. e.g.,
* 0 for January.
* @param day The day-in-month of the given date.
* @param dayOfWeek The day-of-week of the given date.
* @param millis The milliseconds in day in <em>standard</em> local time.
* @return The milliseconds to add to UTC to get local time.
* @exception IllegalArgumentException the <code>era</code>,
* <code>month</code>, <code>day</code>, <code>dayOfWeek</code>,
* or <code>millis</code> parameters are out of range
*/
public int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis) {
if (era != GregorianCalendar.AD && era != GregorianCalendar.BC) {
throw new IllegalArgumentException("Illegal era " + era);
}
int y = year;
if (era == GregorianCalendar.BC) {
// adjust y with the GregorianCalendar-style year numbering.
y = 1 - y;
}
// can't be supported by the Java time system.
if (y >= 292278994) {
y = 2800 + y % 2800;
} else if (y <= -292269054) {
// y %= 28 also produces an equivalent year, but positive
// year numbers would be convenient to use the UNIX cal
// command.
y = (int) CalendarUtils.mod((long) y, 28);
}
// convert year to its 1-based month value
int m = month + 1;
// First, calculate time as a Gregorian date.
BaseCalendar cal = gcal;
BaseCalendar.Date cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE);
cdate.setDate(y, m, day);
// normalize cdate
long time = cal.getTime(cdate);
// UTC time
time += millis - rawOffset;
// style year numbering (..., -1, 0 (BCE 1), 1, 2, ...).
if (time < GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER) {
cal = (BaseCalendar) CalendarSystem.forName("julian");
cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE);
cdate.setNormalizedDate(y, m, day);
time = cal.getTime(cdate) + millis - rawOffset;
}
if ((cdate.getNormalizedYear() != y) || (cdate.getMonth() != m) || (cdate.getDayOfMonth() != day) || // compatibility.
(dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) || (millis < 0 || millis >= (24 * 60 * 60 * 1000))) {
throw new IllegalArgumentException();
}
if (!useDaylight || year < startYear || era != GregorianCalendar.CE) {
return rawOffset;
}
return getOffset(cal, cdate, y, time);
}
use of sun.util.calendar.BaseCalendar in project j2objc by google.
the class Date method normalize.
// fastTime and the returned data are in sync upon return.
private final BaseCalendar.Date normalize(BaseCalendar.Date date) {
int y = date.getNormalizedYear();
int m = date.getMonth();
int d = date.getDayOfMonth();
int hh = date.getHours();
int mm = date.getMinutes();
int ss = date.getSeconds();
int ms = date.getMillis();
TimeZone tz = date.getZone();
// transition here.
if (y == 1582 || y > 280000000 || y < -280000000) {
if (tz == null) {
tz = TimeZone.getTimeZone("GMT");
}
GregorianCalendar gc = new GregorianCalendar(tz);
gc.clear();
gc.set(GregorianCalendar.MILLISECOND, ms);
gc.set(y, m - 1, d, hh, mm, ss);
fastTime = gc.getTimeInMillis();
BaseCalendar cal = getCalendarSystem(fastTime);
date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz);
return date;
}
BaseCalendar cal = getCalendarSystem(y);
if (cal != getCalendarSystem(date)) {
date = (BaseCalendar.Date) cal.newCalendarDate(tz);
date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
}
// Perform the GregorianCalendar-style normalization.
fastTime = cal.getTime(date);
// In case the normalized date requires the other calendar
// system, we need to recalculate it using the other one.
BaseCalendar ncal = getCalendarSystem(fastTime);
if (ncal != cal) {
date = (BaseCalendar.Date) ncal.newCalendarDate(tz);
date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
fastTime = ncal.getTime(date);
}
return date;
}
use of sun.util.calendar.BaseCalendar in project j2objc by google.
the class Date method normalize.
private final BaseCalendar.Date normalize() {
if (cdate == null) {
BaseCalendar cal = getCalendarSystem(fastTime);
cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime, TimeZone.getDefaultRef());
return cdate;
}
// required for the compatible behavior.
if (!cdate.isNormalized()) {
cdate = normalize(cdate);
}
// If the default TimeZone has changed, then recalculate the
// fields with the new TimeZone.
TimeZone tz = TimeZone.getDefaultRef();
if (tz != cdate.getZone()) {
cdate.setZone(tz);
CalendarSystem cal = getCalendarSystem(cdate);
cal.getCalendarDate(fastTime, cdate);
}
return cdate;
}
Aggregations