Я беру свой первый кряк в Ajax с помощью jQuery. Я получаю свои данные на свою страницу, но у меня возникают проблемы с данными JSON, которые возвращаются для типов данных Date. По сути, я получаю строку, которая выглядит следующим образом:
/Date(1224043200000)/
От кого-то совершенно нового для JSON - Как мне отформатировать это в короткий формат даты? Должно ли это быть обработано где-то в коде jQuery? Я пытался использовать jQuery.UI.datepicker
плагин $.datepicker.formatDate()
без какого-либо успеха.
К вашему сведению: вот решение, которое я придумал, используя комбинацию ответов здесь:
function getMismatch(id) {
$.getJSON("Main.aspx?Callback=GetMismatch",
{ MismatchId: id },
function (result) {
$("#AuthMerchId").text(result.AuthorizationMerchantId);
$("#SttlMerchId").text(result.SettlementMerchantId);
$("#CreateDate").text(formatJSONDate(Date(result.AppendDts)));
$("#ExpireDate").text(formatJSONDate(Date(result.ExpiresDts)));
$("#LastUpdate").text(formatJSONDate(Date(result.LastUpdateDts)));
$("#LastUpdatedBy").text(result.LastUpdateNt);
$("#ProcessIn").text(result.ProcessIn);
}
);
return false;
}
function formatJSONDate(jsonDate) {
var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
return newDate;
}
Это решение получило мой объект из метода обратного вызова и правильно отобразило даты на странице, используя библиотеку формата даты.
eval()
не обязательно. Это будет хорошо работать:
var date = new Date(parseInt(jsonDate.substr(6)));
substr()
Функция вынимает /Date(
часть, а parseInt()
функция получает целое число и игнорирует )/
в конце. Полученный номер передается в Date
конструктор.
Я намеренно пропустил основание (второй аргумент parseInt
); см. мой комментарий ниже .
Кроме того, я полностью согласен с комментарием Рори : даты ISO-8601 предпочтительнее этого старого формата, поэтому этот формат обычно не следует использовать для новых разработок. Посмотрите превосходную библиотеку Json.NET для отличной альтернативы, которая сериализует даты, используя формат ISO-8601.
Для дат JSON в формате ISO-8601 просто передайте строку в Date
конструктор:
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
В JSON нет встроенного типа даты . Это похоже на количество секунд / миллисекунд от некоторой эпохи. Если вы знаете эпоху, вы можете создать дату, добавив нужное количество времени.
Если вы говорите в JavaScript,
var thedate = new Date(1224043200000);
alert(thedate);
вы увидите, что это правильная дата, и вы можете использовать ее в любом месте кода JavaScript с любым фреймворком.
Вы можете использовать это, чтобы получить дату из JSON:
var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
И затем вы можете использовать сценарий формата даты JavaScript (1,2 КБ при минимизации и сжатии), чтобы отобразить его, как вы хотите.
jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1'));
Ваш JSON, вероятно, должен возвращать какой-либо объект (ну, его строковое представление).
"{ myDate : Date(1224043200000) }"
Используя jQuery, вы можете получить доступ к вашему объекту данных следующим образом:
$.get(
"myJSONFile.php",
function (data) {
// data.myDate will be a date object.
// to show in a short date format (eg: dd/mm/yyyy)
alert (
data.myDate.getDate() + "/"
+ (data.myDate.getMonth() + 1) + "/"
+ data.myDate.getFullYear()
); // alerts: "15/10/2008"
}
);
Проверьте дату стандарта ISO; вроде как это:
yyyy.MM.ddThh:mm
Это становится 2008.11.20T22:18
.
var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
Есть ли другой вариант без использования библиотеки jQuery?
В итоге я добавил символы "в регулярное выражение Panos, чтобы избавиться от символов, сгенерированных сериализатором Microsoft для записи объектов во встроенный скрипт:
Так что если у вас есть свойство в вашем коде C # это что-то вроде
protected string JsonObject { get { return jsSerialiser.Serialize(_myObject); }}
И в вашем aspx у вас есть
<script type="text/javascript">
var myObject = '<%= JsonObject %>';
</script>
Вы получите что-то вроде
var myObject = '{"StartDate":"\/Date(1255131630400)\/"}';
Обратите внимание на двойные кавычки.
Чтобы получить это в форме, которую eval будет правильно десериализовать, я использовал:
myObject = myObject.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
Я использую Prototype и для его добавления я добавил
String.prototype.evalJSONWithDates = function() {
var jsonWithDates = this.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
return jsonWithDates.evalJSON(true);
}
Поздний пост, но для тех, кто искал этот пост.
Вообразите это:
[Authorize(Roles = "Administrator")]
[Authorize(Roles = "Director")]
[Authorize(Roles = "Human Resources")]
[HttpGet]
public ActionResult GetUserData(string UserIdGuidKey)
{
if (UserIdGuidKey!= null)
{
var guidUserId = new Guid(UserIdGuidKey);
var memuser = Membership.GetUser(guidUserId);
var profileuser = Profile.GetUserProfile(memuser.UserName);
var list = new {
UserName = memuser.UserName,
Email = memuser.Email ,
IsApproved = memuser.IsApproved.ToString() ,
IsLockedOut = memuser.IsLockedOut.ToString() ,
LastLockoutDate = memuser.LastLockoutDate.ToString() ,
CreationDate = memuser.CreationDate.ToString() ,
LastLoginDate = memuser.LastLoginDate.ToString() ,
LastActivityDate = memuser.LastActivityDate.ToString() ,
LastPasswordChangedDate = memuser.LastPasswordChangedDate.ToString() ,
IsOnline = memuser.IsOnline.ToString() ,
FirstName = profileuser.FirstName ,
LastName = profileuser.LastName ,
NickName = profileuser.NickName ,
BirthDate = profileuser.BirthDate.ToString() ,
};
return Json(list, JsonRequestBehavior.AllowGet);
}
return Redirect("Index");
}
Как вы можете видеть, я использую функцию C # 3.0 для создания «авто» Generics. Это немного лениво, но мне это нравится, и это работает. Просто примечание: Профиль - это пользовательский класс, который я создал для своего проекта веб-приложения.
Не думай об этом. Как и в течение десятилетий, передайте числовое смещение от стандартной фактической эпохи 1 января 1970 года по полуночи GMT / UTC / & c в секундах (или миллисекундах) с этой эпохи. JavaScript нравится, Java нравится, C нравится, а Интернету нравится.
Оригинальный пример:
/Date(1224043200000)/
не отражает форматирование, используемое WCF при отправке дат через WCF REST с использованием встроенной сериализации JSON. (по крайней мере, на .NET 3.5, SP1)
Я нашел ответ здесь полезным, но требуется небольшое редактирование регулярного выражения, так как кажется, что смещение часового пояса GMT добавляется к числу, возвращенному (с 1970 года) в WCF JSON.
В службе WCF у меня есть:
[OperationContract]
[WebInvoke(
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest
)]
ApptVisitLinkInfo GetCurrentLinkInfo( int appointmentsId );
ApptVisitLinkInfo определяется просто:
public class ApptVisitLinkInfo {
string Field1 { get; set; }
DateTime Field2 { get; set; }
...
}
Когда «Field2» возвращается как Json из службы, значение равно:
/Date(1224043200000-0600)/
Обратите внимание на смещение часового пояса, включенное как часть значения.
Модифицированное регулярное выражение:
/\/Date\((.*?)\)\//gi
Это немного более нетерпеливо и захватывает все между паренами, а не только первый номер. Полученное время sinze 1970, плюс смещение часового пояса, все могут быть переданы в eval для получения объекта даты.
Результирующая строка JavaScript для замены:
replace(/\/Date\((.*?)\)\//gi, "new Date($1)");
Для тех, кто использует Newtonsoft Json.NET , читайте о том, как сделать это через Native JSON в IE8, Firefox 3.5 плюс Json.NET .
Также полезна документация по изменению формата дат, написанных Json.NET: Сериализация дат с помощью Json.NET
Для тех, кто слишком ленив, вот быстрые шаги. Поскольку JSON имеет свободную реализацию DateTime, вам нужно использовать IsoDateTimeConverter()
. Обратите внимание, что начиная с Json.NET 4.5 формат даты по умолчанию - ISO, поэтому приведенный ниже код не требуется.
string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());
JSON будет проходить как
"fieldName": "2009-04-12T20:44:55"
Наконец, немного JavaScript для преобразования даты ISO в дату JavaScript:
function isoDateReviver(value) {
if (typeof value === 'string') {
var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(?:([\+-])(\d{2})\:(\d{2}))?Z?$/.exec(value);
if (a) {
var utcMilliseconds = Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]);
return new Date(utcMilliseconds);
}
}
return value;
}
Я использовал это так
$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);
new Date("2009-04-12T20:44:55")
+a[1]
etc представляет части массива регулярного выражения, и +
он будет приводить его к числу, +a[1]
равному 2009
и т. д. Вот разбивка массива: 0: "2009-04-12T20:44:55" 1: "2009" 2: "04" 3: "12" 4: "20" 5: "44" 6: "55"
Mootools решение:
new Date(Date(result.AppendDts)).format('%x')
Требует mootools-больше. Протестировано с использованием mootools-1.2.3.1-more на Firefox 3.6.3 и IE 7.0.5730.13
К вашему сведению, для тех, кто использует Python на стороне сервера: datetime.datetime (). Ctime () возвращает строку, которая изначально анализируется с помощью «new Date ()». То есть, если вы создаете новый экземпляр datetime.datetime (например, с datetime.datetime.now), строка может быть включена в строку JSON, а затем эта строка может быть передана в качестве первого аргумента конструктору Date. Я еще не нашел каких-либо исключений, но я не проверял это слишком строго.
Я получаю дату как это:
"/Date(1276290000000+0300)/"
В некоторых примерах дата имеет несколько разные форматы:
"/Date(12762900000000300)/"
"Date(1276290000000-0300)"
и т.п.
Итак, я придумал следующий RegExp:
/\/+Date\(([\d+]+)\)\/+/
и окончательный код:
var myDate = new Date(parseInt(jsonWcfDate.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1')));
Надеюсь, это поможет.
Обновление: Я нашел эту ссылку от Microsoft: Как мне сериализовать даты с помощью JSON?
Это похоже на то, что мы все ищем.
Публикация в отличной теме:
var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));
Это расстраивает. Мое решение состояло в том, чтобы разобрать «/ и /» из значения, сгенерированного JavaScriptSerializer ASP.NET, так что, хотя JSON может не иметь литерала даты, он все равно будет интерпретироваться браузером как дата, и это все, что я на самом деле хотеть:{"myDate":Date(123456789)}
Пользовательский JavaScriptConverter для DateTime?
Я должен подчеркнуть точность комментария Роя Тинкера. Это не законный JSON. Это грязный, грязный хак на сервере, чтобы удалить проблему, прежде чем она станет проблемой для JavaScript. Он захлебнется парсером JSON. Я использовал это для того, чтобы оторваться от земли, но я больше не использую это. Тем не менее, я все еще чувствую, что лучший ответ заключается в изменении того, как сервер форматирует дату, например, ISO, как упоминалось в другом месте.
Не повторяйте себя - автоматизируйте преобразование даты с помощью $.parseJSON()
Ответы на ваш пост обеспечивают ручное преобразование дат в даты JavaScript. Я $.parseJSON()
немного расширил jQuery , поэтому он может автоматически разбирать даты, когда вы указываете это. Он обрабатывает даты в формате ASP.NET ( /Date(12348721342)/
), а также даты в формате ISO ( 2010-01-01T12.34.56.789Z
), которые поддерживаются встроенными функциями JSON в браузерах (и библиотеках, таких как json2.js).
Так или иначе. Если вы не хотите повторять ваш код преобразования даты снова и снова, я предлагаю вам прочитать этот пост в блоге и получить код, который сделает вашу жизнь немного проще.
обновленный
У нас есть внутренняя библиотека пользовательского интерфейса, которая должна справляться как со встроенным форматом JSON Microsoft ASP.NET, например /Date(msecs)/
, о котором мы спрашивали здесь изначально, так и с большинством форматов дат JSON, включая JSON.NET 2014-06-22T00:00:00.0
. Кроме того, нам нужно справиться с неспособностью oldIE справиться с чем-либо, кроме трех знаков после запятой .
Сначала мы определяем, какую дату мы потребляем, анализируем ее в обычный Date
объект JavaScript , а затем форматируем ее.
1) Определить формат даты Microsoft
// Handling of Microsoft AJAX Dates, formatted like '/Date(01238329348239)/'
function looksLikeMSDate(s) {
return /^\/Date\(/.test(s);
}
2) Определить формат даты ISO
var isoDateRegex = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d\d?\d?)?([\+-]\d\d:\d\d|Z)?$/;
function looksLikeIsoDate(s) {
return isoDateRegex.test(s);
}
3) Парс MS формат даты:
function parseMSDate(s) {
// Jump forward past the /Date(, parseInt handles the rest
return new Date(parseInt(s.substr(6)));
}
4) Разобрать формат даты ISO.
По крайней мере, у нас есть способ быть уверенным, что мы имеем дело со стандартными датами ISO или датами ISO, измененными так, чтобы они всегда имели три миллисекунды ( см. Выше ), поэтому код отличается в зависимости от среды.
4a) Разобрать стандартный формат даты ISO, справиться с проблемами oldIE:
function parseIsoDate(s) {
var m = isoDateRegex.exec(s);
// Is this UTC, offset, or undefined? Treat undefined as UTC.
if (m.length == 7 || // Just the y-m-dTh:m:s, no ms, no tz offset - assume UTC
(m.length > 7 && (
!m[7] || // Array came back length 9 with undefined for 7 and 8
m[7].charAt(0) != '.' || // ms portion, no tz offset, or no ms portion, Z
!m[8] || // ms portion, no tz offset
m[8] == 'Z'))) { // ms portion and Z
// JavaScript's weirdo date handling expects just the months to be 0-based, as in 0-11, not 1-12 - the rest are as you expect in dates.
var d = new Date(Date.UTC(m[1], m[2]-1, m[3], m[4], m[5], m[6]));
} else {
// local
var d = new Date(m[1], m[2]-1, m[3], m[4], m[5], m[6]);
}
return d;
}
4b) Разобрать формат ISO с фиксированным трех миллисекундным десятичным знаком - намного проще:
function parseIsoDate(s) {
return new Date(s);
}
5) Отформатируйте это:
function hasTime(d) {
return !!(d.getUTCHours() || d.getUTCMinutes() || d.getUTCSeconds());
}
function zeroFill(n) {
if ((n + '').length == 1)
return '0' + n;
return n;
}
function formatDate(d) {
if (hasTime(d)) {
var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
s += ' ' + d.getHours() + ':' + zeroFill(d.getMinutes()) + ':' + zeroFill(d.getSeconds());
} else {
var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
}
return s;
}
6) Свяжите все это вместе:
function parseDate(s) {
var d;
if (looksLikeMSDate(s))
d = parseMSDate(s);
else if (looksLikeIsoDate(s))
d = parseIsoDate(s);
else
return null;
return formatDate(d);
}
Приведенный ниже старый ответ полезен для того, чтобы связать это форматирование даты с собственным JSON-анализом JSON, чтобы вы получали объекты Date вместо строк, или если вы все равно застряли в jQuery <1.5.
Старый ответ
Если вы используете функцию Ajax jQuery 1.4 с ASP.NET MVC, вы можете превратить все свойства DateTime в объекты Date с помощью:
// Once
jQuery.parseJSON = function(d) {return eval('(' + d + ')');};
$.ajax({
...
dataFilter: function(d) {
return d.replace(/"\\\/(Date\(-?\d+\))\\\/"/g, 'new $1');
},
...
});
В jQuery 1.5 вы можете избежать parseJSON
глобального переопределения метода, используя опцию преобразователей в вызове Ajax.
http://api.jquery.com/jQuery.ajax/
К сожалению, вам нужно переключиться на более старый маршрут eval, чтобы Dates мог анализироваться глобально, иначе вам нужно конвертировать их в более индивидуальном порядке после анализа.
В jQuery 1.5, если у вас есть json2.js для старых браузеров, вы можете десериализовать все даты из Ajax следующим образом:
(function () {
var DATE_START = "/Date(";
var DATE_START_LENGTH = DATE_START.length;
function isDateString(x) {
return typeof x === "string" && x.startsWith(DATE_START);
}
function deserializeDateString(dateString) {
var dateOffsetByLocalTime = new Date(parseInt(dateString.substr(DATE_START_LENGTH)));
var utcDate = new Date(dateOffsetByLocalTime.getTime() - dateOffsetByLocalTime.getTimezoneOffset() * 60 * 1000);
return utcDate;
}
function convertJSONDates(key, value) {
if (isDateString(value)) {
return deserializeDateString(value);
}
return value;
}
window.jQuery.ajaxSetup({
converters: {
"text json": function(data) {
return window.JSON.parse(data, convertJSONDates);
}
}
});
}());
Я включил логику, которая предполагает, что вы отправляете все даты с сервера в формате UTC (что вам следует); Затем потребитель получает Date
объект JavaScript, который имеет правильное значение ticks, чтобы отразить это. То есть, вызов getUTCHours()
и т. Д. В дату вернет то же значение, что и на сервере, а вызов getHours()
вернет значение в местном часовом поясе пользователя, как определено его браузером.
Это не учитывает формат WCF со смещением часового пояса, хотя это было бы относительно легко добавить.
У каждого из этих ответов есть одна общая черта: все они хранят даты как одно значение (обычно строку).
Другой вариант - воспользоваться преимуществами внутренней структуры JSON и представить дату в виде списка чисел:
{ "name":"Nick",
"birthdate":[1968,6,9] }
Конечно, вам нужно убедиться, что оба конца беседы согласуются с форматом (год, месяц, день) и полями, которые должны быть датами, но у него есть преимущество, заключающееся в том, что он полностью избегает вопроса о дате. Преобразование в строку. Это все числа - никаких строк. Кроме того, использование порядка: год, месяц, день также позволяет правильно сортировать по дате.
Просто подумайте нестандартно - дату в формате JSON не нужно хранить в виде строки.
Другим преимуществом этого является то, что вы можете легко (и эффективно) выбирать все записи за определенный год или месяц, используя способ, которым CouchDB обрабатывает запросы к значениям массива.
var obj = eval('(' + "{Date: \/Date(1278903921551)\/}".replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')');
var dateValue = obj["Date"];
Использование средства выбора даты jQuery UI - действительно имеет смысл, только если вы уже включили jQuery UI:
$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6))));
вывод:
15 октября 2008 г.
Просто чтобы добавить еще один подход, «тиковый подход», который использует WCF, подвержен проблемам с часовыми поясами, если вы не слишком осторожны, как описано здесь и в других местах. Поэтому сейчас я использую формат ISO 8601, который должным образом поддерживает и .NET, и JavaScript, включая смещения часовых поясов. Ниже приведены подробности:
В WCF / .NET:
Где CreationDate - это System.DateTime; ToString ("o") использует спецификатор формата туда и обратно .NET, который генерирует строку даты, совместимую с ISO 8601
new MyInfo {
CreationDate = r.CreationDate.ToString("o"),
};
В JavaScript
Сразу после получения JSON я исправляю даты, чтобы они были объектами JavaSript Date, используя конструктор Date, который принимает строку даты ISO 8601 ...
$.getJSON(
"MyRestService.svc/myinfo",
function (data) {
$.each(data.myinfos, function (r) {
this.CreatedOn = new Date(this.CreationDate);
});
// Now each myinfo object in the myinfos collection has a CreatedOn field that is a real JavaScript date (with timezone intact).
alert(data.myinfos[0].CreationDate.toLocaleString());
}
)
Если у вас есть дата JavaScript, вы можете использовать все удобные и надежные методы Date, такие как toDateString , toLocaleString и т. Д.
Добавьте плагин jQuery UI на свою страницу:
function DateFormate(dateConvert) {
return $.datepicker.formatDate("dd/MM/yyyy", eval('new ' + dateConvert.slice(1, -1)));
};
Ниже приведено довольно простое решение для анализа дат JSON. Используйте следующие функции согласно вашему требованию. Вам просто нужно передать формат даты JSON, выбранный в качестве параметра для функций ниже:
function JSONDate(dateStr) {
var m, day;
jsonDate = dateStr;
var d = new Date(parseInt(jsonDate.substr(6)));
m = d.getMonth() + 1;
if (m < 10)
m = '0' + m
if (d.getDate() < 10)
day = '0' + d.getDate()
else
day = d.getDate();
return (m + '/' + day + '/' + d.getFullYear())
}
function JSONDateWithTime(dateStr) {
jsonDate = dateStr;
var d = new Date(parseInt(jsonDate.substr(6)));
var m, day;
m = d.getMonth() + 1;
if (m < 10)
m = '0' + m
if (d.getDate() < 10)
day = '0' + d.getDate()
else
day = d.getDate();
var formattedDate = m + "/" + day + "/" + d.getFullYear();
var hours = (d.getHours() < 10) ? "0" + d.getHours() : d.getHours();
var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes();
var formattedTime = hours + ":" + minutes + ":" + d.getSeconds();
formattedDate = formattedDate + " " + formattedTime;
return formattedDate;
}
Дата JSON легко преобразовать в дату JavaScript:
var s = Response.StartDate;
s = s.replace('/Date(', '');
s = s.replace(')/', '');
var expDate = new Date(parseInt(s));
Нажмите здесь, чтобы проверить демо
JavaScript / JQuery
var = MyDate_String_Value = "/Date(1224043200000)/"
var value = new Date
(
parseInt(MyDate_String_Value.replace(/(^.*\()|([+-].*$)/g, ''))
);
var dat = value.getMonth() +
1 +
"/" +
value.getDate() +
"/" +
value.getFullYear();
Результат - "15.10.2008"
Вы также можете использовать библиотеку JavaScript moment.js , которая пригодится, когда вы планируете работать с различными локализованными форматами и выполнять другие операции со значениями дат:
function getMismatch(id) {
$.getJSON("Main.aspx?Callback=GetMismatch",
{ MismatchId: id },
function (result) {
$("#AuthMerchId").text(result.AuthorizationMerchantId);
$("#SttlMerchId").text(result.SettlementMerchantId);
$("#CreateDate").text(moment(result.AppendDts).format("L"));
$("#ExpireDate").text(moment(result.ExpiresDts).format("L"));
$("#LastUpdate").text(moment(result.LastUpdateDts).format("L"));
$("#LastUpdatedBy").text(result.LastUpdateNt);
$("#ProcessIn").text(result.ProcessIn);
}
);
return false;
}
Настроить локализацию так же просто, как добавить файлы конфигурации (вы можете получить их на momentjs.com) в свой проект и настроить язык:
moment.lang('de');
Мне также пришлось искать решение этой проблемы, и в конце концов я наткнулся на moment.js, отличную библиотеку, которая может анализировать этот формат даты и многое другое.
var d = moment(yourdatestring)
Это избавило меня от головной боли, поэтому я решил поделиться этим с вами. :)
Вы можете найти больше информации об этом здесь: http://momentjs.com/
Date
.