io.github.wycst.wast.common.beans.GeneralDate Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wast Show documentation
Show all versions of wast Show documentation
Wast is a high-performance Java toolset library package that includes JSON, YAML, CSV, HttpClient, JDBC and EL engines
package io.github.wycst.wast.common.beans;
import io.github.wycst.wast.common.reflect.UnsafeHelper;
import io.github.wycst.wast.common.utils.EnvUtils;
import io.github.wycst.wast.common.utils.NumberUtils;
import java.lang.reflect.Field;
import java.util.TimeZone;
/**
* 日期基础类
*
* 1582年历法按4年一润,当年删去了10天(10月5日~10月14日) ,1582-? 按最新历法
*
* Asia/Harbin, Asia/Shanghai, Asia/Chongqing, Asia/Urumqi, Asia/Kashgar:
*
1986年至1991年,每年四月的第2个星期日早上2点,到九月的第2个星期日早上2点之间。
* 1986年5月4日至9月14日(1986年因是实行夏令时的第一年,从5月4日开始到9月14日结束)
* 1987年4月12日至9月13日,
* 1988年4月10日至9月11日,
* 1989年4月16日至9月17日,
* 1990年4月15日至9月16日,
* 1991年4月14日至9月15日。
* 1992年起,夏令时暂停实行
*
* 注:[Asia/*]时区下Calendar消失的时间段(不存在的时间,无法通过设置时间域得到对应的时间点)
* 以Asia/Shanghai为例,时区文件: %JRE_HOME%/lib/zi/Asia/Shanghai
* 1900[1900-01-01 08:00:00, 1900-01-01 08:05:42) 5分43秒
* 1940[1940-06-03 00:00:00, 1940-06-03 00:59:59] 1小时
* 1941[1940-03-16 00:00:00, 1940-03-16 00:59:59] 1小时
* 以及夏令时每年开始第一个小时:
* 1986[1986-05-04 00:00:00, 1986-05-04 00:59:59] 一个小时区间
* 1987[1987-04-12 00:00:00, 1987-04-12 00:59:59] 一个小时区间
* ...
* 1991[1991-04-14 00:00:00, 1991-04-14 00:59:59] 一个小时区间
*
:
*
* TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");
* TimeZone.setDefault(timeZone);
*
* Calendar calendar = Calendar.getInstance();
* calendar.set(1900, 0, 1, 8, 0, 0);
* calendar.set(Calendar.MILLISECOND, 0);
*
* System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime())); // 1900-01-01 08:05:43
* System.out.println(calendar.get(Calendar.HOUR_OF_DAY)); // 8
* System.out.println(calendar.get(Calendar.MINUTE)); // 5
* System.out.println(calendar.get(Calendar.SECOND)); // 43
*
*
*
*
* @Author: wangy
* @Date: 2022/8/11 22:53
* @Description:
*/
public class GeneralDate {
// 最小时间:公元元年时间(0001-01-01 00:00:00.000)
// public static final GeneralDate MIN_DATE = GeneralDate.of(1, 1, 1, 0, 0, 0, 0);
public static final int YEAR = 1;
public static final int MONTH = 2;
public static final int DAY_OF_MONTH = 3;
public static final int HOUR = 4;
public static final int MINUTE = 5;
public static final int SECOND = 6;
public static final int MILLISECOND = 7;
protected int year;
protected int month;
protected int dayOfMonth;
protected int hourOfDay;
protected int minute;
protected int second;
protected int millisecond;
// 是否闰年
protected boolean leapYear;
// 当年第多少天
protected int daysOfYear;
// 距离1970.1.1 - 时区标准毫秒数
protected long standardMills;
// 距离1970.1.1 - 时区校对后的毫秒数
protected long timeMills = -1;
// 地球公转一周年毫秒数(计算24节气)
// 计算来源: 36524219 * 24 * 36
public final static long YEAR_TIMEMILLS = 31556925216l;
// 公元元年(0001).1.1 ~ 1970.1.1 相对天数
// 计算来源:1969 * 365 + 1969 / 4 - 1969 / 100 + 1969 / 400 + (1582 / 100 - 1582 / 400 - 10)
public final static long RELATIVE_DAYS = 719164l;
// 公元元年(0001).1.1 ~ 1970.1.1 相对毫秒数
// 计算来源: RELATIVE_DAYS * 24 * 3600 * 1000
public final static long RELATIVE_MILLS = 62135769600000l;
public final static long RELATIVE_SECONDS = 62135769600l;
// 以1970.1.1 周四 作为参考
public final static int RELATIVE_DAY_OF_WEEK = 5;
// 时钟
protected TimeZone timeZone;
// 可变时差
protected int currentOffset;
// 虽然是默认时钟,但默认时钟也可以被修改,这里初始化一个时钟,在没有时钟信息时会使用默认时钟
private static TimeZone defaultTimeZone;
// 获取实时的默认时钟
private final static Field defaultTimeZoneField;
// 公元元年(0001).1.1 ~ current 相对天数
protected long currentDays;
private static final int[] DAYS_OF_YEAR_OFFSET = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
private static final int[] DAYS_OF_LEAP_YEAR_OFFSET = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
// 一天(24小时)实际毫秒数
protected static final long MILLS_DAY = 86400000; // 24 * 3600 * 1000
// 平年一年(365天)实际毫秒数:
protected static final long MILLS_365_DAY = 365 * MILLS_DAY;
// 闰年一年(366天)毫秒数
protected static final long MILLS_366_DAY = 366 * MILLS_DAY;
protected static final long SECONDS_1991_09_14_23_59_59 = 62820658799l;
protected static final long SECONDS_1900_01_01_07_59_59 = 59926809599l;
protected static final long TIME_1900_01_01_08_05_43 = -2208988800000l;
protected static final long TIME_1991_09_15_00_00_00 = 684864000000l;
protected static final YearMeta[] POSITIVE_YEAR_METAS = new YearMeta[2100];
protected static final long MAX_CACHE_OFFSET_DAYS;
protected static final MonthDayMeta[] MONTH_DAY_OF_YEAR = new MonthDayMeta[365];
protected static final MonthDayMeta[] MONTH_DAY_OF_LEAP_YEAR = new MonthDayMeta[366];
static final int OFFSET_DAYS_DIVISOR = 146097;
public GeneralDate(TimeZone timeZone) {
ofTimeZone(timeZone);
}
public GeneralDate(long time) {
this(time, defaultTimeZone);
}
public GeneralDate(long time, TimeZone timeZone) {
ofTimeZone(timeZone);
setTime(time, true);
}
public GeneralDate(long time, String timeZone) {
ofTimeZone(timeZone == null ? defaultTimeZone : getTimeZoneById(timeZone));
setTime(time, true);
}
GeneralDate(int year, int month, int day, int hour, int minute, int second,
int millisecond, TimeZone timeZone) {
ofTimeZone(timeZone);
this.year = year;
this.month = month;
this.dayOfMonth = day;
this.hourOfDay = hour;
this.minute = minute;
this.second = second;
this.millisecond = millisecond;
}
public static GeneralDate of(int year, int month, int day, int hour, int minute, int second,
int millisecond) {
GeneralDate generalDate = new GeneralDate(year, month, day, hour, minute, second, millisecond, (TimeZone) null);
generalDate.updateTime();
return generalDate;
}
/**
* 通过 TimeZone对象设置时差
* 时间戳不变,重置各个系数
*
* @param timeZone
* @return
*/
public GeneralDate setTimeZone(TimeZone timeZone) {
this.timeZone = timeZone;
int rawOffset = timeZone.getRawOffset();
if (this.currentOffset != rawOffset) {
this.currentOffset = rawOffset;
setTime(this.timeMills, true);
}
return this;
}
/**
* 通过表达式设置GMT时钟
*
* @param offsetExpr +-{hour}:{minute}?
* Z
* @return
*/
public GeneralDate setTimeZone(String offsetExpr) {
return setTimeZone(getTimeZoneById(offsetExpr));
}
TimeZone getTimeZoneById(String offsetExpr) {
if (offsetExpr.startsWith("GMT")) {
return TimeZone.getTimeZone(offsetExpr);
}
return TimeZone.getTimeZone("GMT" + offsetExpr);
}
protected void ofTimeZone(TimeZone timeZone) {
this.timeZone = timeZone;
if (timeZone == null) {
this.timeZone = getDefaultTimeZone();
}
this.currentOffset = this.timeZone.getRawOffset();
}
static class YearMeta {
final int year;
final boolean leap;
final long offsetDays;
YearMeta(int year, boolean leap, long offsetDays) {
this.year = year;
this.leap = leap;
this.offsetDays = offsetDays;
}
}
static class MonthDayMeta {
final int month;
final int day;
public MonthDayMeta(int month, int day) {
this.month = month;
this.day = day;
}
}
static {
// 计算 1-1-1 00:00:00 ~ 1970-1-1 00:00:00 之间得 relativeMills
// 1582年历法按4年一润,当年删去了10天 ,1582-? 按最新历法
// 范围: 0001~1969(时间戳从1970年开始)
// RELATIVE_DAYS = 1969 * 365 + 1969 / 4 - 1969 / 100 + 1969 / 400 + (1582 / 100 - 1582 / 400 - 10);
// RELATIVE_MILLS = RELATIVE_DAYS * 24 * 3600 * 1000;
Field timeZoneField = null;
try {
timeZoneField = TimeZone.class.getDeclaredField("defaultTimeZone");
if (!UnsafeHelper.setAccessible(timeZoneField)) {
timeZoneField.setAccessible(true);
}
} catch (Throwable throwable) {
timeZoneField = null;
}
defaultTimeZoneField = timeZoneField;
getDefaultTimeZone();
for (int year = 0; year < POSITIVE_YEAR_METAS.length; year++) {
POSITIVE_YEAR_METAS[year] = createYearMeta(year);
}
MAX_CACHE_OFFSET_DAYS = POSITIVE_YEAR_METAS[POSITIVE_YEAR_METAS.length - 1].offsetDays;
int monthOfYear = 1;
int monthOfLeapYear = 1;
int daysOfYearOffset = DAYS_OF_YEAR_OFFSET[monthOfYear - 1];
int daysOfLeapYearOffset = DAYS_OF_LEAP_YEAR_OFFSET[monthOfLeapYear - 1];
for (int i = 0; i < 366; i++) {
if (i < 365) {
int dayOfMonthAtYear = i - daysOfYearOffset + 1;
// 4位(0-11) + 5位(0-30)
MONTH_DAY_OF_YEAR[i] = new MonthDayMeta(monthOfYear, dayOfMonthAtYear);
if (monthOfYear < 12 && i == DAYS_OF_YEAR_OFFSET[monthOfYear] - 1) {
daysOfYearOffset = DAYS_OF_YEAR_OFFSET[monthOfYear++];
}
}
int dayOfMonthAtLeapYear = i - daysOfLeapYearOffset + 1;
MONTH_DAY_OF_LEAP_YEAR[i] = new MonthDayMeta(monthOfLeapYear, dayOfMonthAtLeapYear);
if (monthOfLeapYear < 12 && i == DAYS_OF_LEAP_YEAR_OFFSET[monthOfLeapYear] - 1) {
daysOfLeapYearOffset = DAYS_OF_LEAP_YEAR_OFFSET[monthOfLeapYear++];
}
}
}
public final static long getTime(int year, int month, int day, int hour, int minute, int second,
int millisecond, TimeZone timeZone) {
GeneralDate generalDate = new GeneralDate(year, month, day, hour, minute, second, millisecond, timeZone);
generalDate.updateTime();
return generalDate.timeMills;
}
public final static long getSeconds(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second) {
if (month > 12) {
int increaseYear = (month - 1) / 12;
year += increaseYear;
month = month - increaseYear * 12;
} else if (month < 1) {
int increaseYear = month / 12 - 1;
year += increaseYear;
month = month - increaseYear * 12;
}
YearMeta meta = getYearMeta(year);
boolean isLeapYear = meta.leap;
long days = meta.offsetDays;
int offset = isLeapYear ? DAYS_OF_LEAP_YEAR_OFFSET[month - 1] : DAYS_OF_YEAR_OFFSET[month - 1];
int daysOfYear = offset + dayOfMonth;
if (year == 1582 && month > 9) {
if (month == 10) {
if (dayOfMonth > 14) {
daysOfYear -= 10;
}
} else {
daysOfYear -= 10;
}
}
days += daysOfYear;
return days * 86400 + hourOfDay * 3600 + minute * 60 + second - RELATIVE_SECONDS;
}
/**
* 支持格式: {'yyyy-MM-dd', 'yyyy-MM-dd HH:mm:ss'}
* 年月日必须
*
* @param dateStr
* @return
*/
public final static long parseTime(String dateStr) {
return parseTime(dateStr, null);
}
/**
* 支持格式: {'yyyy-MM-dd', 'yyyy-MM-dd HH:mm:ss'}
* 年月日必须
*
* @param dateStr
* @param timeZone
* @return
*/
public final static long parseTime(String dateStr, TimeZone timeZone) {
GeneralDate generalDate = parseGeneralDate(dateStr, timeZone);
generalDate.updateTime();
return generalDate.timeMills;
}
/**
* 支持格式: {'yyyy-MM-dd', 'yyyy-MM-dd HH:mm:ss'}
* 年月日必须
*
* @param dateStr
* @return
*/
public final static GeneralDate parseGeneralDate(String dateStr, TimeZone timeZone) {
dateStr.getClass();
int length = dateStr.length();
int year, month, day, hour = 0, minute = 0, second = 0;
try {
if (length == 19) {
year = NumberUtils.parseInt4(dateStr.charAt(0), dateStr.charAt(1), dateStr.charAt(2), dateStr.charAt(3));
month = NumberUtils.parseInt2(dateStr.charAt(5), dateStr.charAt(6));
day = NumberUtils.parseInt2(dateStr.charAt(8), dateStr.charAt(9));
hour = NumberUtils.parseInt2(dateStr.charAt(11), dateStr.charAt(12));
minute = NumberUtils.parseInt2(dateStr.charAt(14), dateStr.charAt(15));
second = NumberUtils.parseInt2(dateStr.charAt(17), dateStr.charAt(18));
} else if (length == 10) {
year = NumberUtils.parseInt4(dateStr.charAt(0), dateStr.charAt(1), dateStr.charAt(2), dateStr.charAt(3));
month = NumberUtils.parseInt2(dateStr.charAt(5), dateStr.charAt(6));
day = NumberUtils.parseInt2(dateStr.charAt(8), dateStr.charAt(9));
} else {
throw new UnsupportedOperationException(" Date Format Error, only supported 'yyyy-MM-dd' or 'yyyy-MM-dd HH:mm:ss'");
}
return new GeneralDate(year, month, day, hour, minute, second, 0, timeZone);
} catch (Throwable throwable) {
throw new UnsupportedOperationException("Date Format Error, default parse only supported 'yyyy-MM-dd' or 'yyyy-MM-dd HH:mm:ss'");
}
}
public final static GeneralDate parseGeneralDate_Standard_19(char[] buf, int offset, TimeZone timeZone) {
int year, month, day, hour = 0, minute = 0, second = 0;
try {
year = NumberUtils.parseInt4(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
month = NumberUtils.parseInt2(buf[offset + 5], buf[offset + 6]);
day = NumberUtils.parseInt2(buf[offset + 8], buf[offset + 9]);
hour = NumberUtils.parseInt2(buf[offset + 11], buf[offset + 12]);
minute = NumberUtils.parseInt2(buf[offset + 14], buf[offset + 15]);
second = NumberUtils.parseInt2(buf[offset + 17], buf[offset + 18]);
return new GeneralDate(year, month, day, hour, minute, second, 0, timeZone);
} catch (Throwable throwable) {
throw new UnsupportedOperationException("Date Format Error, parseGeneralDate_Standard_19 only supported 'yyyy?MM?dd?HH:mm:ss'");
}
}
public final static GeneralDate parseGeneralDate_Standard_19(byte[] buf, int offset, TimeZone timeZone) {
int year, month, day, hour = 0, minute = 0, second = 0;
try {
year = NumberUtils.parseInt4(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
month = NumberUtils.parseInt2(buf[offset + 5], buf[offset + 6]);
day = NumberUtils.parseInt2(buf[offset + 8], buf[offset + 9]);
hour = NumberUtils.parseInt2(buf[offset + 11], buf[offset + 12]);
minute = NumberUtils.parseInt2(buf[offset + 14], buf[offset + 15]);
second = NumberUtils.parseInt2(buf[offset + 17], buf[offset + 18]);
return new GeneralDate(year, month, day, hour, minute, second, 0, timeZone);
} catch (Throwable throwable) {
throw new UnsupportedOperationException("Date Format Error, parseGeneralDate_Standard_19 only supported 'yyyy?MM?dd?HH:mm:ss'");
}
}
public final static GeneralDate parseGeneralDate_Standard_10(char[] buf, int offset, TimeZone timeZone) {
int year, month, day, hour = 0, minute = 0, second = 0;
try {
year = NumberUtils.parseInt4(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
month = NumberUtils.parseInt2(buf[offset + 5], buf[offset + 6]);
day = NumberUtils.parseInt2(buf[offset + 8], buf[offset + 9]);
return new GeneralDate(year, month, day, hour, minute, second, 0, timeZone);
} catch (Throwable throwable) {
throw new UnsupportedOperationException("Date Format Error, parseGeneralDate_Standard_10 only supported 'yyyy?MM?dd'");
}
}
public static TimeZone getDefaultTimeZone() {
if (defaultTimeZoneField != null) {
try {
TimeZone defaultTimezone = (TimeZone) defaultTimeZoneField.get(null);
if (defaultTimezone != null) {
return defaultTimeZone = defaultTimezone;
}
} catch (IllegalAccessException exception) {
}
}
return defaultTimeZone = TimeZone.getDefault();
}
// 溢出处理不必考虑固定量值如日(24h)时(60m)分(60s)秒(1000ms)毫秒(只要给定了值就可直接换算为固定毫秒数)
// todo 是否存在因为过量溢出导致年份变化(是否闰年)带来的数据误差?
private void overflow() {
if (month > 12) {
int increaseYear = (month - 1) / 12;
year += increaseYear;
month = month - increaseYear * 12;
} else if (month < 1) {
int increaseYear = month / 12 - 1;
year += increaseYear;
month = month - increaseYear * 12;
}
}
private static boolean isLeapYear(int year) {
boolean remainder4 = (year & 3) == 0;
return year > 1582 ? remainder4 && (year % 100 != 0 || year % 400 == 0) : remainder4;
}
private static long getOffsetDays(long year) {
if (year > 1582) {
return (year - 1) * 365 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400 + 2;
}
return (year - 1) * 365 + (year - 1) / 4;
}
protected void updateTime() {
// 溢出处理
overflow();
YearMeta meta = getYearMeta(year);
boolean isLeapYear = meta.leap;
// // 是否闰年
// boolean isLeapYear = isLeapYear(year);
// if (year == 3200) {
// isLeapYear = false;
// }
// 0001.1.1~{year}.1.1的天数
long days = meta.offsetDays;
int offset = isLeapYear ? DAYS_OF_LEAP_YEAR_OFFSET[month - 1] : DAYS_OF_YEAR_OFFSET[month - 1];
int daysOfYear = offset + dayOfMonth;
// compute days
// if (year > 1582) {
// days = (year - 1) * 365 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400 + 2;
// } else {
// days = (year - 1) * 365 + (year - 1) / 4;
// }
// 1582年只有355天 此年10月5日~10月14日不存在
if (year == 1582 && month > 9) {
if (month == 10) {
if (dayOfMonth > 14) {
daysOfYear -= 10;
} else if (dayOfMonth > 4 && dayOfMonth <= 14) {
// 不存在的10天,按java日历的标准 +10
dayOfMonth += 10;
}
} else {
daysOfYear -= 10;
}
}
days += daysOfYear;
long seconds = days * 86400 + hourOfDay * 3600 + minute * 60 + second;
// 转化ms
this.timeMills = seconds * 1000 + millisecond - this.currentOffset - RELATIVE_MILLS;
// 当前时区(raw)下标准毫秒数(距离1970.1.1)
this.standardMills = this.timeMills;
// Asia/* 时区下区间offset调整
if (seconds <= SECONDS_1991_09_14_23_59_59 && seconds > SECONDS_1900_01_01_07_59_59) {
// 时区调整(Asia/* 夏令时调整)
int actualOffset = timeZone.getOffset(this.timeMills);
this.timeMills += this.currentOffset - actualOffset;
}
// 是否闰年
this.leapYear = isLeapYear;
// 一年第多少天
this.daysOfYear = daysOfYear;
// 公元元年(0001).1.1 ~ current 相对天数
this.currentDays = days;
}
void setTime(long timeMills, boolean reset) {
this.timeMills = timeMills;
if (timeMills >= TIME_1900_01_01_08_05_43 && timeMills < TIME_1991_09_15_00_00_00) {
// actual mills for compute
int zoneOffset = timeZone.getOffset(timeMills);
timeMills -= this.currentOffset - zoneOffset;
this.standardMills = timeMills;
}
long offset = RELATIVE_MILLS + currentOffset;
timeMills += offset;
long seconds;
int millisecond;
int offsetYear = 0;
if (timeMills > 0) {
seconds = EnvUtils.JDK_AGENT_INSTANCE.multiplyHighKaratsuba(timeMills, 0x4189374bc6a7ef9eL) >> 8; // timeMills / 1000;
millisecond = (int) (timeMills - seconds * 1000);
} else {
if (this.timeMills > Long.MAX_VALUE - offset) {
// overflowing the maximum value of long
int rem = (int) (this.timeMills % 1000);
seconds = this.timeMills / 1000 + (offset + rem) / 1000;
millisecond = (int) (rem + (offset % 1000)) % 1000;
} else {
// 如果是公元元年之前先计算年份,然后将timeMills补齐到正数在进行计算
// 这里只做了初略的转正处理,确保time段(时分秒)解析正确
do {
boolean leap = ((offsetYear + 1) & 3) == 0;
timeMills += leap ? MILLS_366_DAY : MILLS_365_DAY;
timeMills += MILLS_DAY;
offsetYear++;
} while (timeMills < 0);
seconds = timeMills / 1000;
millisecond = (int) (timeMills - seconds * 1000);
}
}
long days = EnvUtils.JDK_AGENT_INSTANCE.multiplyHighKaratsuba(seconds, 0x611722833944a55cL) >> 15; // seconds / 86400l;
int secondsOfDay = (int) (seconds - days * 86400l);
int hour = (int) EnvUtils.JDK_AGENT_INSTANCE.multiplyHighKaratsuba(secondsOfDay, 0x123456789abce0L); // secondsOfDay / 3600;
secondsOfDay = secondsOfDay - hour * 3600;
int minute = (int) EnvUtils.JDK_AGENT_INSTANCE.multiplyHighKaratsuba(secondsOfDay, 0x444444444444445L); // secondsOfDay / 60;
int second = secondsOfDay - minute * 60;
int daysOfYear;
boolean isLeapYear;
// int year = (int) ((days + 1) * 100000 / 36524219) + 1;
int year = (int) EnvUtils.JDK_AGENT_INSTANCE.multiplyHighKaratsuba(days * 400, 0x72d60d7991f1L) + 1; // (int) ((days * 400) / OFFSET_DAYS_DIVISOR + 1);
GeneralDate.YearMeta targetMeta = getYearMeta(year);
long offsetDays = targetMeta.offsetDays;
if (days <= offsetDays) {
targetMeta = getYearMeta(--year);
offsetDays = targetMeta.offsetDays;
}
daysOfYear = (int) (days - offsetDays);
isLeapYear = targetMeta.leap;
MonthDayMeta monthDayMeta;
try {
int dayIndex = daysOfYear - 1;
if (isLeapYear) {
if (daysOfYear > MONTH_DAY_OF_LEAP_YEAR.length) {
daysOfYear -= 366;
dayIndex -= 366;
++year;
isLeapYear = false;
}
monthDayMeta = MONTH_DAY_OF_LEAP_YEAR[dayIndex];
} else {
if (daysOfYear > MONTH_DAY_OF_YEAR.length) {
daysOfYear -= 365;
dayIndex -= 365;
++year;
isLeapYear = isLeapYear(year);
}
monthDayMeta = MONTH_DAY_OF_YEAR[dayIndex];
}
// monthDayMeta = isLeapYear ? Month_Day_Of_LeapYear[daysOfYear - 1] : Month_Day_Of_Year[daysOfYear - 1];
} catch (Throwable throwable) {
throw new IllegalArgumentException("error mills for " + this.timeMills);
}
int month = monthDayMeta.month;
int day = monthDayMeta.day;
// 1582年共355天 不存在的10天(1582.10.05~1582.10.14 对应278~287) 288~355
if (year == 1582 && daysOfYear >= 278) {
// daysOfYear 必然 <= 355 ,12月通过算法得到day最大21
day += 10;
// 10~11月溢出处理
if (month == 10 && day > 31) {
month += 1;
day = day - 31;
} else if (month == 11 && day > 30) {
month += 1;
day = day - 30;
}
}
this.year = year - offsetYear;
this.month = month;
this.dayOfMonth = day;
this.hourOfDay = hour;
this.minute = minute;
this.second = second;
this.millisecond = millisecond;
this.daysOfYear = daysOfYear;
this.leapYear = isLeapYear;
this.currentDays = days;
}
public final static long getDefaultOffset() {
return getDefaultTimeZone().getRawOffset();
}
private static YearMeta createYearMeta(int year) {
boolean leap = isLeapYear(year);
// starting from 0001-01-01, days have already represented January 1st of that year
long offsetDays = getOffsetDays(year) - 1;
return new YearMeta(year, leap, offsetDays);
}
static YearMeta getYearMeta(int year) {
if (year > -1 && year < POSITIVE_YEAR_METAS.length) {
return POSITIVE_YEAR_METAS[year];
}
return createYearMeta(year);
}
public final int getYear() {
return year;
}
public final int getMonth() {
return month;
}
public final int getDay() {
return dayOfMonth;
}
public final int getHourOfDay() {
return hourOfDay;
}
public final int getMinute() {
return minute;
}
public final int getSecond() {
return second;
}
public final int getMillisecond() {
return millisecond;
}
public long getTime() {
return timeMills;
}
public long getStandardTime() {
return standardMills;
}
public int getCurrentOffset() {
return currentOffset;
}
/**
* 是否上午
*
* @return
*/
public boolean isAm() {
return this.hourOfDay < 12;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy