时间戳 - 获取时间戳01/01/2017

时间:2017-04-01 11:00:22

标签: timestamp unix-timestamp

我目前的时间戳是:1491044139,这是04/01/2017 @ 10:53 am(UTC)。

我试图从它计算01/01/2017(即当前时间戳的1月1日)。

function getJan1stTimestamp(_timestamp){
    return (_timestamp-(_timestamp%(365*24*3600)));
}

但它一直在返回1482192000!这是 12/20/2016 @ 12:00 am(UTC)而不是01/01/2017 @ 00:00(UTC)

我觉得我做的事非常愚蠢,但我不知道它是什么;(

我是一个非常原始的系统,所以我不能使用高级日期函数,必须使用基本算术。

**编辑:刚刚意识到我没有发布解决方案......

这是:

uint currentYear=floor(1970+(current_timestamp/(365.25*24*3600)));   //Swallowed the 0.25s by rounding ;)
uint nLeapYears=floor((currentYear-1972)/4);   //again, rounded ;) 1972 is the first leap year after 1970
uint nNonLeapYears=currentYear-1970-nLeapYears;
uint firstJanTimestamp=nLeapYears*366*24*3600 + nNonLeapYears*365*24*3600 + 24*3600;   //added one day for good measure ;)
return firstJanTimestamp;

以上所有操作都是用非常原始的操作符完成的(我这样做是为了在Solidity中使用 - 注意:在Solidity中你不会需要floor(...),因为你的小数位会自动丢失。)< / p>

感谢大家的帮助;)

1 个答案:

答案 0 :(得分:1)

  

我目前的时间戳是:1491044139,这是04/01/2017 @ 10:53 am(UTC)。

1491044139是2017-04-01 10:55:39 UTC。

  

我试图从它计算01/01/2017:

01/01/2017是1483228800。

  

但它一直在返回1482192000!这是12/20/2016 @ 12:00 am(UTC)

正确。

Here are algorithmsy-m-d三倍转换为自1970-01-01以来的天数,反之亦然。一旦你有一个天数,你可以乘以/除以86400(24 * 3600)得到秒。这当然会忽略闰秒,但Unix Time也是如此,所以这是一致的。

算法是用C ++ 14编写的,但它们简短而简单,应该可以轻松移植到任何语言。这些算法如何工作的详细描述,以及跨越+/-百万年的单元测试都在the link

template <class Int>
constexpr
Int
days_from_civil(Int y, unsigned m, unsigned d) noexcept
{
    static_assert(std::numeric_limits<unsigned>::digits >= 18,
             "This algorithm has not been ported to a 16 bit unsigned integer");
    static_assert(std::numeric_limits<Int>::digits >= 20,
             "This algorithm has not been ported to a 16 bit signed integer");
    y -= m <= 2;
    const Int era = (y >= 0 ? y : y-399) / 400;
    const unsigned yoe = static_cast<unsigned>(y - era * 400);      // [0, 399]
    const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1;  // [0, 365]
    const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy;         // [0, 146096]
    return era * 146097 + static_cast<Int>(doe) - 719468;
}

template <class Int>
constexpr
std::tuple<Int, unsigned, unsigned>
civil_from_days(Int z) noexcept
{
    static_assert(std::numeric_limits<unsigned>::digits >= 18,
             "This algorithm has not been ported to a 16 bit unsigned integer");
    static_assert(std::numeric_limits<Int>::digits >= 20,
             "This algorithm has not been ported to a 16 bit signed integer");
    z += 719468;
    const Int era = (z >= 0 ? z : z - 146096) / 146097;
    const unsigned doe = static_cast<unsigned>(z - era * 146097);          // [0, 146096]
    const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365;  // [0, 399]
    const Int y = static_cast<Int>(yoe) + era * 400;
    const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100);                // [0, 365]
    const unsigned mp = (5*doy + 2)/153;                                   // [0, 11]
    const unsigned d = doy - (153*mp+2)/5 + 1;                             // [1, 31]
    const unsigned m = mp + (mp < 10 ? 3 : -9);                            // [1, 12]
    return std::tuple<Int, unsigned, unsigned>(y + (m <= 2), m, d);
}