Я знаю, что должен быть более простой способ сделать это: модель функции Javascript, возвращающая дату

Я должен сказать, я не эксперт с датами Javascript.. вообще! Я, например, посмотрел на DateJS, но моя проблема не просто в конвертации даты (или, может быть, так и должно быть!).

Краткая справка: у меня есть сервисный вызов, который возвращает некоторые данные JSON, которые содержат страшную дату в стиле Epoch из WCF/REST (в настоящее время я не могу использовать Webapi - что даст мне родной JSON.NET?).

Итак, пример даты из объекта JSON:

StartDate: "/Date(1343378404560+0100)/"

Теперь JSON, возвращенный из моего вызова, содержит больше информации, которая мне нужна для моего объекта календаря событий Wijmo, поэтому я подумал, что хорошо, создам функцию / модель Javascript для моего объекта события Wijmo и использую функцию jQuery MAP, чтобы выбрать только те поля, которые я необходимость.

Моя модель событий Javascript выглядит так:

function wijmoEventModel(in_id, in_calendar, in_subject, in_location, in_start, in_end, in_description, in_colour, in_allday, in_tag) {

    this._id = in_id;
    this._calendar = in_calendar;
    this._subject = in_subject;
    this._location = in_location;
    this._start = jsonDate(in_start);
    this._end = jsonDate(in_end);
    this._description = in_description;
    this._colour = in_colour;
    this._allday = in_allday;
    this._tag = in_tag;

    //  Public Properties/Methods
    return {
        id: this.id,
        calendar: this._calendar,
        subject: this._subject,
        location: this._location,
        start: this._start,
        end: this._end,
        description: this._description,
        color: this._colour,
        allday: this._allday,
        tag: this._tag
    }
};

Итак, у меня есть еще одна маленькая функция, которая использует функцию jQuery MAP следующим образом:

function returnWijmoCalendarObject(diaryEventData) {

    //  Using jQuery map, reduce our raw event data down to only the required wijmo calendar items
    var _calobj = $.map(diaryEventData, function (fld) {
        return new wijmoEventModel(fld.ID, fld.ResourceCalendarID, fld.EventTitle, fld.Location, fld.StartDate, fld.EndDate, fld.Description, fld.ResourceColour, fld.AllDay);
    });
    return {
        calendardata: _calobj
    }
};

Поэтому вышеупомянутая функция просто выбирает обязательные поля из моего исходного полного возврата JSON и использует мою функцию / модель Javascript для возврата нового объекта JSON "calendardata", который я могу использовать с моим календарем событий Wijmo.

Есть еще одна небольшая функция, которая преобразует дату в стиле эпохи "/Date(1343378404560+0100)/" в (я думаю!) Реальный объект Javascript Date.. вот так:

function jsonDate(rawDate) {

    var d = new Date();
    d.setMilliseconds = parseInt(rawDate.substr(6));
    return d;
}

Таким образом, приведенная выше небольшая функция, конечно, используется в первом блоке кода выше, чтобы, надеюсь, преобразовать исходную дату в стиле Epoch в дату Javascript.

ТАК МОЙ ВОПРОС / ПРОБЛЕМА:

Приведенная выше модель и функция отображения jQuery работают хорошо, я получаю подмножество объекта JSON именно той структуры, которая мне нужна, однако возвращаемые даты (wijmoEventModel.start & end) не возвращаются как объект Date Javascript?? хотя отладка в этом wijmoEventModel определенно имеет даты как объекты даты JS??

Очевидно, я упускаю / не понимаю некоторые жизненно важные и фундаментальные аспекты здесь!!!

ПОЖАЛУЙСТА! если кто-то может помочь, так как это сводит меня с ума...

Дэвид.

2 ответа

Решение

Установка миллисекунд только устанавливает часть даты в миллисекундах, она не устанавливает дату из эпохи.

В основе javascript-объекта даты лежит количество миллисекунд с 1970-01-01 по 00:00:00 в UTC. Так что, если у вас есть "время с начала эпохи", то если вы конвертируете его в число, вы можете сделать:

var d = new Date( Number(millisecondsSinceEpoch) );

См. ECMA-262 15.9.3.2

Это создаст объект даты в местном часовом поясе на основе "времени с начала эпохи" в UTC. Таким образом, в разных часовых поясах будет отображаться разное время, представляющее один и тот же момент в UTC.

например

var millisecondsSinceEpoch = '1343378404560';
alert( new Date(Number(millisecondsSinceEpoch))); //Fri Jul 27 2012 18:40:04 GMT+1000 (EST)

Время в ОП равно "1343378404560+0100", что подразумевает смещение, которое, как я полагаю, будет hhmm. Так что это должно быть вычтено из числа перед передачей его в Date:

var s = '1343378404560+0100';
var t = s.split('+')[1];

if (t) {
  t = t.substring(0,2)*3600 + t.substring(2)*60;
} else {
  t = 0;
}

var d = new Date(parseInt(s) - t * 1000);  // Fri Jul 27 2012 17:40:04 GMT+1000 (EST)

редактировать

Выше предполагается, что знак "+", строка должна быть разбита на "+" или "-", затем знак обнаруживается и применяется позже, например

var t = s.split(/[-+]/)[1];

После установки значения t примените знак:

t *= /-/.test(s)? -1000 : 1000;
var d = new Date(parseInt(s) - t);

Или какой-то вариант из вышеперечисленного.

В функции jsonDate свойство setMilliseconds для d (не самого d) будет датой, из которой вы могли бы вызывать wijmoEventModel.start.d, Вы на самом деле хотите var d = new Date(parseInt(rawDate.substr(6))), (Или ты хочешь var d = new Date(parseInt(rawDate.split('+')[0]))?)

Другие вопросы по тегам