将Unix时间戳转换为儒略日

23

我该如何将Unix时间戳(例如1232559922)转换为分数儒略日(2454853.03150)。

我找到了一个网站(http://aa.usno.navy.mil/data/docs/JulianDate.php),它执行类似的计算,但我需要以编程方式进行计算。

解决方案可以使用C / C ++,Python,Perl,Bash等语言实现...

4个回答

38

Unix时代(零点)是1970年1月1日GMT。这对应于朱利安日2440587.5

因此,伪代码如下:

function float getJulianFromUnix( int unixSecs )
{
   return ( unixSecs / 86400.0 ) + 2440587.5;
}

12
你忘记在结尾处加上0.5了。添加的常数应该是2440587.5。 - Robert L
我不明白86400.0是什么意思?而且结果与当前时间轴相差甚远。 - eapo
2
86400 是秒转换为天的因子(1天=24小时/天x60分钟/小时x60秒/分钟)。 - TNgo

7
我知道这是一篇旧文章,但我想说...
Jason Cohen给出的答案是转换的一个很好的近似值。
然而,存在一个问题与一天中的秒数有关。一天不完全是86400秒长,周期性地会添加秒以使时间与各种可观测标准同步。这些称为闰秒(https://en.wikipedia.org/wiki/Leap_second)。闰秒被添加到UTC中以使其与UT1相差不超过1秒。
随着自1970年1月1日以来经过的时间越来越长,上述简单转换将从“实际可观察时间”中累积更多误差。在1972年至2013年间,添加了25个闰秒。
儒略日数的美丽和简单之处在于它们根本不表示日期字符串。它们只是自儒略纪元开始以来经过的时间计数,就像POSIX时间是自POSIX纪元开始以来的毫秒连续计数一样。唯一存在的问题是当您尝试将儒略日数映射到本地化日期字符串时。
如果您需要一个精确到分钟的日期字符串(在2013年),那么您需要一个可以考虑闰秒的算法。

11
我认为Unix/Posix时间忽略闰秒,因此Jason Cohen的算法不会随着闰秒的累积而漂移。请参阅http://en.wikipedia.org/wiki/Unix_time#Leap_seconds。如果我理解有误,请纠正我。 - Martin Stone

0

这个问题在写作时已经超过13年了,真是太疯狂了。感谢eapo的JS公式,我将其转换为PineScript v5,并在测试中发现它至少非常接近。我认为对于大多数(如果有的话)TradingView应用程序来说,完美的准确性甚至都不相关。因此,我没有去确保完美的准确性。但它有效。谢谢eapo,你节省了我很多时间。

编辑:TradingView以股票/货币交易所时区显示时间。因此,需要创建其他参数来提供交易所使用的UTC偏移量。

[重要提示:请记住,使用夏令时的交易所将根据DST状态从 UTC-n 转移到 UTC-n-1 。您必须相应地更新UTC偏移参数。]

// Julian Date & Partial Day in CST
computeJulianDate(dd, mm, yy, hr, mn, sc, offset=0, live=false) =>
    HR = hr
    HR := hr + (mn / 60) + (sc / 3600)
    GGG = 1
    if year <= 1585 
        GGG := 0
    float JD = -1 * math.floor(7 * (math.floor((mm + 9) / 12) + yy) / 4)
    S = 1
    if ((mm - 9)<0) 
        S :=-1
    A = math.abs(mm - 9)
    J1 = math.floor(yy + S * math.floor(A / 7))
    J1 := -1 * math.floor((math.floor(J1 / 100) + 1) * 3 / 4)
    JD := JD + math.floor(275 * mm / 9) + dd + (GGG * J1)
    JD := JD + 1721027 + 2 * GGG + 367 * yy
    JD := JD + (HR / 24) 
    barsInSession  = timeframe.isintraday ? ((24 * 60) / timeframe.multiplier) : timeframe.multiplier
    barsInSession := math.floor(barsInSession) == barsInSession and timeframe.isintraday ? barsInSession - 1 : math.floor(barsInSession)
    offsetInc = 1 / barsInSession
    offsetCt  = (offset * ((barsInSession / 24) * offsetInc))
    JD := live ? JD + offsetCt : math.floor(JD - offsetCt) - 0.5
    JD

0

这是我的JavaScript代码,用于将Unix时间戳转换为Julian日期。原本它显示的是当前日期和时间,但稍作修改后就可以回答您的问题:

function computeJulianDate(DD,MM,YY,HR,MN,SC) {
    with (Math) {
        HR = HR + (MN / 60) + (SC/3600);
        GGG = 1;
        if (YY <= 1585) GGG = 0;
        JD = -1 * floor(7 * (floor((MM + 9) / 12) + YY) / 4);
        S = 1;
        if ((MM - 9)<0) S=-1;
        A = abs(MM - 9);
        J1 = floor(YY + S * floor(A / 7));
        J1 = -1 * floor((floor(J1 / 100) + 1) * 3 / 4);
        JD = JD + floor(275 * MM / 9) + DD + (GGG * J1);
        JD = JD + 1721027 + 2 * GGG + 367 * YY - 0.5;
        JD = JD + (HR / 24);
    }
    return JD;
}
function getUTCDateTimeOrJD(now,jd=0) {
    var hours = now.getUTCHours();
    var minutes = now.getUTCMinutes();
    var seconds = now.getUTCSeconds()
    var month = now.getUTCMonth() + 1;
    var day = now.getUTCDate();
    var year = now.getUTCFullYear();
    if (jd==1)
        return computeJulianDate(month, day, year, hours, minutes, seconds);
    else
        return day+". "+month+". "+year+". "+hours+":"+minutes+":"+seconds;
}

var unixTime = 1473294606;

    getUTCDateTimeOrJD(new Date(unixTime*1000));
    getUTCDateTimeOrJD(new Date(unixTime*1000),1);

这里有一个可工作的JSFiddle示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接