同福

JavaScript的日期和时间的使用技巧【20210409】

介绍

介绍

今天福哥将要给大家讲解JavaScript编程基础知识日期和时间的使用技巧,这个技术在程序开发时候的使用率还是非常高的,基本上95%以上的项目都离不开日期和时间的应用场景。

关于日期和时间还是有很多知识需要了解的,如果不清楚这些的话,就会遇到很多奇怪的问题。在很多对时间控制很严格的系统里面会有非常复杂的时间处理逻辑,如果没有很好的使用经验甚至功能都无法实现。例如:昨天是什么日子?距离下一个周末还有几天?今年有多少个工作日?想要解决这些问题还是需要好好学习一下日期和时间的使用技巧的。

时区

时区时间

地球是圆的,处于不同经度地区的人看到的时间是不一样的,在一条经度上的人看到的时间是一样的。所以我们在描述一个时间的时候都会以当地经度上的一个主要城市为准计算当地的时间,例如:北京时间,东京时间,伦敦时间,纽约时间等等。

处于不同经度地区的人看到的时间之间是有差的,这个差就是我们常说的时差。服务器也是存在于某一个经度地区的,所以跨时区操作网站的时候就会有时差问题。

为了解决这个问题程序默认会以一个公共时区UTC的时间为基准,大家都以这个UTC时区的时间记录具体时间,在显示的时候可以根据所在时区与UTC时区的偏移经度计算时差,从而得到本地时区正确的具体时间。

格式化时间

JavaScript默认是没有类似Java的SimpleDataFormat这样的格式化对象的,为了解决这个问题福哥自己造了一个轮子,用来格式化Date对象的时间信息。

后面的讲解中使用的例子都假设在已经引用这个扩展之后运行的,童鞋们可以自行引入到自己的项目当中。

Date.prototype.format = function (format, utc) {
    var o;
    if(!format){
        format = "yyyy/MM/dd HH:mm:ss";
    }
    if(utc){
        o = {
            "y+" : this.getUTCFullYear(),
            "M+" : this.getUTCMonth()+1,
            "d+" : this.getUTCDate(),
            "H+" : this.getUTCHours(),
            "m+" : this.getUTCMinutes(),
            "s+" : this.getUTCSeconds(),
            "w+" : (this.getUTCDay() == 0) ? 7 : this.getUTCDay()
        }
    }
    else{
        o = {
            "y+" : this.getFullYear(),
            "M+" : this.getMonth()+1,
            "d+" : this.getDate(),
            "H+" : this.getHours(),
            "m+" : this.getMinutes(),
            "s+" : this.getSeconds(),
            "w+" : (this.getDay() == 0) ? 7 : this.getDay()
        }
    }

    for(var k in o){
        format = format.replace(new RegExp("(" + k + ")", "g"), function(f, m, p, s){
            if(m.length > 1){
                o[k] = o[k] + "";
                while(m.length > o[k].length){
                    o[k] = "0" + o[k];
                }
            }

            return o[k];
        });
    }

    return format;
};

当前时间

UTC时间

前面介绍时区的时候说过了,为了便于针对不同经度地区的人显示当地的时间系统里面存储的最好是UTC时间。

out += "<h3>当前UTC时间</h3>";
out += new Date().format("yyyy/MM/dd HH:mm:ss", true);

本地时间

要得到对应本地时区的时间只需要去掉getUTCXXX里面的UTC就可以了,如果是通过福哥封装的扩展的话只需要不传入参数utc即可。

out += "<h3>本地时间</h3>";
out += new Date().format("yyyy/MM/dd HH:mm:ss");

创建时间

如果我们要创建一个时间(或者说是指定一个具体的时间)需要用到Date对象的UTC方法。

Date对象的UTC方法可以顺序传入年、月、日、时、分、秒的定制参数,用来构造一个特定时间。需要注意的是月份参数是从0开始计算的,也就是说“1”代表2月,“0”才是1月。

另外还需要注意Date.UTC指定的是UTC时间,如果我们要直接设置本地时间需要手动计算时差。福哥这里传入的小时是13点,对应的北京时间就是21点。

out += "<h3>创建时间</h3>";
out += new Date(Date.UTC(2021, 3, 8, 13, 56, 38)).format("yyyy/MM/dd HH:mm:ss");

时间偏移

时间偏移就是根据当前时间向前(过去)或者向后(未来)进行推移得到一个过去时间或者未来时间。

JavaScript默认也是没有类似Java的Calendar.add功能的,所以福哥又造了一个轮子,用来实现时间的偏移。

后面的讲解中使用的例子都假设在已经引用这个扩展之后运行的,童鞋们可以自行引入到自己的项目当中。

Date.prototype.add = function (field, amount) {
    switch (field) {
        case "year":
            this.setFullYear(this.getFullYear()+amount);
            break;
        case "month":
            this.setMonth(this.getMonth()+amount);
            break;
        case "day":
            this.setDate(this.getDate()+amount);
            break;
        case "hour":
            this.setHours(this.getHours()+amount);
            break;
        case "minute":
            this.setMinutes(this.getMinutes()+amount);
            break;
        case "second":
            this.setSeconds(this.getSeconds()+amount);
            break;
    }

    return this;
};

注意:福哥在实现add扩展的时候没有考虑UTC的情况,因为无论是根据UTC时间进行偏移还是根据本地时间进行偏移结构都是一样的,主要是看format扩展的时候要显示哪个时间。

未来

将当前时间向后偏移可以计算未来的某个时间点。

out += "<h3>明天</h3>";
out += new Date().add("day", 1).format();
out += "<h3>下周的今天</h3>";
out += new Date().add("day", 7).format();
out += "<h3>距离最近的周日还有" + (7-parseInt(new Date().format("w"))) + "天</h3>";
out += "<h3>下个月的今天是周" + (parseInt(new Date().add("month", 1).format("w"))) + "天</h3>";

home/topic/2021/0410/08/a25b35a19b7cdd0124712b6776fa03b3.jpg

过去

将当前时间向前偏移可以计算未来的某个时间点。

out += "<h3>昨天</h3>";
out += new Date().add("day", -1).format();
out += "<h3>上周的今天</h3>";
out += new Date().add("day", -7).format();
out += "<h3>8月8日出生的人去年的生日那天是周" + (parseInt(new Date(Date.UTC(2021, 7, 8, 0, 0, 0)).add("year", -1).format("w"))) + "</h3>";
out += "<h3>8月8日出生的人自上次生日到今天过了" + (parseInt((new Date().getTime()-(new Date(Date.UTC(2021, 7, 8, 0, 0, 0)).add("year", -1).getTime()))/(3600*24*1000))) + "</h3>";

home/topic/2021/0410/09/00fd762f60e8b86cd6a93e01b446096e.jpg

格式化

在我们将系统时间输出出来的时候可以通过福哥造的轮子Date.format提供的一些字符进行格式的自定义。因为福哥比较懒,所以只支持年、月、日、时、分、秒、周的格式。

格式

  • y:年

  • M:月

  • d:日

  • H:时

  • m:分

  • s:秒

  • w:周

UTC时间转本地时间

时区转换过程就是拿到当前时区时间的Date对象,然后通过Date.UTC传入年、月、日、时、分、秒创建UTC时间,再通过Date对象输出格式化后的时间即可。

如果源时间是字符串格式,可以通过Date的parse方法进行解析得到时间的Date对象。

时区转换

out += "<h3>UTC时间</h3>";
nowUTC = new Date().format(null, true);
out += nowUTC;
out += "<h3>本地时间</h3>";
nowDateUTC = new Date(Date.parse(nowUTC));
out += new Date(Date.UTC(nowDateUTC.getFullYear(), nowDateUTC.getMonth(), nowDateUTC.getDate(), nowDateUTC.getHours(), nowDateUTC.getMinutes(), nowDateUTC.getSeconds())).format();

home/topic/2021/0410/09/825875599bc0299ed856ca75b4a3be8e.jpg

总结

今天福哥带着童鞋们对于JavaScript操作日期和时间的技巧系统地学习了一下,相信经过今天的课程之后童鞋们对于在程序里面使用日期和时间的功能会变得得心应手了。

日期和时间的学习暂时告一段落,下一课开始福哥给带着大家了解各种语言操作JSON格式数据的技巧,敬请期待~~