有关时间的一些操作

有关时间的一些操作

本文无需说明理论知识,纯简化实操的代码,直接来看吧:

Date 传入的参数需符合标准,请见 IETF-compliant RFC 2822 timestampsversion of ISO8601

PS:传入的参数 date 需为 Date 对象的实例,请先行转化。
PPS:比如改变了天数,其实 时分秒并未改变,使用时请注意。(划重点)
PPPS:修改的是对象,为了避免操作的是同一个对象的数据栈,可以再 new Date() 一下。

处理 "/Date("xxxxxxxxx")/" 形态的时间戳,一般出现在后端接口的数据里

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],个人推荐按你的开发习惯进行是否 -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 转换成字符串格式(但这里没有自动补零,需要的话请自行改写)

// 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;
}

自动补零

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);

本身理论并不难,但需要注意以下几点:

  1. 月份记得要减 1
  2. 时间相减再 new 出来的时间是有时差的,比如最后一秒 getHours() 会为 8,所以如果有天数和小时级别的倒计时要特别注意这个坑(划重点)
  3. 但拥有时差的 d 最后一秒 getTime()0,去掉了时差会为负数哟

所以我只能进行了下面这种性能实在不佳的封装

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);  // 处理时区问题
  dd = new Date(dd.setHours(dd.getHours() + dd.getTimezoneOffset() / 60));
  // 正式开始
  if (d.getTime() > -1) _begin();
  else { fn && fn(end, d); cb && cb(); }
  // 内部方法
  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,
  }
}

// ------ 倒计时运行
var endTime = new Date(2017, (9-1), 6, 13, 35, 0);  // 这里修改结束时间
timecount(new Date(), endTime, function(left, raw){
  // left 为真实剩余时间,raw 为时间相减本来得到的值
  console.log(left, raw.getTime());
});

再举个栗子(制作日历的原理之一)

以下代码实现的是,从本月到往后五个月所有日期形成的二维数组。
其中 DateAddMonth 和 DateAddDay 是类似的方法,就不再复写了。

var result = [];
var now = new Date();
var temp = FirstDay(now);  // 求取本月第一天,因为 31 号时的月份加减很容易出错咯
for (var i=0; i<6; i++) {
  result[i] = [];
  var month = DateAddMonth(temp, i);  // 六个月第一天的日期
  var days = HowMuchDay(month.getMonth(), month.getFullYear());  // 当月有多少天
  for (var j=0; j<days; j++) {
    result[i].push(DateAddDay(month, j));  // 当月每一天放入数组中
  }
}
console.log(result);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,950评论 6 13
  • SwiftDate概况 从Swift发布起,我们就没有放弃使用Swift。 当然,我们希望在项目能够轻松自如地管理...
    Mee_Leo阅读 10,064评论 1 13
  • 春天浓重又热闹老是容易花粉过敏冬天太冷还爱起静电脱毛衣的时候噼里啪啦响夏天的西瓜和短袖我一直都会想夜晚清凉的故事太...
    余公子_阅读 163评论 0 0
  • 命和运的区别早已有了相对明确的说法:命是与生俱来的东西,生在帝王家就是王子,生在贫民家就是屌丝;运是后天存在变数又...
    KVC阅读 732评论 1 6
  • 从儿时开始,生性贪玩的我最兴奋的事情就是去陌生的地方,看陌生的风景。我享受陌生带来的新鲜感,象漆黑夜空中的烟火,在...
    小番茄食堂阅读 518评论 0 3