我试图在JavaScript中获取最接近绝对年份的毫秒值,仅回复JavaScript Date对象的valueOf()
方法。
例如:今天是2016年4月4日星期一上午12:50。所以我正在寻找最接近的绝对年份(过去)。 2016年1月1日00:00 am。
这是我的代码:
var ms_per_year = 31536000000;
var now = new Date().valueOf();
var mod_year = now % ms_per_year;
var nearest_absolute_year = now - mod_year;
console.log(new Date(nearest_absolute_year));
// Sun Dec 20 2015 19:00:00 GMT-0500 (EST)
console.log(new Date(Date.parse('2016 1 1 00:00:00')));
// Fri Jan 01 2016 00:00:00 GMT-0500 (EST)
我希望这两个打印日期与分钟相同:
var ms_per_minute = 60 * 1000;
var now = new Date().valueOf();
var mod_minute = now % ms_per_minute;
var nearest_absolute_minute = now - mod_minute;
console.log(new Date(nearest_absolute_minute));
// Mon Apr 04 2016 00:57:00 GMT-0400 (EDT)
console.log(new Date(Date.parse('2016 4 4 00:57:00')));
// Mon Apr 04 2016 00:57:00 GMT-0400 (EDT)
如何在不使用Date.parse()的情况下计算自1970年以来和当年年初开始的毫秒数,仅依靠数学?
答案 0 :(得分:1)
你需要应对闰年,Himanshu正在寻找一个优雅的解决方案,一个简单的循环可以做到这一点,但效率不高:
/* @returns {number} time value for start of current year
** Don't use Date methods
** Assumes current time is after epoch (1970-01-01T00:00:00Z)
*/
function getStartOfYear(timeValue) {
var timeValue = timeValue || Date.now();
var accumulatedTime = 0;
var day = 8.64e7;
var year = 1970;
var msForYear = 365*day; // ms for 1970
function isLeap(n) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
// Continue while adding ms for current year won't go past limit
while ((accumulatedTime + msForYear) < timeValue) {
// Add time for current year
accumulatedTime += msForYear;
// Calculate time for next year
msForYear = (isLeap(++year)? 366:365) * day;
}
// Return accumulated time
return accumulatedTime;
}
// Tests
['2010','2011','2012','2013','2014','2015','2016','2017'].forEach(function(y){
//Generate time value away from start of year
var startOfYear = new Date(getStartOfYear(new Date(y,3).getTime() + 23000));
document.write('<br>UTC start of year: ' + startOfYear.toISOString());
startOfYear.setMinutes(startOfYear.getMinutes() + startOfYear.getTimezoneOffset());
document.write('<br>Local start of year: ' + startOfYear);
});
&#13;
body {
font-family: courier, mono-space;
font-size: 90%
}
&#13;
这是一个非循环解决方案。它如上所述在UTC中工作,但也可以根据建议调整到本地。
function getStartOfYear(timeValue) {
timeValue = +timeValue || Date.now();
// ms for one day
var day = 8.64e7;
// ms for standard year
var year = 365 * day
// ms for leap block
var leapBlock = year * 4 + day;
// Use 1969-01-01T00:00:00Z as epoch
timeValue += year;
// Accumulate time
var accumulatedTime = 0;
accumulatedTime += Math.floor(timeValue / leapBlock) * leapBlock;
accumulatedTime += Math.floor((timeValue % leapBlock) / year) * year;
// Reset epoch to 1970-01-01T00:00:00Z and return time value
return accumulatedTime - year;
}
如果您想要混淆但简洁的代码,请尝试:
function getStartOfYear(timeValue) {
timeValue = +timeValue || Date.now();
var day = 8.64e7, year = 365 * day, leapBlock = year * 4 + day, accumulatedTime = 0;
return ((timeValue + year) / leapBlock | 0) * leapBlock + ((timeValue + year) % leapBlock / year | 0) * year - year;
}
答案 1 :(得分:1)
这应该可以解决问题:
var d = new Date(new Date().getFullYear(), 0);
d.valueOf(); // > 1451634391371 (ms)
答案 2 :(得分:0)
由于以下假设,你的逻辑不起作用
var ms_per_year = 31536000000
对于365天的这一年,这是正确的毫秒值,但是你忘了考虑几年。
以下代码将有所帮助
var ms_per_year = 31536000000;
var ms_per_day = 86400000;
var now = new Date().valueOf();
var mod_year = now % ms_per_year;
var year = Math.floor(now/ms_per_year);
var leap_years = Math.floor(year/4);
var nearest_absolute_year = now - mod_year;
var actual_value = nearest_absolute_year + (leap_years*ms_per_day);
console.log(new Date(actual_value));
如果你发现任何错误,请纠正我。