timestamp - 获取 01/01/2017 的时间戳
timestamp - get timestamp for 01/01/2017
我有我当前的时间戳:1491044139,即 04/01/2017 @10:53am(UTC)。
我正在尝试从中计算 01/01/2017(即当前时间戳年份的 1 月 1 日)。
function getJan1stTimestamp(_timestamp){
return (_timestamp-(_timestamp%(365*24*3600)));
}
但是一直返回1482192000!这是 12/20/2016 @ 12:00am (UTC) 而不是 01/01/2017 @ 00:00 (UTC)
我觉得我在做一些很愚蠢的事情,但我不知道那是什么 ;(
我在一个非常原始的系统上,所以我不能使用高级日期函数,必须使用基本算术。
**编辑:刚刚意识到我没有post解决方案...
这里是:
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(...)
因为你的小数位会自动丢失)。
感谢大家的帮助;)
I have my current timestamp: 1491044139 which is 04/01/2017 @ 10:53am (UTC).
1491044139 是 2017-04-01 10:55:39 UTC。
I'm trying to calculate 01/01/2017 from it:
01/01/2017 是 1483228800。
But it keeps returning 1482192000! This is 12/20/2016 @ 12:00am (UTC)
正确。
Here are algorithms to convert y-m-d
triples to a count of days since 1970-01-01, and vice versa. Once you have a count of days you can multiply/divide by 86400 (24*3600) to get seconds. This does of course neglect leap seconds, but so does 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);
}
我有我当前的时间戳:1491044139,即 04/01/2017 @10:53am(UTC)。
我正在尝试从中计算 01/01/2017(即当前时间戳年份的 1 月 1 日)。
function getJan1stTimestamp(_timestamp){
return (_timestamp-(_timestamp%(365*24*3600)));
}
但是一直返回1482192000!这是 12/20/2016 @ 12:00am (UTC) 而不是 01/01/2017 @ 00:00 (UTC)
我觉得我在做一些很愚蠢的事情,但我不知道那是什么 ;(
我在一个非常原始的系统上,所以我不能使用高级日期函数,必须使用基本算术。
**编辑:刚刚意识到我没有post解决方案...
这里是:
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(...)
因为你的小数位会自动丢失)。
感谢大家的帮助;)
I have my current timestamp: 1491044139 which is 04/01/2017 @ 10:53am (UTC).
1491044139 是 2017-04-01 10:55:39 UTC。
I'm trying to calculate 01/01/2017 from it:
01/01/2017 是 1483228800。
But it keeps returning 1482192000! This is 12/20/2016 @ 12:00am (UTC)
正确。
Here are algorithms to convert y-m-d
triples to a count of days since 1970-01-01, and vice versa. Once you have a count of days you can multiply/divide by 86400 (24*3600) to get seconds. This does of course neglect leap seconds, but so does 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);
}