/*
Реализация среды исполнения языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package avt.util;
public final class JulianCalendar(Calendar)
{
private static final long EPOCH_START = -0x000000000a4cb800L;
private static int getDaysCount(int year, int month) {
switch(month + 1)
{
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 % 4 == 3 ? 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 JulianCalendar clone() { return new JulianCalendar(timeInMillis, offsetInMillis); }
protected void computeFields() {
long time = fldTimeInMillis + offsetInMillis - EPOCH_START;
int rem = (int) (time % 86400000);
int[] content = fldFieldsContent;
content[HOUR_OF_DAY] = rem / 3600000;
content[MINUTE] = (rem %= 3600000) / 60000;
content[SECOND] = (rem %= 60000) / 1000;
content[MILLISECOND] = rem % 1000;
int year = ((rem = (int) (time /= 86400000)) / 1461) * 4;
if((rem %= 1461) >= 1460)
{
year += 3;
rem = 365;
} else
{
year += rem / 365;
rem %= 365;
}
int month = 0;
for(int days; rem >= (days = getDaysCount(year, month)); month++) rem -= days;
content[YEAR] = year + 1;
content[MONTH] = month + 1;
content[DAY_OF_MONTH] = rem + 1;
content[DAY_OF_WEEK] = ((int) time + SATURDAY) % 7;
computeHalfdayFields();
}
protected void computeTime() {
boolean[] set = fldFieldsSet;
int[] content = fldFieldsContent;
int yer;
int year = yer = content[YEAR] - 1 & 0xffff;
int month = content[MONTH] - 1;
int day = content[DAY_OF_MONTH] - 1;
int hour = set[HOUR_OF_HALFDAY] | set[HALFDAY] | (set[HOUR_OF_HALFDAY] = set[HALFDAY] = false) ? content[HOUR_OF_HALFDAY] % 12 + content[HALFDAY] * 12 : content[HOUR_OF_DAY];
int minute = content[MINUTE];
int second = content[SECOND];
int millisecond = content[MILLISECOND];
int days = (year / 4) * 1461 + (year % 4) * 365 + day;
for(int mnt = 0; mnt < month; mnt++) days += getDaysCount(yer, mnt);
fldTimeInMillis = (long) days * 86400000 + hour * 3600000 + minute * 60000 + second * 1000 + millisecond - offsetInMillis + EPOCH_START;
}
}