Лучшим способом обработки дат в knockoutjs является использование библиотеки времени и обработки дат типа босса. Вы можете легко иметь дело с датами типа / Date (-62135578800000) /. Нет необходимости беспокоиться о том, как дата сериализации в контроллере.
function jsonToDate(date,format) {
return moment(date).format(format);
}
использовать его как
var formattedDate = jsonToDate(date,'MM/DD/YYYY')
momentjs поддерживает множество форматов времени дат и функции полезности в датах.
Moment.js - обширная библиотека datetime, которая также поддерживает это. http://momentjs.com/docs/#/parsing/asp-net-json-dates/
ex: moment ("/ Date (1198908717056-0700) /" )
Это может помочь. вывод плунжера
Смотрите эту тему:
http://forums.asp.net/p/1038457/1441866.aspx#1441866
В принципе, пока формат Date () действителен javascript, он НЕ является допустимым JSON (есть разница). Если вы хотите использовать старый формат, вам, вероятно, придется создать фасад и преобразовать значение самостоятельно или найти способ получить сериализатор для вашего типа в JsonResult и использовать его в качестве настраиваемого формата для дат.
Отформатируйте дату в запросе.
var _myModel = from _m in model.ModelSearch(word)
select new { date = ((DateTime)_m.Date).ToShortDateString() };
Единственная проблема с этим решением заключается в том, что вы не получите никаких результатов, если ANY из значений даты равно null. Чтобы обойти это, вы можете либо поставить условные операторы в свой запрос, прежде чем вы выбираете дату, которая игнорирует дату null, или вы можете настроить запрос для получения всех результатов, а затем пропустить всю эту информацию с помощью цикла foreach и присвоить значение ко всем датам, которые являются нулевыми до того, как вы сделаете свой новый SELECT.
Пример обоих:
var _test = from _t in adc.ItemSearchTest(word)
where _t.Date != null
select new { date = ((DateTime)_t.Date).ToShortDateString() };
Второй вариант требует другого запроса, чтобы вы могли присваивать значения всем нулям. Это и цикл foreach должны быть перед вашим запросом, который выбирает значения.
var _testA = from _t in adc.ItemSearchTest(word)
select _i;
foreach (var detail in _testA)
{
if (detail.Date== null)
{
detail.Date= Convert.ToDateTime("1/1/0001");
}
}
Просто идея, которую я нашел более простой, чем все примеры javascript.
Вот мое решение в Javascript - очень похоже на JPot, но короче (и, возможно, немного быстрее):
value = new Date(parseInt(value.substr(6)));
"value.substr (6)" вынимает "/ Date ( ", а функция parseInt игнорирует символы не числа, которые встречаются в конце.
EDIT: Я намеренно исключил основание (второй аргумент parseInt), см. мой комментарий ниже . Также обратите внимание, что даты ISO-8601 предпочтительнее этого старого формата, поэтому этот формат обычно не должен использоваться для новой разработки. См. отличную библиотеку Json.NET для отличная альтернатива, которая сериализует даты с использованием формата ISO-8601.
Для ISO-8601 отформатированных дат JSON просто передайте строку в конструктор Date:
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
Я обнаружил, что создание нового JsonResult
и возвращение неудовлетворительного - замена всех вызовов на return Json(obj)
на return new MyJsonResult { Data = obj }
- боль.
Итак, я понял, почему не просто захватить JsonResult
, используя ActionFilter
:
public class JsonNetFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is JsonResult == false)
{
return;
}
filterContext.Result = new JsonNetResult(
(JsonResult)filterContext.Result);
}
private class JsonNetResult : JsonResult
{
public JsonNetResult(JsonResult jsonResult)
{
this.ContentEncoding = jsonResult.ContentEncoding;
this.ContentType = jsonResult.ContentType;
this.Data = jsonResult.Data;
this.JsonRequestBehavior = jsonResult.JsonRequestBehavior;
this.MaxJsonLength = jsonResult.MaxJsonLength;
this.RecursionLimit = jsonResult.RecursionLimit;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
var isMethodGet = string.Equals(
context.HttpContext.Request.HttpMethod,
"GET",
StringComparison.OrdinalIgnoreCase);
if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet
&& isMethodGet)
{
throw new InvalidOperationException(
"GET not allowed! Change JsonRequestBehavior to AllowGet.");
}
var response = context.HttpContext.Response;
response.ContentType = string.IsNullOrEmpty(this.ContentType)
? "application/json"
: this.ContentType;
if (this.ContentEncoding != null)
{
response.ContentEncoding = this.ContentEncoding;
}
if (this.Data != null)
{
response.Write(JsonConvert.SerializeObject(this.Data));
}
}
}
}
. Это можно применить к любому методу, возвратившему JsonResult
вместо JSON.Net:
[JsonNetFilter]
public ActionResult GetJson()
{
return Json(new { hello = new Date(2015, 03, 09) }, JsonRequestBehavior.AllowGet)
}
, который будет реагировать с помощью
{"hello":"2015-03-09T00:00:00+00:00"}
по желанию!
Вы можете, если не возражать при вызове сравнения is
при каждом запросе , добавьте это в свой FilterConfig
:
// ...
filters.Add(new JsonNetFilterAttribute());
, и все ваши JSON теперь будут сериализованы с помощью JSON.Net вместо встроенного JavaScriptSerializer
.
Вы можете использовать этот метод:
String.prototype.jsonToDate = function(){
try{
var date;
eval(("date = new " + this).replace(/\//g,''));
return date;
}
catch(e){
return new Date(0);
}
};
Не самый элегантный способ, но это сработало для меня:
var ms = date.substring(6, date.length - 2);
var newDate = formatDate(ms);
function formatDate(ms) {
var date = new Date(parseInt(ms));
var hour = date.getHours();
var mins = date.getMinutes() + '';
var time = "AM";
// find time
if (hour >= 12) {
time = "PM";
}
// fix hours format
if (hour > 12) {
hour -= 12;
}
else if (hour == 0) {
hour = 12;
}
// fix minutes format
if (mins.length == 1) {
mins = "0" + mins;
}
// return formatted date time string
return date.getMonth() + 1 + "/" + date.getDate() + "/" + date.getFullYear() + " " + hour + ":" + mins + " " + time;
}
Есть довольно много ответов для обработки клиентской стороны, но вы можете изменить выходную серверную сторону, если хотите.
Есть несколько способов приблизиться к этому, я начну с основы. Вам придется подклассифицировать класс JsonResult и переопределить метод ExecuteResult. Оттуда вы можете использовать несколько разных подходов для изменения сериализации.
Подход 1: Реализация по умолчанию использует JsonScriptSerializer . Если вы посмотрите на документацию, вы можете использовать метод RegisterConverters для добавления пользовательских JavaScriptConverters . Есть несколько проблем с этим: JavaScriptConverter сериализуется в словаре, то есть он берет объект и сериализуется в Json-словаре. Чтобы сделать сериализацию объекта строкой, требуется бит хакера, см. post .
public class CustomJsonResult : JsonResult
{
private const string _dateFormat = "yyyy-MM-dd HH:mm:ss";
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
// Use your custom JavaScriptConverter subclass here.
serializer.RegisterConverters(new JavascriptConverter[] { new CustomConverter });
response.Write(serializer.Serialize(Data));
}
}
}
Подход 2 (рекомендуется): Второй подход - начать с переопределенного JsonResult и пойти с другим сериализатором Json, в моем случае Json .NET сериализатор. Это не требует взлома подхода 1. Вот моя реализация подкласса JsonResult:
public class CustomJsonResult : JsonResult
{
private const string _dateFormat = "yyyy-MM-dd HH:mm:ss";
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
// Using Json.NET serializer
var isoConvert = new IsoDateTimeConverter();
isoConvert.DateTimeFormat = _dateFormat;
response.Write(JsonConvert.SerializeObject(Data, isoConvert));
}
}
}
Пример использования:
[HttpGet]
public ActionResult Index() {
return new CustomJsonResult { Data = new { users=db.Users.ToList(); } };
}
Дополнительные кредиты: Джеймс Newton-King
У меня была та же проблема, и вместо того, чтобы вернуть фактическое значение даты, я просто использовал ToString («dd MMM yyyy»). Затем в моем javascript я использовал новую Date (datevalue), где datevalue может быть «01 января 2009».
Самый простой:
var milisegundos = parseInt (data.replace ("/ Date (", "") .replace (") /", "")); Var newDate = новая дата (milisegundos) .toLocaleDateString ("en-UE");
Он возвращает формат даты сервера. Вы должны определить свою собственную функцию.
function jsonDateFormat(jsonDate) {
// Changed data format;
return (new Date(parseInt(jsonDate.substr(6)))).format("mm-dd-yyyy / h:MM tt");
};
Связь Ajax между клиентом и сервером часто включает данные в формате JSON. В то время как JSON хорошо работает для строк, чисел и логических значений, он может создавать определенные трудности для дат из-за того, как они преобразуются в ASP.NET. Поскольку у них нет специального представления для дат, они сериализуются как простые строки. В качестве решения механизм сериализации по умолчанию ASP.NET Web Forms и MVC сериализует даты в специальной форме - / Date (ticks) / - где тики - это число миллисекунд с 1 января 1970 года.
Эта проблема может быть решена двумя способами:
клиентская сторона
Преобразование полученной строки даты в число и создание объекта даты с использованием конструктора класса даты с параметрами ticks as.
function ToJavaScriptDate(value) {
var pattern = /Date\(([^)]+)\)/;
var results = pattern.exec(value);
var dt = new Date(parseFloat(results[1]));
return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
}
серверная сторона
В предыдущем решении используется сценарий на стороне клиента для преобразования даты в объект JavaScript. Вы также можете использовать код на стороне сервера, который сериализует экземпляры .NET DateTime в выбранном вами формате. Для выполнения этой задачи вам необходимо создать свой собственный ActionResult и затем сериализовать данные так, как вы хотите.
ссылка: http://www.developer.com/net/dealing-with-json -dates-в-asp.net-mvc.html
Что для меня работало, так это создать модель представления, содержащую свойство date в виде строки. Присвоение свойства DateTime из модели домена и вызов .ToString () в свойстве date при назначении значения в viewmodel.
Результат JSON из метода действия MVC возвращает дату в формате, совместимом с представлением.
public class TransactionsViewModel
{
public string DateInitiated { get; set; }
public string DateCompleted { get; set; }
}
public class Transaction{
public DateTime? DateInitiated {get; set;}
public DateTime? DateCompleted {get; set;}
}
public JsonResult GetTransactions(){
var transactions = _transactionsRepository.All;
var model = new List<TransactionsViewModel>();
foreach (var transaction in transactions)
{
var item = new TransactionsViewModel
{
...............
DateInitiated = transaction.DateInitiated.ToString(),
DateCompleted = transaction.DateCompleted.ToString(),
};
model.Add(item);
}
return Json(model, JsonRequestBehavior.AllowGet);
}
$.parseJSON
Примечание : этот ответ предоставляет расширение jQuery, которое добавляет автоматическую поддержку формата даты ISO и .net.
blockquote>Поскольку вы используете Asp.net MVC, я подозреваю, что вы используете jQuery на стороне клиента. Я предлагаю вам прочитать этот пост в блоге , в котором есть код, как использовать
$.parseJSON
для автоматического преобразования дат для вас.Код поддерживает даты форматирования Asp.net, такие как те, которые вы упомянули как а также даты форматирования ISO. Все даты будут автоматически отформатированы для вас с помощью
$.parseJSON()
.
Я работаю над решением этой проблемы, так как ни один из вышеперечисленных ответов мне не помог. Я работаю с календарем недели jquery и нуждаюсь в моих датах, чтобы иметь информацию о часовом поясе на сервере и локально на странице. После того, как я немного поработал, я решил найти решение, которое может помочь другим.
Я использую asp.net 3.5, vs 2008, asp.net MVC 2 и календарь недели jquery,
Во-первых, я использую библиотеку, написанную Стивеном Левитаном, которая помогает справляться с датами на стороне клиента, библиотекой дат Стивена Левитана . Формат isoUtcDateTime идеально подходит для того, что мне нужно. В моем вызове jQuery AJAX я использую функцию формата, предоставляемую библиотекой с форматом isoUtcDateTime, и когда вызов ajax вызывает мой метод действия, datetime Kind установлен в локальный и отражает время сервера.
Когда я отправьте даты на мою страницу через AJAX, я отправлю их в виде текстовых строк, форматируя даты, используя «ddd, dd MMM yyyy HH»: 'mm': 'ss' GMT'zzzz. Этот формат легко конвертируется на стороне клиента, используя
var myDate = new Date(myReceivedDate);
. Вот мое полное решение минус источник Стива Левитана, который вы можете скачать:
Контроллер:
public class HomeController : Controller
{
public const string DATE_FORMAT = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'zzzz";
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
public JsonResult GetData()
{
DateTime myDate = DateTime.Now.ToLocalTime();
return new JsonResult { Data = new { myDate = myDate.ToString(DATE_FORMAT) } };
}
public JsonResult ReceiveData(DateTime myDate)
{
return new JsonResult { Data = new { myDate = myDate.ToString(DATE_FORMAT) } };
}
}
Javascript:
<script type="text/javascript">
function getData() {
$.ajax({
url: "/Home/GetData",
type: "POST",
cache: "false",
dataType: "json",
success: function(data) {
alert(data.myDate);
var newDate = cleanDate(data.myDate);
alert(newDate);
sendData(newDate);
}
});
}
function cleanDate(d) {
if (typeof d == 'string') {
return new Date(d) || Date.parse(d) || new Date(parseInt(d));
}
if (typeof d == 'number') {
return new Date(d);
}
return d;
}
function sendData(newDate) {
$.ajax({
url: "/Home/ReceiveData",
type: "POST",
cache: "false",
dataType: "json",
data:
{
myDate: newDate.format("isoUtcDateTime")
},
success: function(data) {
alert(data.myDate);
var newDate = cleanDate(data.myDate);
alert(newDate);
}
});
}
// bind myButton click event to call getData
$(document).ready(function() {
$('input#myButton').bind('click', getData);
});
</script>
Надеюсь, этот быстрый пример поможет другим в той же ситуации, в которой я был. В настоящее время он отлично работает с Microsoft JSON Serialization и сохраняет мои даты правильными часовые пояса.
Не зря, но есть и другой способ. Сначала создайте запрос LINQ. Затем создайте запрос результата Enumerated и примените для вас любой тип форматирования.
var query = from t in db.Table select new { t.DateField };
var result = from c in query.AsEnumerable() select new { c.DateField.toString("dd MMM yyy") };
Я должен сказать, что дополнительный шаг раздражает, но он работает хорошо.
добавить jquery ui плагин на вашей странице.
function JsonDateFormate(dateFormate, jsonDateTime) {
return $.datepicker.formatDate(dateFormate, eval('new ' + jsonDateTime.slice(1, -1)));
};
Вот код JavaScript, который я написал, который устанавливает значение <input type="date">
из даты, переданной из ASP.NET MVC.
var setDate = function (id, d) {
if (d !== undefined && d !== null) {
var date = new Date(parseInt(d.replace("/Date(", "").replace(")/", ""), 10));
var day = ('0' + date.getDate()).slice(-2);
var month = ('0' + (date.getMonth() + 1)).slice(-2);
var parsedDate = date.getFullYear() + "-" + (month) + "-" + (day);
$(id).val(parsedDate);
}
};
Вы вызываете эту функцию следующим образом:
setDate('#productCommissionStartDate', data.commissionStartDate);
Где CommissionStartDate - это дата JSON, переданная MVC.