本帖最后由 Clark.Pan 于 2024-2-2 18:57 编辑
前言:
OADate(OLE Automation Date)是一种日期和时间表示形式,通常在OLE(Object Linking and Embedding)自动化中使用。它是一种浮点数表示法,用于在不同的编程环境中传递日期和时间信息。
在OADate中,日期被表示为从"1899年12月30日 00:00:00"开始的天数,而时间则以小数部分表示。负数表示该日期在"1899年12月30日"之前,而正数表示在之后。
具体而言,OADate的计算方式是将日期和时间转换为一个浮点数,其中整数部分表示日期,小数部分表示时间。例如,OADate为0.0表示"1899年12月30日 00:00:00",而OADate为1.0表示"1899年12月31日 00:00:00"。
在某些编程语言和环境中,使用OADate可以方便地在不同系统和平台之间传递日期和时间信息,因为它是一种标准的自动化日期表示方法。
SpreadJS中OADate的应用:
SpreadJS中使用了OADate,用于日期格式的处理以及序列化。在SpreadJS中,当单元格的 value 是一个日期类型时,toJSON 或者导出 sjs 序列化,数据绑定等功能会将该日期以OADate字符串的形式表现出来,例如:"/OADate(45317)/"。
注意,这里所说的日期类型指的是Date对象,而非日期字符串,例如new Date("2024-01-31") 这个是一个日期类型,"2024-01-31" 这个不是一个日期类型,是一个字符串类型的日期。
因为无法将一个对象直接序列化,所以需要借助OADate这种形式做转换。
OADate转换:
那么具体 OADate 与 日期类型,或者字符串之间该如何转换呢,下文会详细进行介绍。
JavaScript 将日期字符串转 OADate :
function toOADateStr(dateStr){
const ticks = new Date(dateStr).valueOf() - new Date().getTimezoneOffset() * 60 * 1000;
const oad = ticks / 86400000 + 25569;
if (oad < 0) {
const frac = oad - Math.trunc(oad);
if (frac !== 0) {
oad = Math.ceil(oad) - frac - 2;
}
}
return "/OADate(" + oad + ")/";
}
JavaScript 将 OADate 转为日期字符串:
function toDateStr(oADateStr){
var oaDateReg = new RegExp('^/OADate\\(([-+]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)\\)/\\s*$');
if (typeof oADateStr === "string" && oaDateReg.test(oADateStr)) {
var oadate = parseFloat(oADateStr.match(oaDateReg)[1]);
var ms = (oadate * 86400000 * 1440 - 25569 * 86400000 * 1440 + new Date((oadate - 25569) * 86400000).getTimezoneOffset() * 86400000 ) / 1440;
return new Date(ms);
}else{
return date;
}
}
考虑到一些客户通过解析和获取,拿到 OADate 字符串后自己分析,亦或是有时候需要修改 ssjson 或者 DataSource 中的 OADate 场景,这里将一些后端语言处理OADate 的方法也列举出来,供大家参考:
Java 将日期字符串转 OADate:
public static Double convertToOADate(String dateStr) throws ParseException {
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
Date date = myFormat.parse(dateStr);
BigDecimal time = new BigDecimal(date.getTime());
time = (time.add(new BigDecimal("2209190400000"))).divide(new BigDecimal(86400000),11,RoundingMode.HALF_UP);
System.out.println("OADate:"+time.doubleValue());
return time.doubleValue();
}
Java 将 OADate 转为日期字符串:
public static String convertFromOADateStr(String oADateStr) throws ParseException {
String pattern = "/OADate\\((\\d+(\\.\\d+)?)\\)/";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(oADateStr);
if (m.find()) {
double d = Double.parseDouble(m.group(1));
double mantissa = d - (long) d;
double hour = mantissa*24;
double min =(hour - (long)hour) * 60;
double sec=(min- (long)min) * 60;
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date baseDate = myFormat.parse("1899-12-30 00:00:00");
Calendar c = Calendar.getInstance();
c.setTime(baseDate);
c.add(Calendar.DATE,(int)d);
c.add(Calendar.HOUR,(int)hour);
c.add(Calendar.MINUTE,(int)min);
c.add(Calendar.SECOND,(int)sec);
return myFormat.format(c.getTime());
}else {
return "Not a OADate";
}
}
|
|