Предотвращение неявного преобразования даты в JavaScript

У меня есть приложение, которое используется из разных часовых поясов. Если кто-то введен в базу данных в Нью-Йорке (восточное время), на нем должно отображаться лицо, введенное в нью-йоркском времени (что и происходит в большинстве приложений). Однако, когда кто-то за пределами часового пояса просматривает его, кажется, что время конвертируется в часовой пояс этого пользователя.

Я пытаюсь либо остановить преобразование, либо выполнить преобразование в нужное время. Он передается в JavaScript правильно, именно в JavaScript, где проблема найдена.

Строка даты для объекта показывает (например) "Пт 21 августа, 12:30:00 PDT 2013".

Я изменил эту функцию для работы с американским летним временем и для использования центрального часового пояса. Я также использовал эту функцию для обработки даты от формата до эпохи Unix.

Я думал, что если "PDT" или любой другой идентификатор часового пояса ("CST", "MST", "PST" и т. Д.), То, возможно, преобразование не произойдет. Я отмечу, что отметка времени, отличная от "PDT", - это правильное время, которое мне нужно, но что-то происходит, когда оно отображается на 2 часа раньше.

Моя главная проблема - если кто-то введен в 13:00 24.07.2013 в Нью-Йорке, он все равно должен сказать, что независимо от того, в каком часовом поясе я нахожусь, когда я просматриваю эти данные. Вот проблема:

  1. Пользователь вводится в систему из местоположения (это не всегда Нью-Йорк, но его легко использовать в качестве примера) 24.07.2013 в 15:00.
  2. Он отправляется из базы данных и через приложение к JavaScript правильно (24.07.2013 15:00)
  3. Если я нахожусь в другом часовом поясе (скажем, в центральном), дата отображается в объекте в javascript как (ср. 24 июля, 3:00 CDT 2013).<- Как вы видите, все еще технически правильно, кроме этого идентификатора часового пояса "CDT". Если время, как правило, совпадает, если есть какой-то способ удалить этот идентификатор из него, я думаю, я был бы золотым.
  4. Никакая другая функция не вызывается, и теперь она показывает дату как 24.07.2013, 2:00.

Любые мысли были бы чрезвычайно полезны. Вот моя функция преобразования:

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 ответ

Решение

Используйте несколько подстановок строк, чтобы сохранить исходную строку:

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/,"")
Другие вопросы по тегам