diff --git a/classpath/java/util/Calendar.java b/classpath/java/util/Calendar.java index 640b7a237a..c479cc49fc 100644 --- a/classpath/java/util/Calendar.java +++ b/classpath/java/util/Calendar.java @@ -59,11 +59,62 @@ public abstract class Calendar { public abstract int getActualMaximum(int field); private static class MyCalendar extends Calendar { + private static final long MILLIS_PER_DAY = 86400000; + private static final int MILLIS_PER_HOUR = 3600000; + private static final int MILLIS_PER_MINUTE = 60000; + private static final int MILLIS_PER_SECOND = 1000; + + private static final int EPOCH_YEAR = 1970; + private static final int[][] DAYS_IN_MONTH = new int[][] { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + }; + public MyCalendar(long time) { this.time = time; this.isTimeSet = true; + parseIntoFields(time); } + public void setTime(Date date) { + super.setTime(date); + parseIntoFields(this.time); + } + + private static boolean isLeapYear(int year) { + return (year%4 == 0) && (year%100 != 0) || (year%400 == 0); + } + + private static int daysInYear(int year) { + return isLeapYear(year) ? 366 : 365; + } + + private void parseIntoFields(long timeInMillis) { + long days = timeInMillis / MILLIS_PER_DAY; + int year = EPOCH_YEAR; + while (days >= daysInYear(year)) { + days -= daysInYear(year++); + } + int month=0; + int leapIndex = isLeapYear(year) ? 1 : 0; + while (days >= DAYS_IN_MONTH[leapIndex][month]) { + days -= DAYS_IN_MONTH[leapIndex][month++]; + } + days++; + int remainder = (int)(timeInMillis % MILLIS_PER_DAY); + int hour = remainder / MILLIS_PER_HOUR; + remainder = remainder % MILLIS_PER_HOUR; + int minute = remainder / MILLIS_PER_MINUTE; + remainder = remainder / MILLIS_PER_MINUTE; + int second = remainder / MILLIS_PER_SECOND; + fields[YEAR] = year; + fields[MONTH] = month; + fields[DAY_OF_MONTH] = (int)days; + fields[HOUR_OF_DAY] = hour; + fields[MINUTE] = minute; + fields[SECOND] = second; + } + public void roll(int field, boolean up) { // todo }