2

这是一个很难用谷歌搜索的。我有一个一百万行长的 XML 文档,我正在使用 Ruby 来解析它并删除我不关心的条目。我的标准之一是创建日期。这些 XML 块中的日期看起来很有趣

<attribute name="datemodified" type="date">362895460.21263897418975830078</attribute>
<attribute name="datecreated" type="date">356831173.15324598550796508789</attribute>

我从来没有见过这样格式的日期。如果你做了类似的事情,它们看起来很相似Time.now.to_f。即便如此,我也不知道如何将它们转换为 Ruby DateTime 对象。如果您甚至可以确定这些时间是如何产生的,或者它们的含义,那将非常有帮助。

如果有帮助,这个 XML 文件最初是由一个名为“Things”的 Mac OS X 应用程序创建的。

谢谢阅读!

更新:我又创建了两个条目并记录了创建它们的时间:

从 2012 年 7 月 2 日上午 9:57 开始

<attribute name="datemodified" type="date">362941035.01687598228454589844</attribute> 
<attribute name="datecreated" type="date">362940986.89370900392532348633</attribute>

从 2012 年 7 月 2 日上午 9:58 开始

<attribute name="datemodified" type="date">362941107.69538801908493041992</attribute>
<attribute name="datecreated" type="date">362941080.53793197870254516602</attribute>

我无法精确到秒,但我确实让它们相隔大约一分钟......这使得它们看起来实际上是秒......但是......从某个随机日期开始。也许是开发者的生日:)

做一些快速的数学运算,为了便于记忆,随机日期似乎在 2000-12-31 16:09:43 -0800 左右,或者可能是 01/01/01... 并且 978336000 以秒为单位。

4

2 回答 2

3

Time.at方法从 1970 年以来的秒数转换为一个Time实例:

[1] pry(main)> Time.at 362895460.21263897418975830078
=> 1981-07-02 00:17:40 -0400

如果该日期不正确,但单位是秒,则可以添加一个常量以获取正确的日期,例如

[2] pry(main)> Time.parse('2001-01-01') - Time.at(0)
=> 978325200.0
于 2012-07-02T16:45:35.017 回答
0

这些数字在我看来就像整数部分是儒略日期,而小数部分是一天的小数部分。我没有详细调查过。作为参考,撒克逊语中用于从“朱利安瞬间”转换日期/时间的代码是:

public static DateTimeValue fromJulianInstant(/*@NotNull*/ BigDecimal instant) {
        BigInteger julianSecond = instant.toBigInteger();
        BigDecimal microseconds = instant.subtract(new BigDecimal(julianSecond)).multiply(DecimalValue.BIG_DECIMAL_ONE_MILLION);
        long js = julianSecond.longValue();
        long jd = js / (24L * 60L * 60L);
        DateValue date = DateValue.dateFromJulianDayNumber((int)jd);
        js = js % (24L * 60L * 60L);
        byte hour = (byte)(js / (60L * 60L));
        js = js % (60L * 60L);
        byte minute = (byte)(js / (60L));
        js = js % (60L);
        return new DateTimeValue(date.getYear(), date.getMonth(), date.getDay(),
                hour, minute, (byte)js, microseconds.intValue(),0 , true);
}

public static DateValue dateFromJulianDayNumber(int julianDayNumber) {
        if (julianDayNumber >= 0) {
            int L = julianDayNumber + 68569 + 1;    // +1 adjustment for days starting at noon
            int n = (4 * L) / 146097;
            L = L - (146097 * n + 3) / 4;
            int i = (4000 * (L + 1)) / 1461001;
            L = L - (1461 * i) / 4 + 31;
            int j = (80 * L) / 2447;
            int d = L - (2447 * j) / 80;
            L = j / 11;
            int m = j + 2 - (12 * L);
            int y = 100 * (n - 49) + i + L;
            return new DateValue(y, (byte) m, (byte) d, true);
        } else {
            // add 12000 years and subtract them again...
            DateValue dt = dateFromJulianDayNumber(julianDayNumber +
                    (365 * 12000 + 12000 / 4 - 12000 / 100 + 12000 / 400));
            dt.year -= 12000;
            return dt;
        }
    }
于 2012-07-02T20:04:21.360 回答