3

我需要一个好的 OLEDate java 实现,而这个似乎不起作用。是否有任何已知的良好开源实现(如在 apache commons 中)?如果没有,我在哪里阅读它,以便我编写自己的实现?

4

3 回答 3

3

试试这个代码:

public static Date getDateFromCOMDate(float comtime) {
    String floatstr = String.valueOf(comtime);
    String [] ss = floatstr.split("\\.");
    long nulltime = -2209183200000L;
    long dayms = 86400000;
    int days = Integer.valueOf(ss[0]);
    float prop = comtime - days;
    long cdayms = Math.round(dayms * prop);
    long time = nulltime + days*dayms + cdayms;
    Date d = new Date(time);
    return d;
}
于 2013-06-21T17:01:09.200 回答
3

以前的实现是错误的,例如 1.0 和 -1.25 的日期错误。下面的实现符合 MSDN 中描述的 OLE 日期,例如:https ://msdn.microsoft.com/en-us/library/system.datetime.tooadate(v=vs.110).aspx

下面的实现确实符合 MSDN 文档。它将 BigDecimal 值转换为 Joda LocalDateTime。BigDecimal 比 float 和 double 更好,因为它能够保存一个精确的值。

class COMDateToRegularDateConverter {
    private static final LocalDateTime ZERO_COM_TIME = new LocalDateTime(1899, 12, 30, 0, 0);
    private static final BigDecimal MILLIS_PER_DAY = new BigDecimal(86400000);

    LocalDateTime toLocalDateTime(BigDecimal comTime) {
        BigDecimal daysAfterZero = comTime.setScale(0, RoundingMode.DOWN);
        BigDecimal fraction = comTime.subtract(daysAfterZero).abs(); //fraction always represents the time of that day
        BigDecimal fractionMillisAfterZero = fraction.multiply(MILLIS_PER_DAY).setScale(0, RoundingMode.HALF_DOWN);

        return ZERO_COM_TIME.plusDays(daysAfterZero.intValue()).plusMillis(fractionMillisAfterZero.intValue());
    }
}
于 2015-02-12T14:11:51.637 回答
2

这个Old New Thing 博客条目似乎是关于该主题的一篇不错的论文:

OLE 自动化日期格式是一个浮点值,从 1899 年 12 月 30 日午夜开始计算天数。小时和分钟表示为小数天。

如果您有权访问 Visual Studio 和 MFC COleDateTime 源,则可以在 Java 中重新实现它。

于 2010-04-12T16:41:26.720 回答