专栏首页web编程技术分享js常用方法和一些封装 -- 时间相关(附案例详解)

js常用方法和一些封装 -- 时间相关(附案例详解)

昨天上传的时候少了一个方法,现在补上:

//日期转换
function transformDate(date){
    if(typeof date =="string"){
        return new Date(date.replace(/-/ig,"/").replace("T"," "));
    }else{
        return date;
    }
 }
勘误:_center()方法中timeBox应改为dom,封装方法的时候忘了改过来了,现在已更正。

本文介绍一些时间操作相关的方法,经过思考,从这一篇开始,主要围绕一个例子开始讲,先通过案例来讲解一下基本的操作。然后上干货 -- 也就是各种封装好的方法,都是可以直接使用的。

如有讲得不对的地方,恳请各位大神指正,欢迎评论和吐槽。

好了,现在开始展示案例:

2.gif

这个例子是一个背景色根据时间来动态变化的小demo,我们知道16进制的颜色是类似#666666这样的格式,而时间的格式是 hh:mm:ss,非常的相似,所以我们能够通过时间的变动来实现这样的效果。

下面来分析一下这个小demo。

第一步,在body区域中画一个div

 <div id="time" class="time"></div>

Paste_Image.png

如图,当我画一个div,如果不添加任何css样式的话,它既没有高度也没有宽度,但是仍独占一行,因为div是块级元素。顺便说一句,如果是行级元素,你即便给了它宽高,还是不会起作用的。

比如,我们不用div了,改用span来做。

 <span id="time" class="time"></span>

接下来,我们给他添加一些基本的样式吧:

color: #FFF2F4;
height: 60px;
width: 500px;
font-size: 28px;
line-height: 60px;

Paste_Image.png

如图,你加了width和height还是没用滴。但是它会根据span里面的内容进行撑开。

像这样:

background: deeppink;
 <span id="time" class="time">123456</span>

Paste_Image.png

一个解决方法就是将span升级为行内块级元素。

display: inline-block;

Paste_Image.png

可见,当我们设置display为inline-block的时候,宽度和高度就会发生变化了,而且不会独占一行。

诶,一看不对啊,我们当然希望里面的文字在盒子内居中显示,这样才比较好看嘛。

首先是水平居中,这个比较简单,只需要

text-align: center;

至于垂直居中,之前的css样式中,这一条代码就实现了

line-height: 60px;

line-height代表行高,当我们设置行高与容器高度相等的时候,文字就会垂直居中。

Paste_Image.png

这样子好多了吧。

接下来,我们希望将这个盒子相对于body居中显示,如何做呢?

123.gif

网上流传的居中方法有很多,我在此就列举一种比较简单的方式。 根据示意图,外层的大盒子代表body,我先将body分为左右相等的两块,各50%的意思,现在左上角的盒子代表已经升级为inline-block的span元素,要让它水平居中,首先可以将这个盒子从左往右移动50%,但是这样的话,就多移动了自身宽度的一半,对不对?

也就是说,如果要让它水平居中,只需要将这个盒子拖回来自身宽度的一半,就OK了。

垂直居中也是这个道理。

我们用js的方式来实现:

//让元素居中的方法
function _center(dom){
    dom.style.position = 'absolute';
    dom.style.top = '50%';
    dom.style.left = '50%';
    dom.style['margin-top'] = - dom.offsetHeight / 2 + 'px';
    dom.style['margin-left'] = - dom.offsetWidth / 2 + 'px';
}

var timeBox = dom("#time"); //dom方法的封装,请参考上一篇文章,其实就是document.getElementById。

_center(timeBox);

Paste_Image.png

居中了,就是如此简单。

接下来,我们把文字和背景色删除掉,只留下这个span。在调试模式下,我们依然可以看到这个区域。

Paste_Image.png

我们希望拿到hh:mm:ss格式的时间数据,而js原生态的date对象没有format方法,所以先通过下面的代码扩展一下:

Date.prototype.format = function(fmt) {
    var o = {
        "Y+" : this.getFullYear(),
        "M+" : this.getMonth() + 1,
        // 月份
        "d+" : this.getDate(),
        // 日
        "h+" : this.getHours() % 12 == 0 ? 12 : this.getHours() % 12,
        // 小时
        "H+" : this.getHours(),
        // 小时
        "m+" : this.getMinutes(),
        // 分
        "s+" : this.getSeconds(),
        // 秒
        "q+" : Math.floor((this.getMonth() + 3) / 3),
        // 季度
        "S" : this.getMilliseconds()
    // 毫秒
    };
    var week = {
        "0" : "星期日",
        "1" : "星期一",
        "2" : "星期二",
        "3" : "星期三",
        "4" : "星期四",
        "5" : "星期五",
        "6" : "星期六"
    };
    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "")
                .substr(4 - RegExp.$1.length));
    }
    if (/(E+)/.test(fmt)) {
        fmt = fmt.replace(
                        RegExp.$1,
                        ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f"
                                : "/u5468")
                                : "")
                                + week[this.getDay() + ""]);
    }
    for ( var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k])
                    : (("00" + o[k]).substr(("" + o[k]).length)));
        }
    }
    return fmt;
};

测试:

var now = new Date();
var hh = now.format('hh');
var mm = now.format('mm');
var ss = now.format('ss');
var bgColor = '#' + hh + mm  + ss ;
alert(bgColor);

Paste_Image.png

接下来,我们希望随着时间的流动来动态地获取背景色,于是可以这样

setInterval(function(){
    var now = new Date();
    var hh = now.format('hh');
    var mm = now.format('mm');
    var ss = now.format('ss');
    var bgColor = '#' + hh + mm  + ss ;
    console.log(bgColor);
},1000); //一秒钟变化一次

123.gif

接下来,只需要将动态获得的背景色加在body上面就可以啦!

var now = new Date();
var hh = now.format('hh');
var mm = now.format('mm');
var ss = now.format('ss');
var bgColor = '#' + hh + mm  + ss ;
now = now.format('yyyy年MM月dd日  E hh:mm:ss');
document.body.style.background = bgColor;
time.innerHTML = now;
setInterval(function(){
    now = new Date();
    hh = now.format('hh');
    mm = now.format('mm');
    ss = now.format('ss');
    now = now.format('yyyy年MM月dd日  E hh:mm:ss');
    bgColor = '#' + hh + mm  + ss ;
    console.log('当前的背景颜色为:' + bgColor);
    time.innerHTML = now;
    document.body.style.background = bgColor;
},1000);

123.gif

于是,关于这个小demo的讲解就愉快地结束了。

接下来,分享一下我搜集的关于时间操作的相关方法:

//获取多久以前,比如1秒前、一分钟前、一天前,等等
function getTimeFormat(startTime) {
    var startTimeMills = startTime.getTime();
    var endTimeMills = new Date().getTime();
    var diff = parseInt((endTimeMills - startTimeMills) / 1000);//秒
    var day_diff = parseInt(Math.floor(diff / 86400));//天
    var buffer = Array();
    if (day_diff < 0) {
        return "[error],时间越界...";
    } else {
        if (day_diff == 0 && diff < 60) {
            if (diff <= 0)
                diff = 1;
            buffer.push(diff + "秒前");
        } else if (day_diff == 0 && diff < 120) {
            buffer.push("1 分钟前");
        } else if (day_diff == 0 && diff < 3600) {
            buffer.push(Math.round(Math.floor(diff / 60)) + "分钟前");
        } else if (day_diff == 0 && diff < 7200) {
            buffer.push("1小时前");
        } else if (day_diff == 0 && diff < 86400) {
            buffer.push(Math.round(Math.floor(diff / 3600)) + "小时前");
        } else if (day_diff == 1) {
            buffer.push("1天前");
        } else if (day_diff < 7) {
            buffer.push(day_diff + "天前");
        } else if (day_diff < 30) {
            buffer.push(Math.round(Math.floor(day_diff / 7)) + " 星期前");
        } else if (day_diff >= 30 && day_diff <= 179) {
            buffer.push(Math.round(Math.floor(day_diff / 30)) + "月前");
        } else if (day_diff >= 180 && day_diff < 365) {
            buffer.push("半年前");
        } else if (day_diff >= 365) {
            buffer.push(Math.round(Math.floor(day_diff / 30 / 12)) + "年前");
        }
    }
    return buffer.toString();
}

/*返回 1970 年 1 月 1 日至今的毫秒数。*/
 function getMillTime(date){
     return transformDate(date).getTime();
 }
 
 //日期转换
function transformDate(date){
    if(typeof date =="string"){
        return new Date(date.replace(/-/ig,"/").replace("T"," "));
    }else{
        return date;
    }
 }
 
/*返回相差的毫秒数。*/
function getDifMillSeconds(date1,date2){
    var stimes = getMillTime(transformDate(date1));
    var etimes = getMillTime(transformDate(date2));
    return etimes - stimes;
}


/*返回相差的秒数。*/
function getDifSeconds(date1,date2){
    return Math.floor(getDifMillSeconds(date1,date2) / 1000);
}   

/*返回相差的分。*/
function getDifMinutes(date1,date2){
    return Math.floor(getDifMillSeconds(date1,date2)/(1000*60));
}

/*返回相差的小时。*/
function getDifHours(date1,date2){
    return Math.floor(getDifMillSeconds(date1,date2)/(1000*60*60));
}

/*返回相差的天数。*/
function getDifDays(date1,date2){ 
    var times = getDifSeconds(date1,date2);
    return Math.ceil(times/(3600 * 24));
}

/*返回相差的月份。*/
function getDifMonths(date1,date2){ 
    var times = getDifDays(date1,date2);
    return  Math.floor(times/30);
}

/*获取相差的年份*/
function getDifYear(date1,date2){
    var times = getDifDays(date1,date2);
    return  Math.floor(times/365);
}

/*获取年份*/
function getYear(date){
    return transformDate(date).getFullYear();
}

/*获取月*/
function getMonth(date){
     var month = transformDate(date).getMonth()+1;
     return month>9 ? month : "0"+month;
 }

 /*获取日*/
 function getDay(date){
     var day = transformDate(date).getDate();
     return day >9 ? day : "0"+day;
 }
 
  /*获取今天星期几,如果为0代表星期日*/
 function getWeek(date){
     return transformDate(date).getDay();
 }

 function getWeekChinese(date){
    var weekdays = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六']; 
    return weekdays[getWeek(date)];
}

 /*获取时*/
 function getHour(date){
     var hour = transformDate(date).getHours();
     return hour >9 ? hour : "0"+hour;
 }

 /*12小时制时*/
 function getHour12(date){
     var hour = transformDate(date).getHours();
     return hour%12 == 0 ? 12 : hour % 12;
 }

 /*分*/
 function getMinute(date){
     var minutes = transformDate(date).getMinutes();
     return minutes >9 ? minutes : "0"+minutes;
 }

 /*秒*/
 function getSecond(date){
    var seconds = transformDate(date).getSeconds();
    return seconds >9 ? seconds : "0"+seconds;
 }

 /*毫秒*/
 function getMillisecond(date){
    return transformDate(date).getMilliseconds();
 }
 
  /*获取今天在当年是第几季度*/
 function getPeriod(date){
    var month = getMonth(date)*1;
    return  Math.floor((month+3)/3);
 }
        
/*根据输入的日期获取该年的第一天*/
function getFirstDayOfYear(date){
    var year = getYear(date);
    var dateString = year+"-01-01 00:00:00";
    return dateString;
}

/*获取输入日期是当年中的第几天*/
function getDayOfYear(date){
    return Math.ceil(getDifDays(getFirstDayOfYear(date),date));
}

测试:

var date1 = transformDate("2016/8/10 09:12:45");
var date2 = transformDate("2016/8/10 08:12:45");
console.log('1个小时有' + getDifSeconds(date2,date1)); //一个小时为3600秒


date1 = transformDate("2016/8/11 08:12:45");
date2 = transformDate("2016/8/10 08:12:45");
console.log('1天有' + getDifHours(date2,date1) + '个小时'); //一天为24个小时
  
date1 = transformDate("2016/8/11 08:12:45");
date2 = transformDate("2016/7/11 08:12:45");
console.log('7月份有' + getDifDays(date2,date1) + '天');


date1 = transformDate("2016/8/11 08:12:45");
date2 = transformDate("2015/8/11 08:12:45");
console.log('一年为' + getDifMonths(date2,date1) + '个月'); 

date1 = transformDate("2016/8/11 08:12:45");
date2 = transformDate("2010/8/11 08:12:45");
console.log('2010年和2016年相差' + getDifYear(date2,date1) + '年'); 

var date = new Date();
console.log('今年是' + getYear(date) + '年');
console.log('本月是' + getMonth(date) + '月');
console.log('今天是' + getDay(date) + '日');
console.log('今年的第一天是' + getFirstDayOfYear(date));
console.log('今年是星期' + getWeek(date));
console.log('今年是' + getWeekChinese(date));


//获取多久以前
console.log('2016/8/16 09:10:45是' + getTimeFormat(transformDate("2016/8/16 09:10:45")));
console.log('1995/8/16是' + getTimeFormat(transformDate("1995/8/16")));

Paste_Image.png

本章结束 ...

剽悍一小兔,电气自动化毕业。 参加工作后对计算机感兴趣,深知初学编程之艰辛。 希望将自己所学记录下来,给初学者一点帮助。

免责声明: 博客中所有的图片素材均来自百度搜索,仅供学习交流,如有问题请联系我,侵立删,谢谢。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【H5 音乐播放实例】第五节 音轨制作

    剽悍一小兔
  • 小兔JS教程(三)-- 彻底攻略JS回调函数

    剽悍一小兔
  • js学习: 自定义类库 - miniQuery 2.0

    剽悍一小兔
  • ztree实现根节点单击事件,显示节点信息

    这段时间在维护公司的项目,去年做的项目里面有ztree树的例子,想起之前还没有开始写博客,一些知识点也无从找起,要新加一个右击节点事件,折腾了半天,其中也包含了...

    祈澈菇凉
  • 推荐几个只有程序员才会玩的游戏

    这是一个在线解谜游戏,画风简洁,部分关卡需要具备一定的web知识。url地址直接访问,打开浏览器调试等操作都是解谜必要的。对于web开发人员来说非常值得一玩。

    五分钟学算法
  • ztree实现根节点右击事件,显示添加删除

    1:在setting 配置里面,给callback设置,右击事件onRightClick:

    祈澈菇凉
  • 程序员准备面试时常犯11个错误,切记!

    如果面试官要考核你的技术,很有可能会要求你在白板上写代码,而不是电脑上。所以,你就不能只在电脑上练习。电脑上的编译器会自动发现你的语法错误,但是白板不会。

    Java架构技术
  • 前端自动化测试解决方案探析

      前端测试一直是前端项目开发过程中机器重要的一个环节,高效的测试方法可以减少我们进行代码自测的时间,提高我们的开发效率,如果你的代码涉及的测试用例较多,而且项...

    IMWeb前端团队
  • 前端自动化测试解决方案探析

    前端测试一直是前端项目开发过程中机器重要的一个环节,高效的测试方法可以减少我们进行代码自测的时间,提高我们的开发效率,如果你的代码涉及的测试用例较多,而且项目需...

    IMWeb前端团队
  • 在SE37里批量执行ABAP函数

    在SE37里直接执行如下function module,对应的update module ZSQF不会被执行,因为缺少commit work。

    Jerry Wang

扫码关注云+社区

领取腾讯云代金券