#c# #datetime #timezone
#c# #datetime #Часовой пояс
Вопрос:
Я хочу иметь что-то вроде этого:
[Kind=DateTimeKind.Utc]
public DateTime CreatedOn { get; set; }
Возможно ли таким образом декларативно задать вид? Что такое правильный синтаксис? У меня есть классы-заглушки для использования в моем веб-сервисе JSON WCF, и когда другой конец (клиент Java) получает даты — все они нравятся:
123456000-0500
Где «-0500» — это мой часовой пояс, и если я беру только левую часть, то это неправильная дата UTC (я должен вычесть 5 часов). Я бы предпочел исправить это на сервере.
Редактировать:
-
Я сохраняю все даты в базе данных (SQL Server) как UTC. Я никогда не имею дело с локальными датами, за исключением случаев, когда это необходимо отобразить.
-
У меня есть простой класс, который я передаю в качестве ответа в моем сервисе WCF — JSON. Когда я заполняю этот класс, я запрашиваю базу данных с помощью EF и присваиваю значения в этом классе.
-
На клиенте, который является телефоном Android с Java — я использую библиотеку Gson для десериализации. Gson не может десериализовать формат WCF, поэтому я уже написал свой уродливый десериализатор следующим образом:
открытый класс GsonDateDeserializer реализует JsonDeserializer { публичная десериализация даты (JsonElement json, тип typeOfT, контекст JsonDeserializationContext) вызывает исключение JsonParseException { Строка s = json.getAsString(); s = s.replace(«/Дата(«, «»); s = s.replace(«)/», «»»);
//if there us no data passed in - that means NULL if (s.equals("")) return null; //If we got timezone info with this date - cut it off if (s.length() > 5 amp;amp; (s.indexOf("-") == s.length()-5 || s.indexOf(" ") == s.length()-5)) { s = s.substring(0, s.length()-5); } Long l = Long.valueOf(s); return new Date(l); }
}
Я думал, что WCF передает «-0500» только для информации, чтобы клиент знал, в какой часовой пояс его следует преобразовать. Но нет. Оно передает левое число с добавлением 5 часов. Итак, я не хочу, чтобы сервер был «умным», а просто хочу, чтобы он передавал все даты как «-0000»
Комментарии:
1. вы хотите показать скорректированное время на сервере или на клиенте?
2. Я хочу, чтобы клиент получил 123456000-0000 — Я не хочу, чтобы WCF принимал мою дату UTC (которую я получаю из базы данных) и передавал ее как локальную
Ответ №1:
Что ж, эта дата соответствует правильному ISO 8601, поэтому другой конец должен ее принять. Если вы не можете это изменить или не хотите, вы можете сделать следующее:
private DateTime m_createdOn;
public DateTime CreatedOn
{
get { return m_createdOn; }
set { m_createdOn = value.ToUniversalTime(); }
}
РЕДАКТИРОВАТЬ: Вы имеете в виду, что дата с часовым поясом неверна? В этом случае вам, вероятно, следует разрешить вашему уровню базы данных создавать даты с правильным DateKind
.
Комментарии:
1. Смотрите мою ПРАВКУ в основном сообщении. И как мне сообщить SQL Server, что это за тип? Это просто DateTime, и я всегда сохраняю там даты UTC.
Ответ №2:
В итоге я завершил свою собственную функцию. Теперь при десериализации я учитываю часть часового пояса.
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
String s = json.getAsString().replace("/Date(", "").replace(")/", "");
//if there us no data passed in - that means NULL
if (s.equals("")) return null;
//If we got timezone info handle separately:
long offset = 0;
if (s.length() > 5 amp;amp; (s.indexOf("-") == s.length()-5 || s.indexOf(" ") == s.length()-5))
{
//get offset minutes
offset = Long.valueOf(s.substring(s.length()-4, s.length()-2))*60 Long.valueOf(s.substring(s.length()-2, s.length()));
//Apply direction
if (s.indexOf("-") == s.length()-5) offset = -offset;
//Cutoff offset
s = s.substring(0, s.length()-5);
}
return new Date(Long.valueOf(s) offset * 60 * 1000);
}