diff --git a/src/OneScript.StandardLibrary/Json/GlobalJsonFunctions.cs b/src/OneScript.StandardLibrary/Json/GlobalJsonFunctions.cs index fe19b479e..338da894a 100644 --- a/src/OneScript.StandardLibrary/Json/GlobalJsonFunctions.cs +++ b/src/OneScript.StandardLibrary/Json/GlobalJsonFunctions.cs @@ -251,6 +251,26 @@ public IValue ReadJSONDate(string String, JSONDateFormatEnum? format) } } + /// + /// Преобразовывает дату в строку для последующей записи в формат JSON. + /// + /// + /// + /// Дата, которую надо преобразовать в формат JSON. + /// + /// Формат записываемой даты. + /// + /// Вариант записи даты JSON. Значение по умолчанию: ЛокальнаяДата. + /// + /// + /// Значения данного типа содержат строку в формате Unicode произвольной длины. + /// + [ContextMethod("ЗаписатьДатуJSON", "WriteJSONDate")] + public string WriteJSONDate(IValue dateValue, JSONDateFormatEnum format, JSONDateWritingVariantEnum dateWritingVariant = JSONDateWritingVariantEnum.LocalDate) + { + return JSONDateWriter.Write(dateValue, format, dateWritingVariant); + } + /// /// /// Выполняет сериализацию Значение в формат JSON. Результат помещает в объект ЗаписьJSON. diff --git a/src/OneScript.StandardLibrary/Json/JSONDateWriter.cs b/src/OneScript.StandardLibrary/Json/JSONDateWriter.cs new file mode 100644 index 000000000..fec6bea55 --- /dev/null +++ b/src/OneScript.StandardLibrary/Json/JSONDateWriter.cs @@ -0,0 +1,143 @@ +/*---------------------------------------------------------- +This Source Code Form is subject to the terms of the +Mozilla Public License, v.2.0. If a copy of the MPL +was not distributed with this file, You can obtain one +at http://mozilla.org/MPL/2.0/. +----------------------------------------------------------*/ + +using System; +using System.Globalization; +using OneScript.Commons; +using OneScript.Exceptions; +using OneScript.Types; +using ScriptEngine.Machine; + +namespace OneScript.StandardLibrary.Json +{ + internal static class JSONDateWriter + { + public static string Write(IValue dateValue, JSONDateFormatEnum format, JSONDateWritingVariantEnum dateWritingVariant) + { + var date = GetDateArgument(dateValue); + date = DropSubsecond(date); + + switch (format) + { + case JSONDateFormatEnum.ISO: + return WriteISODate(date, dateWritingVariant); + + case JSONDateFormatEnum.JavaScript: + CheckUniversalDateWritingVariant(format, dateWritingVariant); + return $"new Date({UnixMilliseconds(ConvertLocalTimeToUtc(date))})"; + + case JSONDateFormatEnum.Microsoft: + CheckUniversalDateWritingVariant(format, dateWritingVariant); + return $"/Date({UnixMilliseconds(ConvertLocalTimeToUtc(date))})/"; + + default: + throw RuntimeException.InvalidNthArgumentValue(2); + } + } + + private static DateTime GetDateArgument(IValue dateValue) + { + if (dateValue?.SystemType != BasicTypes.Date) + { + throw RuntimeException.InvalidNthArgumentType(1); + } + + return dateValue.AsDate(); + } + + private static string WriteISODate(DateTime date, JSONDateWritingVariantEnum dateWritingVariant) + { + switch (dateWritingVariant) + { + case JSONDateWritingVariantEnum.LocalDate: + return FormatISODate(date); + + case JSONDateWritingVariantEnum.LocalDateWithOffset: + return FormatISODate(date) + FormatJSONDateOffset(GetLocalUtcOffset(date)); + + case JSONDateWritingVariantEnum.UniversalDate: + return FormatISODate(ConvertLocalTimeToUtc(date)) + "Z"; + + default: + throw RuntimeException.InvalidNthArgumentValue(3); + } + } + + private static string FormatISODate(DateTime date) + { + return date.ToString("yyyy-MM-dd'T'HH:mm:ss", CultureInfo.InvariantCulture); + } + + private static DateTime ConvertLocalTimeToUtc(DateTime date) + { + if (date == DateTime.MinValue) + { + return DateTime.MinValue; + } + + return TimeZoneInfo.ConvertTimeToUtc(AsUnspecified(date), TimeZoneInfo.Local); + } + + private static TimeSpan GetLocalUtcOffset(DateTime date) + { + if (date == DateTime.MinValue) + { + return TimeSpan.Zero; + } + + return TimeZoneInfo.Local.GetUtcOffset(AsUnspecified(date)); + } + + private static DateTime AsUnspecified(DateTime date) + { + return DateTime.SpecifyKind(date, DateTimeKind.Unspecified); + } + + private static DateTime DropSubsecond(DateTime date) + { + return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second); + } + + private static long UnixMilliseconds(DateTime utcDate) + { + var utc = DateTime.SpecifyKind(utcDate, DateTimeKind.Utc); + return new DateTimeOffset(utc).ToUnixTimeMilliseconds(); + } + + private static string FormatJSONDateOffset(TimeSpan offset) + { + var sign = offset < TimeSpan.Zero ? "-" : "+"; + var totalMinutes = Math.Abs((int)Math.Truncate(offset.TotalMinutes)); + var hours = totalMinutes / 60; + var minutes = totalMinutes % 60; + + return $"{sign}{hours:00}:{minutes:00}"; + } + + private static void CheckUniversalDateWritingVariant(JSONDateFormatEnum format, JSONDateWritingVariantEnum dateWritingVariant) + { + if (dateWritingVariant == JSONDateWritingVariantEnum.UniversalDate) + { + return; + } + + if (format == JSONDateFormatEnum.JavaScript) + { + throw new RuntimeException(Locale.NStr( + "ru='Невозможно сохранить локальную дату в формате JavaScript'; en='Cannot save local date in JavaScript format'")); + } + + if (format == JSONDateFormatEnum.Microsoft) + { + throw new RuntimeException(Locale.NStr( + "ru='Невозможно сохранить локальную дату в формате Microsoft'; en='Cannot save local date in Microsoft format'")); + } + + throw RuntimeException.InvalidNthArgumentValue(2); + } + } +} diff --git a/src/OneScript.StandardLibrary/Json/JSONDateWritingVariantEnum.cs b/src/OneScript.StandardLibrary/Json/JSONDateWritingVariantEnum.cs new file mode 100644 index 000000000..93d7f853c --- /dev/null +++ b/src/OneScript.StandardLibrary/Json/JSONDateWritingVariantEnum.cs @@ -0,0 +1,26 @@ +/*---------------------------------------------------------- +This Source Code Form is subject to the terms of the +Mozilla Public License, v.2.0. If a copy of the MPL +was not distributed with this file, You can obtain one +at http://mozilla.org/MPL/2.0/. +----------------------------------------------------------*/ + +using OneScript.Contexts.Enums; + +namespace OneScript.StandardLibrary.Json +{ + [EnumerationType("ВариантЗаписиДатыJSON", "JSONDateWritingVariant", + TypeUUID = "7B1B8BE8-0EA9-47BF-BAAF-8BC6A4756E8B", + ValueTypeUUID = "4DD7E419-8D53-4F4C-A3A5-8F7436A07734")] + public enum JSONDateWritingVariantEnum + { + [EnumValue("ЛокальнаяДата", "LocalDate")] + LocalDate, + + [EnumValue("ЛокальнаяДатаСоСмещением", "LocalDateWithOffset")] + LocalDateWithOffset, + + [EnumValue("УниверсальнаяДата", "UniversalDate")] + UniversalDate + } +} diff --git a/tests/json/test-json_date.os b/tests/json/test-json_date.os new file mode 100644 index 000000000..ddd005e67 --- /dev/null +++ b/tests/json/test-json_date.os @@ -0,0 +1,443 @@ +#Использовать asserts + +Перем юТест; + +Функция ПолучитьСписокТестов(Тестирование) Экспорт + + юТест = Тестирование; + + СписокТестов = Новый Массив; + СписокТестов.Добавить("Тест_ДолженЗаписатьДатуJSONВФорматеISOКакЛокальнуюДатуПоУмолчанию"); + СписокТестов.Добавить("Тест_ДолженЗаписатьДатуJSONВФорматеISOКакЯвнуюЛокальнуюДату"); + СписокТестов.Добавить("Тест_ДолженЗаписатьДатуJSONВФорматеISOКакЛокальнуюДатуСоСмещением"); + СписокТестов.Добавить("Тест_ДолженЗаписатьДатуJSONВФорматеISOКакУниверсальнуюДату"); + СписокТестов.Добавить("Тест_ДолженЗаписатьДатуJSONВФорматеJavaScriptКакУниверсальнуюДату"); + СписокТестов.Добавить("Тест_ДолженЗаписатьОбычнуюДатуJSONВФорматеJavaScriptКакУниверсальнуюДату"); + СписокТестов.Добавить("Тест_ДолженЗаписатьДатуJSONВФорматеMicrosoftКакУниверсальнуюДату"); + СписокТестов.Добавить("Тест_ДолженЗаписатьОбычнуюДатуJSONВФорматеMicrosoftКакУниверсальнуюДату"); + СписокТестов.Добавить("Тест_ДолженЗаписатьUnixEpochJSON"); + СписокТестов.Добавить("Тест_ДолженЗаписатьМинимальнуюДатуJSONКакВ1С"); + СписокТестов.Добавить("Тест_ДолженЗаписатьДатыРядомСМинимальнойJSON"); + СписокТестов.Добавить("Тест_ДолженЗаписатьМаксимальнуюДатуJSONКакВ1С"); + СписокТестов.Добавить("Тест_ДолженВызватьИсключениеЕслиДатаИмеетНеверныйТип"); + СписокТестов.Добавить("Тест_ДолженВызватьИсключениеЕслиФорматИмеетНеверныйТип"); + СписокТестов.Добавить("Тест_ДолженВызватьИсключениеЕслиВариантЗаписиИмеетНеверныйТип"); + СписокТестов.Добавить("Тест_ДолженВызватьИсключениеДляФорматаJavaScriptПоУмолчанию"); + СписокТестов.Добавить("Тест_ДолженВызватьИсключениеДляФорматаJavaScriptБезУниверсальнойДаты"); + СписокТестов.Добавить("Тест_ДолженВызватьИсключениеДляФорматаMicrosoftПоУмолчанию"); + СписокТестов.Добавить("Тест_ДолженВызватьИсключениеДляФорматаMicrosoftБезУниверсальнойДаты"); + + Возврат СписокТестов; + +КонецФункции + +Процедура Тест_ДолженЗаписатьДатуJSONВФорматеISOКакЛокальнуюДатуПоУмолчанию() Экспорт + + // Дано + ЗначениеДаты = Дата("20140510131415"); + + // Когда + Результат = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.ISO); + + // Тогда + юТест.ПроверитьРавенство("2014-05-10T13:14:15", Результат); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьДатуJSONВФорматеISOКакЯвнуюЛокальнуюДату() Экспорт + + // Дано + ЗначениеДаты = Дата("20140510131415"); + + // Когда + Результат = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("2014-05-10T13:14:15", Результат); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьДатуJSONВФорматеISOКакЛокальнуюДатуСоСмещением() Экспорт + + // Дано + ЗначениеДаты = Дата("20140510131415"); + ОжидаемыйРезультат = "2014-05-10T13:14:15" + СмещениеТекущейЗоныДляДаты(ЗначениеДаты); + + // Когда + Результат = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением); + + // Тогда + юТест.ПроверитьРавенство(ОжидаемыйРезультат, Результат); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьДатуJSONВФорматеISOКакУниверсальнуюДату() Экспорт + + // Дано + ДатаUTC = Дата("20140510091415"); + ЗначениеДаты = МестноеВремя(ДатаUTC); + + // Когда + Результат = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("2014-05-10T09:14:15Z", Результат); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьДатуJSONВФорматеJavaScriptКакУниверсальнуюДату() Экспорт + + // Дано + ЗначениеДаты = МестноеВремя(Дата("19700101000001")); + + // Когда + Результат = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.JavaScript, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("new Date(1000)", Результат); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьОбычнуюДатуJSONВФорматеJavaScriptКакУниверсальнуюДату() Экспорт + + // Дано + ЗначениеДаты = МестноеВремя(Дата("20140510091415")); + + // Когда + Результат = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.JavaScript, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("new Date(1399713255000)", Результат); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьДатуJSONВФорматеMicrosoftКакУниверсальнуюДату() Экспорт + + // Дано + ЗначениеДаты = МестноеВремя(Дата("19700101000001")); + + // Когда + Результат = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.Microsoft, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("/Date(1000)/", Результат); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьОбычнуюДатуJSONВФорматеMicrosoftКакУниверсальнуюДату() Экспорт + + // Дано + ЗначениеДаты = МестноеВремя(Дата("20140510091415")); + + // Когда + Результат = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.Microsoft, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("/Date(1399713255000)/", Результат); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьUnixEpochJSON() Экспорт + + // Дано + ЗначениеДаты = МестноеВремя(Дата("19700101000000")); + + // Когда + РезультатJavaScript = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.JavaScript, ВариантЗаписиДатыJSON.УниверсальнаяДата); + РезультатMicrosoft = ЗаписатьДатуJSON(ЗначениеДаты, ФорматДатыJSON.Microsoft, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("new Date(0)", РезультатJavaScript); + юТест.ПроверитьРавенство("/Date(0)/", РезультатMicrosoft); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьМинимальнуюДатуJSONКакВ1С() Экспорт + + // Дано + МинимальнаяДата = Дата(1, 1, 1, 0, 0, 0); + + // Когда + РезультатISOКакЛокальнаяДата = ЗаписатьДатуJSON( + МинимальнаяДата, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДата); + РезультатISOСоСмещением = ЗаписатьДатуJSON( + МинимальнаяДата, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением); + РезультатISOКакУниверсальнаяДата = ЗаписатьДатуJSON( + МинимальнаяДата, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.УниверсальнаяДата); + РезультатJavaScript = ЗаписатьДатуJSON( + МинимальнаяДата, ФорматДатыJSON.JavaScript, ВариантЗаписиДатыJSON.УниверсальнаяДата); + РезультатMicrosoft = ЗаписатьДатуJSON( + МинимальнаяДата, ФорматДатыJSON.Microsoft, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("0001-01-01T00:00:00", РезультатISOКакЛокальнаяДата); + юТест.ПроверитьРавенство("0001-01-01T00:00:00+00:00", РезультатISOСоСмещением); + юТест.ПроверитьРавенство("0001-01-01T00:00:00Z", РезультатISOКакУниверсальнаяДата); + юТест.ПроверитьРавенство("new Date(-62135596800000)", РезультатJavaScript); + юТест.ПроверитьРавенство("/Date(-62135596800000)/", РезультатMicrosoft); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьДатыРядомСМинимальнойJSON() Экспорт + + // Дано + ДатаСОднойСекундой = Дата(1, 1, 1, 0, 0, 1); + ДатаСОднимЧасом = Дата(1, 1, 1, 1, 0, 0); + ДатаСТремяЧасами = Дата(1, 1, 1, 3, 0, 0); + СмещениеОколоМинимальнойДаты = СмещениеТекущейЗоныДляДаты(Дата(1, 1, 2, 0, 0, 0)); + + // Когда + ЛокальнаяДатаСОднойСекундой = ЗаписатьДатуJSON( + ДатаСОднойСекундой, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДата); + ЛокальнаяДатаСОднимЧасом = ЗаписатьДатуJSON( + ДатаСОднимЧасом, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДата); + ЛокальнаяДатаСТремяЧасами = ЗаписатьДатуJSON( + ДатаСТремяЧасами, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДата); + ДатаСоСмещениемСОднойСекундой = ЗаписатьДатуJSON( + ДатаСОднойСекундой, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением); + ДатаСоСмещениемСОднимЧасом = ЗаписатьДатуJSON( + ДатаСОднимЧасом, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением); + ДатаСоСмещениемСТремяЧасами = ЗаписатьДатуJSON( + ДатаСТремяЧасами, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением); + УниверсальнаяДатаСОднойСекундой = ЗаписатьДатуJSON( + ДатаСОднойСекундой, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.УниверсальнаяДата); + УниверсальнаяДатаСОднимЧасом = ЗаписатьДатуJSON( + ДатаСОднимЧасом, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.УниверсальнаяДата); + УниверсальнаяДатаСТремяЧасами = ЗаписатьДатуJSON( + ДатаСТремяЧасами, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство("0001-01-01T00:00:01", ЛокальнаяДатаСОднойСекундой); + юТест.ПроверитьРавенство("0001-01-01T01:00:00", ЛокальнаяДатаСОднимЧасом); + юТест.ПроверитьРавенство("0001-01-01T03:00:00", ЛокальнаяДатаСТремяЧасами); + юТест.ПроверитьРавенство("0001-01-01T00:00:01" + СмещениеОколоМинимальнойДаты, + ДатаСоСмещениемСОднойСекундой); + юТест.ПроверитьРавенство("0001-01-01T01:00:00" + СмещениеОколоМинимальнойДаты, + ДатаСоСмещениемСОднимЧасом); + юТест.ПроверитьРавенство("0001-01-01T03:00:00" + СмещениеОколоМинимальнойДаты, + ДатаСоСмещениемСТремяЧасами); + юТест.ПроверитьРавенство(ФорматISO(УниверсальноеВремя(ДатаСОднойСекундой)) + "Z", + УниверсальнаяДатаСОднойСекундой); + юТест.ПроверитьРавенство(ФорматISO(УниверсальноеВремя(ДатаСОднимЧасом)) + "Z", + УниверсальнаяДатаСОднимЧасом); + юТест.ПроверитьРавенство(ФорматISO(УниверсальноеВремя(ДатаСТремяЧасами)) + "Z", + УниверсальнаяДатаСТремяЧасами); + +КонецПроцедуры + +Процедура Тест_ДолженЗаписатьМаксимальнуюДатуJSONКакВ1С() Экспорт + + // Дано + МаксимальнаяДата = Дата(3999, 12, 31, 23, 59, 59); + ОжидаемаяДатаUTC = УниверсальноеВремя(МаксимальнаяДата); + + // Когда + Результат = ЗаписатьДатуJSON(МаксимальнаяДата, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.УниверсальнаяДата); + + // Тогда + юТест.ПроверитьРавенство(ФорматISO(ОжидаемаяДатаUTC) + "Z", Результат); + +КонецПроцедуры + +Процедура Тест_ДолженВызватьИсключениеЕслиДатаИмеетНеверныйТип() Экспорт + + // Дано + Значения = Новый Массив; + Значения.Добавить("20140510131415"); + Значения.Добавить(1); + Значения.Добавить(Истина); + Значения.Добавить(Неопределено); + Значения.Добавить(Null); + Значения.Добавить(Новый Массив); + Значения.Добавить(Новый Структура); + + // Когда + ОписанияОшибок = Новый Массив; + Для Каждого Значение Из Значения Цикл + Попытка + ЗаписатьДатуJSON(Значение, ФорматДатыJSON.ISO); + Исключение + ОписанияОшибок.Добавить(ОписаниеОшибки()); + Продолжить; + КонецПопытки; + + ВызватьИсключение "Для первого параметра недопустимого типа должно быть вызвано исключение"; + КонецЦикла; + + // Тогда + ПроверитьОписанияОшибокСодержат(ОписанияОшибок, "Неверный тип аргумента номер 1"); + +КонецПроцедуры + +Процедура Тест_ДолженВызватьИсключениеЕслиФорматИмеетНеверныйТип() Экспорт + + // Дано + Значения = ЗначенияНеприводимыеКПеречислению(); + + // Когда + ОписанияОшибок = Новый Массив; + Для Каждого Значение Из Значения Цикл + Попытка + ЗаписатьДатуJSON(Дата("20140510131415"), Значение); + Исключение + ОписанияОшибок.Добавить(ОписаниеОшибки()); + Продолжить; + КонецПопытки; + + ВызватьИсключение "Для второго параметра недопустимого типа должно быть вызвано исключение"; + КонецЦикла; + + // Тогда + ПроверитьОписанияОшибокСодержат(ОписанияОшибок, "Неверный тип аргумента"); + +КонецПроцедуры + +Процедура Тест_ДолженВызватьИсключениеЕслиВариантЗаписиИмеетНеверныйТип() Экспорт + + // Дано + Значения = ЗначенияНеприводимыеКПеречислению(); + + // Когда + ОписанияОшибок = Новый Массив; + Для Каждого Значение Из Значения Цикл + Попытка + ЗаписатьДатуJSON(Дата("20140510131415"), ФорматДатыJSON.ISO, Значение); + Исключение + ОписанияОшибок.Добавить(ОписаниеОшибки()); + Продолжить; + КонецПопытки; + + ВызватьИсключение "Для третьего параметра недопустимого типа должно быть вызвано исключение"; + КонецЦикла; + + // Тогда + ПроверитьОписанияОшибокСодержат(ОписанияОшибок, "Неверный тип аргумента"); + +КонецПроцедуры + +Процедура Тест_ДолженВызватьИсключениеДляФорматаJavaScriptПоУмолчанию() Экспорт + + // Дано + Формат = ФорматДатыJSON.JavaScript; + + // Когда + ОписаниеОшибки = ОписаниеИсключенияЗаписиДатыJSON(Формат); + + // Тогда + юТест.ПроверитьВхождение(ОписаниеОшибки, "Невозможно сохранить локальную дату в формате JavaScript"); + +КонецПроцедуры + +Процедура Тест_ДолженВызватьИсключениеДляФорматаJavaScriptБезУниверсальнойДаты() Экспорт + + // Дано + Формат = ФорматДатыJSON.JavaScript; + Варианты = ВариантыЗаписиЛокальнойДатыJSON(); + + // Когда + ОписанияОшибок = ОписанияИсключенийЗаписиДатыJSON(Формат, Варианты); + + // Тогда + ПроверитьОписанияОшибокСодержат(ОписанияОшибок, "Невозможно сохранить локальную дату в формате JavaScript"); + +КонецПроцедуры + +Процедура Тест_ДолженВызватьИсключениеДляФорматаMicrosoftПоУмолчанию() Экспорт + + // Дано + Формат = ФорматДатыJSON.Microsoft; + + // Когда + ОписаниеОшибки = ОписаниеИсключенияЗаписиДатыJSON(Формат); + + // Тогда + юТест.ПроверитьВхождение(ОписаниеОшибки, "Невозможно сохранить локальную дату в формате Microsoft"); + +КонецПроцедуры + +Процедура Тест_ДолженВызватьИсключениеДляФорматаMicrosoftБезУниверсальнойДаты() Экспорт + + // Дано + Формат = ФорматДатыJSON.Microsoft; + Варианты = ВариантыЗаписиЛокальнойДатыJSON(); + + // Когда + ОписанияОшибок = ОписанияИсключенийЗаписиДатыJSON(Формат, Варианты); + + // Тогда + ПроверитьОписанияОшибокСодержат(ОписанияОшибок, "Невозможно сохранить локальную дату в формате Microsoft"); + +КонецПроцедуры + +Функция ФорматISO(Дата) + Если Дата = Дата(1, 1, 1, 0, 0, 0) Тогда + Возврат "0001-01-01T00:00:00"; + КонецЕсли; + + Возврат Формат(Дата, "ДФ=yyyy-MM-ddTHH:mm:ss"); +КонецФункции + +Функция СмещениеТекущейЗоныДляДаты(Дата) + СмещениеВСекундах = Дата - УниверсальноеВремя(Дата); + Знак = ?(СмещениеВСекундах < 0, "-", "+"); + ВсегоСекунд = ?(СмещениеВСекундах < 0, -СмещениеВСекундах, СмещениеВСекундах); + Часы = Цел(ВсегоСекунд / 3600); + Минуты = Цел((ВсегоСекунд - Часы * 3600) / 60); + ЧасыСтрокой = Формат(Часы, "ЧГ=0; ЧН=0"); + МинутыСтрокой = Формат(Минуты, "ЧГ=0; ЧН=0"); + + Если СтрДлина(ЧасыСтрокой) = 1 Тогда + ЧасыСтрокой = "0" + ЧасыСтрокой; + КонецЕсли; + + Если СтрДлина(МинутыСтрокой) = 1 Тогда + МинутыСтрокой = "0" + МинутыСтрокой; + КонецЕсли; + + Возврат Знак + ЧасыСтрокой + ":" + МинутыСтрокой; +КонецФункции + +Функция ЗначенияНеприводимыеКПеречислению() + Значения = Новый Массив; + Значения.Добавить(Дата("20140510131415")); + Значения.Добавить(Новый Массив); + Значения.Добавить(Новый Структура); + Возврат Значения; +КонецФункции + +Функция ВариантыЗаписиЛокальнойДатыJSON() + Варианты = Новый Массив; + Варианты.Добавить(ВариантЗаписиДатыJSON.ЛокальнаяДата); + Варианты.Добавить(ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением); + Возврат Варианты; +КонецФункции + +Функция ОписанияИсключенийЗаписиДатыJSON(Формат, Варианты) + ОписанияОшибок = Новый Массив; + Для Каждого Вариант Из Варианты Цикл + ОписанияОшибок.Добавить(ОписаниеИсключенияЗаписиДатыJSON(Формат, Вариант)); + КонецЦикла; + Возврат ОписанияОшибок; +КонецФункции + +Функция ОписаниеИсключенияЗаписиДатыJSON(Формат, Вариант = Неопределено) + Попытка + Если Вариант = Неопределено Тогда + ЗаписатьДатуJSON(Дата("20140510131415"), Формат); + Иначе + ЗаписатьДатуJSON(Дата("20140510131415"), Формат, Вариант); + КонецЕсли; + Исключение + Возврат ОписаниеОшибки(); + КонецПопытки; + + ВызватьИсключение "Для указанного формата и варианта записи даты должно быть вызвано исключение"; +КонецФункции + +Процедура ПроверитьОписанияОшибокСодержат(ОписанияОшибок, ТекстОшибки) + + Для Каждого ОписаниеОшибки Из ОписанияОшибок Цикл + юТест.ПроверитьВхождение(ОписаниеОшибки, ТекстОшибки); + КонецЦикла; + +КонецПроцедуры