防止JavaScript中的隐式日期转换

时间:2013-07-25 00:32:18

标签: javascript date implicit-conversion date-conversion function-overriding

我有一个从不同时区使用的应用程序。如果有人进入纽约(东部时间)的数据库,它应该显示在纽约时间输入的人(它通过大部分应用程序完成)。但是,当来自时区之外的某人查看它时,似乎时间被转换为该用户的时区。

我正在尝试停止转换或将转换转换为正确的时间。它正确传递给javascript,它位于发现问题的javascript中。

对象的日期字符串显示(例如)“Fri Aug 21 12:30:00 PDT 2013”​​。

我修改了this function以使用美国夏令时并使用中央时区。我还使用了this function来处理从格式到unix时代的日期。

我在想,如果“PDT”或任何其他时区标识符(“CST”,“MST”,“PST”等),则可能不会发生转换。我会注意到除了“PDT”之外的时间戳是我需要的正确时间,但有些事情会在2小时前显示出来。

我的主要问题是,如果有人在2013年7月24日下午1点在纽约进入,那么无论我在查看数据时处于哪个时区,都应该说。这是问题所在:

  1. 用户从一个位置进入系统(并非总是如此 2013年7月24日,纽约,但它很容易作为一个例子使用 下午3:00。
  2. 从数据库和应用程序发送 正确的javascript(2013年7月24日下午3:00)
  3. 如果我处于不同的时区(让我们说中央),那么日期是 在javascript中的对象中显示为(Wed Jul 24 3:00 CDT 2013)。 < - 正如你所看到的那样在技术上仍然是正确的 “CDT”的时区标识符。如果时间基本相同,如果 从某种程度上来说,删除它的标识符,我想我 会是金色的。
  4. 未调用任何其他功能,现在显示日期为7/24/2013 2:00。
  5. 任何想法都会非常有帮助。这是我的转换功能:

    function calcTime(date) {
    //This is to pad the date with a zero if the
    //number is less than 10. eg 7/1/2013 = 07/01/2013
    function pad(num) {
        num = num.toString();
        if (num.length == 1) return "0" + num;
        return num;
    }
    
    //I needed to have my date passed in as string
    //This will set the date to the string and then get the time from
    //that date. It will then set that time.
    var date = new Date(date);
    var time = date.getTime();
    date.setTime(time);
    
    var year = date.getUTCFullYear();
    
    //This nifty little thing will get you the daylight savings time
    // and adjust correctly. In the US, prior to 2006 the DST started
    //first sunday in April and ended in the last sunday in October.
    //After 2007, it was changed to start on the 2nd sunday in March
    //and end in the first sunday in November. If you are working
    //with a different country, please follow this link for
    //the equations in relation to their daylight savings time.
    //http://www.webexhibits.org/daylightsaving/i.html
    if (year <= 2006) {
        var start_day = (2 + ((((6 * year) - year / 4) % 7) + 1));
        var DST_start = new Date(Date.UTC(year, 3, start_day, 1, 0, 0));
    
        var end_day = (31 - ((((5 * year) / 4) + 1) % 7));
        var DST_end = new Date(Date.UTC(year, 9, end_day, 1, 0, 0));
    }
    
    if (year >= 2007) {
        start_day = (14 - ((1 + (year * 5) / 4) % 7));
        DST_start = new Date(Date.UTC(year, 2, start_day, 1, 0, 0));
    
        end_day = (7 - ((1 + (year * 5) / 4) % 7));
        DST_end = new Date(Date.UTC(year, 10, end_day, 1, 0, 0));
    }
    
    //This function is supposed to make sure no matter where you are,
    //you can see this in US central time. Obviously you will need to
    //change this if you need a different time zone.
    //All timezones to the west of GMT to the International Date Line will be negative.
    //Timezones east of GMT to the International Date Line will be positive.
    //The below offset is if it is DST, it adjusts the time accordingly.
    var centralOffset = -6 * 60 * 60 * 1000;
    if (date > DST_start && date < DST_end) centralOffset = -5 * 60 * 60 * 1000;
    
    date.setTime(time + centralOffset);
    
    //This will call the pad function to return a two digit month/day format.
    //Dates are zero based in JS and needed to add 1 to the UTCMonth so we receive the
    //current month
    var centralTime = pad(date.getUTCMonth() + 1) + "/" +
    pad(date.getUTCDate()) + "/" + date.getUTCFullYear() +
    " " + pad(date.getUTCHours()) + ":" +
    pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds());
    
    return centralTime;
    };
    
    //Test Data
    var date = "7/25/2013 09:30:00";
    calcTime(date);
    

    更新 我运气不好。我已经能够成功删除时区标识符,但是当我有一个正确日期的新字符串并尝试将其传递给新的Date函数时,它会重新放入标识符。请参阅下面的更新代码。

    function getDateTime() {
      function pad(num) {
        num = num.toString();
        if (num.length == 1) return "0" + num;
        return num;
    }
    
    
    var timezones = ["PST", "PDT", "MST", "MDT", "CST", "CDT", "EST", "EDT", "GMT"];
    
    var date = this; //this = "Wed Aug 21 14:38:00 CST 2013" or whatever date is being passed in
    
    //This converts date to string so it can remove the time zone identifier.
    date = date.toDateString();
    
    var length = timezones.length;
    while (length--) {
        if (date.indexOf(timezones[length]) != -1) {
            date = date.replace(timezones[length], "");
        }
    }
    
    date = new Date(date); // This pretty much defeats all that I did above.
    //date = Date(date); //This will give the current date and time.
    
    var month = pad(date.getMonth() + 1);
    var day = pad(date.getDate());
    var year = date.getFullYear();
    var hour = pad(date.getHours());
    var minute = pad(date.getMinutes());
    var second = pad(date.getSeconds());
    
    
    if (hour > 12) {
        var timestring = hour.toString() + ":" + minute.toString() + ":" + second.toString() + " PM";
    } else {
        timestring = hour.toString() + ":" + minute.toString() + ":" + second.toString() + " AM";
    }
    
    var output = month.toString() + "/" + day.toString() + "/" + year.toString() + " " +   timestring;
    
    return output;
    
    }
    

    希望这可以清除其他任何人在原帖中可能产生的混淆。

1 个答案:

答案 0 :(得分:1)

使用多个字符串替换来保留原始字符串:

var foo = "2013-10-01T09:00:00.000-04:00";
var bar = foo.substr(-6);
var baz = foo.substr(11,2)
var isoDate = new Date(foo).toISOString().replace("Z",bar).replace(/T../,"T"+baz);
var hours = String(baz).concat(Number(baz) < 12 ? "PM" : "AM").replace(/^0/,"")