• 【JS】时间问题


    一、JS计算时间差

      返回(天、小时、分钟、秒)

    var date1= '2015/05/01 00:00:00';  //开始时间,为了浏览器兼容性,最好不要用'2015-05-01 00:00:00'
    var date2 = new Date();    //结束时间
    var date3 = date2.getTime() - new Date(date1).getTime();   //时间差的毫秒数     
    var hours = date3 / (3600 * 1000);

    二、JS 时间增加后返回时间

    增加(天、小时、分钟、秒)

    var temp = dateTime.setHours(dateTime.getHours() + 2);

    var inDateTimeMin = new Date(temp);

    注:dateTime 是时间格式

    三、JS中new Date()的浏览器兼容性问题

      引言: 同一种语言javascript,在不同的浏览器中,存在语言兼容性问题,本质上是由于不同的浏览器在支持的语言标准和实现上各有差异。

      以下基于new Date来创建Date对象来分析这个问题。

    1.  问题的提出, 开始时间和结束时间控件无法正确的传递值

        在页面中,我们使用了一个时间组件来开发时间选择框,但是发现在Firefox下是无法正常工作的,在Chrome下是可以正常运行的。 问题出在哪里呢?

    2.  问题分析

       结果分析发现是由于如下代码产生的问题:

    var timestart = '2010-05-04';  
    var timeend = '2015-04-01';  
    var time1 = (timestart+' 00:00:00').toString();  
    var time2 = (timeend+' 23:59:59').toString();  
    timestart = new Date(time1);  
    timeend = new Date(time2); 
    View Code

      问题就在于 new Date(time1)这个构造函数无法正确的生成Date对象,其值为NaN. 怪哉,问题在哪里呢?

    3. 各个浏览器上的表现

        在IE下的执行情况:

     在Firefox下的执行情况和在Chrome下的执行情况,正常

    4. 正确的做法

       以下列出正确的做法:

    var time1 = (timestart+' 00:00:00').toString();  
    var time2 = (timeend+' 23:59:59').toString();  
    timestart = new Date(Date.parse(time1 .replace(/-/g,"/"))).getTime();  
    timeend = new Date(Date.parse(time2 .replace(/-/g,"/"))).getTime(); 
    View Code

    主要的变化是对默认的日期格式进行了转换, 基于'/'格式的日期字符串,才是被各个浏览器所广泛支持的,‘-’连接的日期字符串,则是只在chrome下可以正常工作。

    5. 知识点总结

       '2015-05-04'是无法被各个浏览器中【ie中就不行】,使用new Date(str)来正确生成日期对象的。正确的用法是'2015/05/05'.

    实例:

    var currentTimes = data.TIME.replace("T", " ");
    
        currentTimes = new Date(Date.parse(currentTimes.replace(/-/g, "/"))); //兼容IE浏览器
    
        var nowTimes = new Date().toString('YY/MM/dd/hh/mm/ss');
    
        nowTimes = new Date(Date.parse(nowTimes.replace(/-/g, "/")));//兼容IE浏览器
    View Code

    四、JS计算两个时间差,按x时x分输出

      场景:停车时长,您的车已经停了5小时25分

    var myDate = new Date();//获取系统当前时间

    在后台对数据进行json序列化时,如果数据中包含有日期[dateTime],序列化后返回到前端的结果可能是这样的: /Date(1448864369815)/ 

    var startTime = Base.getLongTime(row.STARTTIME);   //getLongTime见下文

    //如果拿到的不是日期类型,而是"2016-03-28 10:27:00"这种的字符串格式呢,那么就需要先将字符串转换为时间类型

    //使用 /代替- 【 '2015-05-04'是无法被各个浏览器中【ie中就不行】,使用new Date(str)来正确生成日期对象的。 正确的用法是'2015/05/05'.】

    var d1 = startTime.replace(/-/g, "/");   // (st.replace("-","/"));

    var date1 = new Date(d1);  //时间类型

    var diffHour = (parseInt(myDate - date1) / 1000 / 3600) //直接相减是毫秒

    return Base.computeHourTime(diffHour);  //computeHourTime见下文

     自定义的js方法:

    //将/Date(1448864369815)/ 转换为"2016-03-28 10:27:00"
    getLongTime: function (nS) {
            nS = nS.replace("/Date(", "");
            nS = nS.replace(")/", "");
            var dt = new Date(parseInt(nS));
            var $_year = dt.getFullYear();
            var $_month = parseInt(dt.getMonth()) + 1;
            if ($_month.toString().length <= 1) {
                $_month = "0" + $_month;
            }
            var $_day = dt.getDate();
            if ($_day.toString().length <= 1) {
                $_day = "0" + $_day;
            }
            var $_hours = dt.getHours();
            if ($_hours.toString().length <= 1) {
                $_hours = "0" + $_hours;
            }
            var $_minutes = dt.getMinutes();
            if ($_minutes.toString().length <= 1) {
                $_minutes = "0" + $_minutes;
            }
            var $_seconds = dt.getSeconds();
            if ($_seconds.toString().length <= 1) {
                $_seconds = "0" + $_seconds;
            }
            var $_f_date = $_year + "-" + $_month + "-" + $_day + " " + $_hours + ":" + $_minutes + ":" + $_seconds;
            return $_f_date;
        },
    
    computeHourTime: function (hour) { //hour是两个时间差 用小时表示,可以为小数
            var r = "";
            r = this.computeMinTime(hour * 60);
            return r;
        }
    
    computeMinTime: function (min) {
            var r = "";
            if (min < 0) {
                r = "-";
            } else if (min == 0) {
                r = "0分";
            } else {
                var m = min % 60;//
                var h = parseInt(min / 60);//
                var d = parseInt(h / 24);//
                h = h - d * 24;
    
                if (d != 0) {
                    r += d + "天";
                }
                if (h != 0) {
                    r += h + "时";
                }
                if (m != 0) {
                    r += Math.ceil(m) + "分";
                }
            }
            return r;
        },
    View Code

    五、JS中比较两个时间的大小

    第一种:直接比较大小即可

    var st="2009-10-20 14:38:40"
    var et="2009-10-20 15:38:40"
    if(st>et)
      alert("开始时间必须小于结束时间")

    第二种:转换为date对象进行比较操作

    var st="2009-10-20 14:38:40"
    var et="2009-10-20 15:38:40"
    var stdt=new Date(st.replace("-","/"));
    var etdt=new Date(et.replace("-","/"));
    if(stdt>etdt) alert("开始时间必须小于结束时间")

     或者

    function compareDate(s1,s2){
      return ((new Date(s1.replace(/-/g,"/")))>(new Date(s2.replace(/-/g,"/"))));
    }

    第三种:  对不明时间字符串格式

    var curTime = new Date();
    //把不明字符串格式 先转换为毫秒数(Date.parse),再转化为日期类
    var starttime = new Date(Date.parse(begintime));
    var endtime = new Date(Date.pares(endtime));
    return (curTime>=starttime && cutTime<=endtime);

    六、AngularJS 时间格式化处理

      1、AngularJs的controller中格式:

     var dateAsString = $filter('date')(item_date, "yyyy-MM-dd hh:mm:ss"); 

    注意: controller需要注入$filter

      2、 AngularJs的views中格式:

    {{item_date | date:'yyyy-MM-dd hh:mm:ss'}}

    七、时间字段Json序列化问题

      在后台对数据进行json序列化时,如果数据中包含有日期[dateTime],序列化后返回到前端的结果可能是这样的: /Date(1448864369815)/  。

    参考:https://www.cnblogs.com/similar/p/5810304.html

    转换1: json时间【‘/Date(1543248000000)/’】转为日期字符串类型,

    var jsonToDate = function GetDateFormat(str) {
                    if (str) {
           return new Date(parseInt(str.substr(6, 13))).toLocaleDateString(); //年月日
                    }
                };

    慎用toLocaleDateString【见第八点】

    转换2:时间字符串 转换为时间格式【angularJS中时间过滤必须是datetime格式】

    $scope.toDate = function (strDate) {
                    if (!strDate) {
                        return new Date();
                    }
                    else {
                        return new Date(strDate);
                    }
                }

    注:可以 将angularJS中传递到后台的时间字段 设置为string格式【后台字段】。

    这样后台再传回来的时候 也是string格式。。而不会出现json时间格式(/Date(1543248000000)/)  后台需要转为时间的时候再转换。

    八、关于toLocaleDateString的坑

      1、Date.toLocaleString()  功能:根据本地时间把Date对象转换为字符串。

    语法:DateObject.toLocaleString()

    返回值:Date对象的字符串表示,以本地时间区表示,并根据本地规则格式化。

      2、Date.toLocaleDateString()

    功能:根据本地时间把Date对象的日期部分转换为字符串。

    语法:DateObject.toLocaleDateString()

    返回值:Date对象日期部分的字符串表示,以本地时间区表示,并根据本地规则格式化。

      3、Date.toLocaleTimeString()

    功能:根据本地时间把Date对象的时间部分转换为字符串。

    语法:DateObject.toLocaleTimeString()

    返回值:Date对象时间部分的字符串表示,以本地时间区表示,并根据本地规则格式化。

    注:时、分、秒字段各占2位数字,如果它们的值小于10,会自动添加前置0。

    new Date().toLocaleString()  // "2018/12/6 上午10:26:57"
    new Date().toLocaleDateString()  //"2018/12/6"
    new Date().toLocaleTimeString()  //"上午10:33:04"

    以下js报错 uncaught TypeError: cannot read property 'length' of undefined.

    const dateTransform = date => {
    
        const tmp = date.split('/');
    
        if (tmp[1].length !== 2) {
    
            tmp[1] = '0' + tmp[1];
    
        }
    
        if (tmp[2].length !== 2) {
    
            tmp[2] = '0' + tmp[2];
    
        }
    
        return tmp.join('-');
    
    }
    
    dateTransform(new Date().toLocaleDateString());
    View Code

    看到这段代码瞬间崩溃,怎么用这种方式处理时间显示 ????????????????

    姑且认为某猿是加班到凌晨2点写的代码吧(同个物种之间要懂得体谅)。该猿的思路是转换形如"2017/5/12"这样的字符串为"2017-5-12",讲道理可以跑起来的。但是为什昨天的代码,到了今天就无法执行了呢?一定是toLocaleDateString的问题。笔者在firefox中执行了这一段代码,完全正常,但是在chrome中报错。浏览器的问题?

    # chrome

    console.log(new Date().toLocaleDateString())

    > 2017-5-12

    #firefox

    console.log(new Date().toLocaleDateString())

    > 2017/5/12

    找到问题了,就是toLocaleDateString的坑。至于为什么昨天能跑,今天不能跑,秒懂啦。chrome升级了。从57升级到了58

    #Chrome < 58

    > new Date().toLocaleDateString()

    > output: "2017/5/12"

    #Chrome >= 58

    > new Date().toLocaleDateString()

    > output: "2017-5-12"

    用moment去实现Date格式化。

    后记:首先看看toLocaleDateString是什么东西:

    toLocaleDateString() 方法返回该日期对象日期部分的字符串,该字符串格式因不同语言而不同。新增的参数 locales 和 options 使程序能够指定使用哪种语言格式化规则,允许定制该方法的表现(behavior)。

    在旧版本浏览器中, locales 和 options 参数被忽略,使用的语言环境和返回的字符串格式是各自独立实现的。

    from https://developer.mozilla.org...

    这方法最大的问题是在不同的浏览器中得到的结果是不一样的,例如

    # firefox
    > new Date().toLocaleDateString()
    > output: "2017/5/12"

    #IE11
    > new Date().toLocaleDateString()
    > output: "2017-5-12"
     
    #Chrome < 58
    > new Date().toLocaleDateString()
    > output: "2017/5/12"

     
    #Chrome >= 58
    > new Date().toLocaleDateString()
    > output: "2017-5-12"

    所以尽可能不要用toLocaleDateString

     

     

     

  • 相关阅读:
    截取
    逃避系统警察
    刷题
    排队
    侦察兵
    朋友
    楼层
    解码
    倒水
    魔法阵
  • 原文地址:https://www.cnblogs.com/peterYong/p/10880043.html
Copyright © 2020-2023  润新知