import cn.hutool.core.date.DateTime;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
@Slf4j
public class OATimeUtil {
private static final long TicksPerMillisecond = 10000;
private static long TicksPerSecond = TicksPerMillisecond * 1000;
private static long TicksPerMinute = TicksPerSecond * 60;
private static long TicksPerHour = TicksPerMinute * 60;
private static long TicksPerDay = TicksPerHour * 24;
private static final int MillisPerSecond = 1000;
private static int MillisPerMinute = MillisPerSecond * 60;
private static int MillisPerHour = MillisPerMinute * 60;
private static int MillisPerDay = MillisPerHour * 24;
private static final int DaysPerYear = 365;
private static int DaysPer4Years = DaysPerYear * 4 + 1;
private static int DaysPer100Years = DaysPer4Years * 25 - 1;
private static int DaysPer400Years = DaysPer100Years * 4 + 1;
private static int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
private final int DaysTo1970 = DaysPer400Years * 4 + DaysPer100Years * 3 + DaysPer4Years * 17 + DaysPerYear; // 719,162
private static long DoubleDateOffset = DaysTo1899 * TicksPerDay;
private static long OADateMinAsTicks = (DaysPer100Years - DaysPerYear) * TicksPerDay;
private static final int[] DaysToMonth365 = new int[]{
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
};
private static final int[] DaysToMonth366 = new int[]{
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
};
private static final Double OADateBase = 25569.0;
private static final Double MillisecondsPerDay = 86400000.0;
private static final Double DifferValue=0.3333333333;
private static boolean IsLeapYear(int year) {
if (year % 4 == 0) {
if (year % 100 == 0) {
return year % 400 == 0;
}
return true;
}
return false;
}
private static long DateToTicks(int year, int month, int day) {
if (year >= 1 && year <= 9999 && month >= 1 && month <= 12) {
int[] array = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365;
if (day >= 1 && day <= array[month] - array[month - 1]) {
int num = year - 1;
int num2 = num * 365 + num / 4 - num / 100 + num / 400 + array[month - 1] + day - 1;
return num2 * 864000000000L;
}
}
return 0;
}
public static double TicksToOADate(DateTime dateTime) {
Long timesMs=DateTimeToLong(dateTime.year(), dateTime.month() + 1, dateTime.dayOfMonth(), dateTime.hour(true), dateTime.minute(), dateTime.second(), dateTime.millisecond());
return TicksToOADate(timesMs);
}
private static long TimeToTicks(int hour, int minute, int second) {
if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60) {
long num = (long) hour * 3600L + (long) minute * 60L + second;
if (num > 922337203685L || num < -922337203685L) {
throw new IllegalArgumentException("Overflow_TimeSpanTooLong");
}
return num * 10000000;
}
throw new ArrayIndexOutOfBoundsException("ArgumentOutOfRange_BadHourMinuteSecond");
}
// This function is duplicated in COMDateTime.cpp
public static double TicksToOADate(Long value) {
if (value == 0)
return 0.0; // Returns OleAut's zero'ed date value.
if (value < TicksPerDay) // This is a fix for VB. They want the default day to be 1/1/0001 rathar then 12/30/1899.
value += DoubleDateOffset; // We could have moved this fix down but we would like to keep the bounds check.
if (value < OADateMinAsTicks)
throw new IllegalArgumentException("Arg_OleAutDateInvalid");
// Currently, our max date == OA's max date (12/31/9999), so we don't
// need an overflow check in that direction.
long millis = (value - DoubleDateOffset) / TicksPerMillisecond;
if (millis < 0) {
long frac = millis % MillisPerDay;
if (frac != 0) millis -= (MillisPerDay + frac) * 2;
}
return (double) millis / MillisPerDay;
}
public static long DateTimeToLong(int year, int month, int day, int hour, int minute, int second, int millisecond) {
if (second == 60) {
second = 59;
}
long num = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
num += (long) millisecond * 10000L;
if (num < 0 || num > 3155378975999999999L) {
throw new IllegalArgumentException("Arg_DateTimeRange");
}
return num;
}
}