有關(guān)時間的一些操作
本文無需說明理論知識,純簡化實(shí)操的代碼绿店,直接來看吧:
Date 傳入的參數(shù)需符合標(biāo)準(zhǔn),請見 IETF-compliant RFC 2822 timestamps 或 version of ISO8601。
PS:傳入的參數(shù) date
需為 Date
對象的實(shí)例稍走,請先行轉(zhuǎn)化地技。
PPS:比如改變了天數(shù)蜈七,其實(shí) 時分秒并未改變,使用時請注意莫矗。(劃重點(diǎn))
PPPS:修改的是對象飒硅,為了避免操作的是同一個對象的數(shù)據(jù)棧砂缩,可以再 new Date() 一下。
處理 "/Date("xxxxxxxxx")/" 形態(tài)的時間戳三娩,一般出現(xiàn)在后端接口的數(shù)據(jù)里
function changeDate(datetime) {
return new Date(parseInt(datetime.replace("/Date(", "").replace(")/", ""), 10));
}
計算變化多少天后的日期庵芭,秒/分/時/月 等都可同理
function DateAddDay(date, days) {
var date = new Date(date);
return new Date(date.setDate(date.getDate() + days));
}
本月第一天的日期
function FirstDay(date) {
var date = new Date(date);
return new Date(date.setDate(1));
}
本周周一的日期,本周周日等同理
function FirstDayInThisWeek(date) {
var date = new Date(date);
return DateAddDay(date, 1 - date.getDay());
}
計算某年某月有幾天(month 范圍 [1, 12]雀监,個人推薦按你的開發(fā)習(xí)慣進(jìn)行是否 -1 的改寫)
function HowMuchDay(month, year) {
if (!year) year = new Date().getFullYear();
var m = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
m[1] = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 29 : 28;
return m[month - 1];
}
將 Date 轉(zhuǎn)換成字符串格式(但這里沒有自動補(bǔ)零双吆,需要的話請自行改寫)
// yyyy = 年 mm = 月 dd = 日 hh = 小時 nn = 分 ss = 秒
function ConvertDateToString(date, pattern) {
var str = pattern;
str = str.replace(/y{4}/i, date.getFullYear());
str = str.replace(/m{2}/i, (date.getMonth()+1));
str = str.replace(/d{2}/i, date.getDate());
str = str.replace(/h{2}/i, date.getHours());
str = str.replace(/n{2}/i, date.getMinutes());
str = str.replace(/s{2}/i, date.getSeconds());
return str;
}
自動補(bǔ)零
function addZero(num, n) {
var len = num.toString().length || 2;
while(len < n) {
num = "0" + num; len++;
}
return num;
}
function addZero2(num, n) {
if (Math.pow(10,n)<num) return num+'';
return (Array(n).join(0) + num).slice(-n);
}
倒計時
var end = new Date(2017, (9-1), 8, 20, 0, 0);
var d = new Date(end - new Date());
setInterval(function(){
d = new Date(d.setSeconds(d.getSeconds() - 1));
if (d.getTime() > 0) console.log(d);
else console.log(end);
}, 1000);
本身理論并不難,但需要注意以下幾點(diǎn):
- 月份記得要減 1
- 時間相減再
new
出來的時間是有時差的会前,比如最后一秒getHours()
會為8
好乐,所以如果有天數(shù)和小時級別的倒計時要特別注意這個坑(劃重點(diǎn)) - 但擁有時差的
d
最后一秒getTime()
為0
,去掉了時差會為負(fù)數(shù)喲
所以我只能進(jìn)行了下面這種性能實(shí)在不佳的封裝
function dateAddSecond(date, second) {
return new Date(date.setSeconds(date.getSeconds() + second));
}
function timecount(start, end, fn, cb) {
var offset = end - start, Timer = null;
var d = new Date(offset);
var dd = new Date(offset); // 處理時區(qū)問題
dd = new Date(dd.setHours(dd.getHours() + dd.getTimezoneOffset() / 60));
// 正式開始
if (d.getTime() > -1) _begin();
else { fn && fn(end, d); cb && cb(); }
// 內(nèi)部方法
function _begin() {
fn && fn(dd, d);
Timer = setInterval(_run, 1000);
}
function _run() {
d = dateAddSecond(d, -1);
dd = dateAddSecond(dd, -1);
fn && fn(dd, d);
if (d.getTime() < 1000) {
_stop(); cb && cb();
}
}
function _stop() {
clearInterval(Timer);
}
return {
start: _begin,
stop: _stop,
}
}
// ------ 倒計時運(yùn)行
var endTime = new Date(2017, (9-1), 6, 13, 35, 0); // 這里修改結(jié)束時間
timecount(new Date(), endTime, function(left, raw){
// left 為真實(shí)剩余時間瓦宜,raw 為時間相減本來得到的值
console.log(left, raw.getTime());
});
再舉個栗子(制作日歷的原理之一)
以下代碼實(shí)現(xiàn)的是蔚万,從本月到往后五個月所有日期形成的二維數(shù)組。
其中 DateAddMonth 和 DateAddDay 是類似的方法临庇,就不再復(fù)寫了反璃。
var result = [];
var now = new Date();
var temp = FirstDay(now); // 求取本月第一天,因?yàn)?31 號時的月份加減很容易出錯咯
for (var i=0; i<6; i++) {
result[i] = [];
var month = DateAddMonth(temp, i); // 六個月第一天的日期
var days = HowMuchDay(month.getMonth(), month.getFullYear()); // 當(dāng)月有多少天
for (var j=0; j<days; j++) {
result[i].push(DateAddDay(month, j)); // 當(dāng)月每一天放入數(shù)組中
}
}
console.log(result);