3

優れたOLEDateJava実装が必要ですが、これは機能していないようです。(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値をJodaLocalDateTimeに変換します。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

このOldNewThingのブログエントリは、このトピックに関するまともな論文のようです。

OLEオートメーションの日付形式は浮動小数点値であり、1899年12月30日の午前0時からの日数をカウントします。時間と分は分数で表されます。

VisualStudioとMFCCOleDateTimeソースにアクセスできる場合は、Javaで再実装できます。

于 2010-04-12T16:41:26.720 に答える