GregorianCalendar.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Исходный код среды исполнения ПВТ-ОО.

    Этот исходный код является частью проекта ПВТ-ОО.

    Copyright © 2021 Малик Разработчик

    Это свободная программа: вы можете перераспространять её и/или
    изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она может быть полезна,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <http://www.gnu.org/licenses/>.
*/

package avt.util;

public final class GregorianCalendar(Calendar)
{
    private static final long EPOCH_START = 0x0000000000000000L;

    private static int getDaysCount(int year, int month) {
        switch(month)
        {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            return 31;
        case 4:
        case 6:
        case 9:
        case 11:
            return 30;
        case 2:
            return year % (year % 100 == 0 ? 400 : 4) == 0 ? 29 : 28;
        }
        return 0;
    }


    public (): this(System.currentTimeInMillis(), System.currentOffsetInMillis()) {  }

    public (long timeInMillis): this(timeInMillis, System.currentOffsetInMillis()) {  }

    public (long timeInMillis, int offsetInMillis): super(timeInMillis, offsetInMillis) { computeFields(); }

    public (Timestamp timestamp): this(timestamp, System.currentOffsetInMillis()) {  }

    public (Timestamp timestamp, int offsetInMillis): super(timestamp, offsetInMillis) { computeFields(); }

    public GregorianCalendar clone() { return new GregorianCalendar(timeInMillis, offsetInMillis); }

    protected void computeFields() {
        long time = fldTimeInMillis + offsetInMillis - EPOCH_START;
        int rem = (int) (time % 86400000L);
        int[] fields = fldFields;
        fields[HOUR_OF_DAY] = rem / 3600000;
        fields[MINUTE] = (rem %= 3600000) / 60000;
        fields[SECOND] = (rem %= 60000) / 1000;
        fields[MILLISECOND] = rem % 1000;
        int year = ((rem = (int) (time /= 86400000L)) / 146097) * 400;
        if((rem %= 146097) >= 146096)
        {
            year += 399;
            rem = 365;
        } else
        {
            year += rem / 36524 * 100 + (rem %= 36524) / 1461 * 4;
            if((rem %= 1461) >= 1460)
            {
                year += 3;
                rem = 365;
            } else
            {
                year += rem / 365;
                rem %= 365;
            }
        }
        fields[YEAR] = ++year;
        int month = 1;
        for(int days; rem >= (days = getDaysCount(year, month)); month++) rem -= days;
        fields[MONTH] = month;
        fields[DAY_OF_MONTH] = rem + 1;
        fields[DAY_OF_WEEK] = ((int) time + MONDAY) % 7;
        computeHalfdayFields();
    }

    protected void computeTime() {
        boolean[] isset = fldFieldsSet;
        int[] fields = fldFields;
        int yearSrc = fields[YEAR] & 0xffff;
        int year = yearSrc - 1;
        int month = fields[MONTH] - 1;
        int day = fields[DAY_OF_MONTH] - 1;
        int hour = isset[HOUR_OF_HALFDAY] | isset[HALFDAY] | (isset[HOUR_OF_HALFDAY] = isset[HALFDAY] = false) ? fields[HOUR_OF_HALFDAY] % 12 + fields[HALFDAY] * 12 : fields[HOUR_OF_DAY];
        int minute = fields[MINUTE];
        int second = fields[SECOND];
        int millisecond = fields[MILLISECOND];
        int days = 146097 * (year / 400);
        year %= 400;
        days += 36524 * (year / 100);
        year %= 100;
        days += 1461 * (year / 4) + 365 * (year % 4) + day;
        for(int i = 1; i <= month; i++) days += getDaysCount(yearSrc, i);
        fldTimeInMillis = days * 86400000L + hour * 3600000L + minute * 60000L + second * 1000L + millisecond - offsetInMillis + EPOCH_START;
    }
}