Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Knihovna System.Text.Json analyzuje a zapisuje DateTime a DateTimeOffset hodnoty podle rozšířeného profilu ISO 8601-1:2019.
Převaděče poskytují vlastní podporu pro serializaci a deserializaci pomocí JsonSerializer. Můžete také použít Utf8JsonReader a Utf8JsonWriter implementovat vlastní podporu.
Podpora formátu ISO 8601-1:2019
, , a typy parsovat a zapisovat JsonSerializer a Utf8JsonReader text reprezentace podle rozšířeného profilu formátu ISO 8601-1:2019, například Utf8JsonWriter.JsonElementDateTimeDateTimeOffset2019-07-26T16:59:57-05:00
DateTime a DateTimeOffset data lze serializovat pomocí JsonSerializer:
using System.Text.Json;
public class Example
{
private class Product
{
public string? Name { get; set; }
public DateTime ExpiryDate { get; set; }
}
public static void Main(string[] args)
{
Product p = new Product();
p.Name = "Banana";
p.ExpiryDate = new DateTime(2019, 7, 26);
string json = JsonSerializer.Serialize(p);
Console.WriteLine(json);
}
}
// The example displays the following output:
// {"Name":"Banana","ExpiryDate":"2019-07-26T00:00:00"}
DateTime a DateTimeOffset lze také deserializovat pomocí JsonSerializer:
using System.Text.Json;
public class Example
{
private class Product
{
public string? Name { get; set; }
public DateTime ExpiryDate { get; set; }
}
public static void Main(string[] args)
{
string json = @"{""Name"":""Banana"",""ExpiryDate"":""2019-07-26T00:00:00""}";
Product p = JsonSerializer.Deserialize<Product>(json)!;
Console.WriteLine(p.Name);
Console.WriteLine(p.ExpiryDate);
}
}
// The example displays output similar to the following:
// Banana
// 7/26/2019 12:00:00 AM
U výchozích možností musí vstupní DateTime a DateTimeOffset textové reprezentace odpovídat rozšířenému profilu ISO 8601-1:2019. Pokud se pokusíte deserializovat reprezentace, které neodpovídají profilu, JsonSerializer vyvolá JsonException chybu:
using System.Text.Json;
public class Example
{
private class Product
{
public string? Name { get; set; }
public DateTime ExpiryDate { get; set; }
}
public static void Main(string[] args)
{
string json = @"{""Name"":""Banana"",""ExpiryDate"":""26/07/2019""}";
try
{
Product _ = JsonSerializer.Deserialize<Product>(json)!;
}
catch (JsonException e)
{
Console.WriteLine(e.Message);
}
}
}
// The example displays the following output:
// The JSON value could not be converted to System.DateTime. Path: $.ExpiryDate | LineNumber: 0 | BytePositionInLine: 42.
JsonDocument poskytuje strukturovaný přístup k obsahu datové části JSON včetně DateTime a DateTimeOffset reprezentací. Následující příklad ukazuje, jak vypočítat průměrnou teplotu v pondělí z kolekce teplot:
using System.Text.Json;
public class Example
{
private static double ComputeAverageTemperatures(string json)
{
JsonDocumentOptions options = new JsonDocumentOptions
{
AllowTrailingCommas = true
};
using (JsonDocument document = JsonDocument.Parse(json, options))
{
int sumOfAllTemperatures = 0;
int count = 0;
foreach (JsonElement element in document.RootElement.EnumerateArray())
{
DateTimeOffset date = element.GetProperty("date").GetDateTimeOffset();
if (date.DayOfWeek == DayOfWeek.Monday)
{
int temp = element.GetProperty("temp").GetInt32();
sumOfAllTemperatures += temp;
count++;
}
}
double averageTemp = (double)sumOfAllTemperatures / count;
return averageTemp;
}
}
public static void Main(string[] args)
{
string json =
@"[" +
@"{" +
@"""date"": ""2013-01-07T00:00:00Z""," +
@"""temp"": 23," +
@"}," +
@"{" +
@"""date"": ""2013-01-08T00:00:00Z""," +
@"""temp"": 28," +
@"}," +
@"{" +
@"""date"": ""2013-01-14T00:00:00Z""," +
@"""temp"": 8," +
@"}," +
@"]";
Console.WriteLine(ComputeAverageTemperatures(json));
}
}
// The example displays the following output:
// 15.5
Pokud se pokusíte vypočítat průměrnou teplotu přijatou datovou částí s nekompatibilními DateTime reprezentacemi, JsonDocument vyvolá FormatException:
using System.Text.Json;
public class Example
{
private static double ComputeAverageTemperatures(string json)
{
JsonDocumentOptions options = new JsonDocumentOptions
{
AllowTrailingCommas = true
};
using (JsonDocument document = JsonDocument.Parse(json, options))
{
int sumOfAllTemperatures = 0;
int count = 0;
foreach (JsonElement element in document.RootElement.EnumerateArray())
{
DateTimeOffset date = element.GetProperty("date").GetDateTimeOffset();
if (date.DayOfWeek == DayOfWeek.Monday)
{
int temp = element.GetProperty("temp").GetInt32();
sumOfAllTemperatures += temp;
count++;
}
}
double averageTemp = (double)sumOfAllTemperatures / count;
return averageTemp;
}
}
public static void Main(string[] args)
{
// Computing the average temperatures will fail because the DateTimeOffset
// values in the payload do not conform to the extended ISO 8601-1:2019 profile.
string json =
@"[" +
@"{" +
@"""date"": ""2013/01/07 00:00:00Z""," +
@"""temp"": 23," +
@"}," +
@"{" +
@"""date"": ""2013/01/08 00:00:00Z""," +
@"""temp"": 28," +
@"}," +
@"{" +
@"""date"": ""2013/01/14 00:00:00Z""," +
@"""temp"": 8," +
@"}," +
@"]";
Console.WriteLine(ComputeAverageTemperatures(json));
}
}
// The example displays the following output:
// Unhandled exception.System.FormatException: One of the identified items was in an invalid format.
// at System.Text.Json.JsonElement.GetDateTimeOffset()
Nižší úroveň Utf8JsonWriter zapisuje data DateTime a DateTimeOffset.
using System.Text;
using System.Text.Json;
public class Example
{
public static void Main(string[] args)
{
JsonWriterOptions options = new JsonWriterOptions
{
Indented = true
};
using (MemoryStream stream = new MemoryStream())
{
using (Utf8JsonWriter writer = new Utf8JsonWriter(stream, options))
{
writer.WriteStartObject();
writer.WriteString("date", DateTimeOffset.UtcNow);
writer.WriteNumber("temp", 42);
writer.WriteEndObject();
}
string json = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json);
}
}
}
// The example output similar to the following:
// {
// "date": "2019-07-26T00:00:00+00:00",
// "temp": 42
// }
Utf8JsonReader parsuje DateTime a DateTimeOffset data:
using System.Text;
using System.Text.Json;
public class Example
{
public static void Main(string[] args)
{
byte[] utf8Data = Encoding.UTF8.GetBytes(@"""2019-07-26T00:00:00""");
Utf8JsonReader json = new Utf8JsonReader(utf8Data);
while (json.Read())
{
if (json.TokenType == JsonTokenType.String)
{
Console.WriteLine(json.TryGetDateTime(out DateTime datetime));
Console.WriteLine(datetime);
Console.WriteLine(json.GetDateTime());
}
}
}
}
// The example displays output similar to the following:
// True
// 7/26/2019 12:00:00 AM
// 7/26/2019 12:00:00 AM
Pokud se pokusíte přečíst nekompatibilní formáty s Utf8JsonReader, vyvolá chybu FormatException:
using System.Text;
using System.Text.Json;
public class Example
{
public static void Main(string[] args)
{
byte[] utf8Data = Encoding.UTF8.GetBytes(@"""2019/07/26 00:00:00""");
Utf8JsonReader json = new Utf8JsonReader(utf8Data);
while (json.Read())
{
if (json.TokenType == JsonTokenType.String)
{
Console.WriteLine(json.TryGetDateTime(out DateTime datetime));
Console.WriteLine(datetime);
DateTime _ = json.GetDateTime();
}
}
}
}
// The example displays the following output:
// False
// 1/1/0001 12:00:00 AM
// Unhandled exception. System.FormatException: The JSON value is not in a supported DateTime format.
// at System.Text.Json.Utf8JsonReader.GetDateTime()
Serializace vlastností DateOnly a TimeOnly
Počínaje rozhraním .NET 7 System.Text.Json podporuje serializaci a deserializaci typů DateOnly a TimeOnly. Představte si následující objekt:
sealed file record Appointment(
Guid Id,
string Description,
DateOnly Date,
TimeOnly StartTime,
TimeOnly EndTime);
Následující příklad serializuje Appointment objekt, zobrazí výsledný JSON a pak deserializuje zpět do nové instance Appointment typu. Nakonec se původní a nově deserializované instance porovnávají s rovností a výsledky se zapisují do konzoly:
Appointment originalAppointment = new(
Id: Guid.NewGuid(),
Description: "Take dog to veterinarian.",
Date: new DateOnly(2002, 1, 13),
StartTime: new TimeOnly(5,15),
EndTime: new TimeOnly(5, 45));
string serialized = JsonSerializer.Serialize(originalAppointment);
Console.WriteLine($"Resulting JSON: {serialized}");
Appointment deserializedAppointment =
JsonSerializer.Deserialize<Appointment>(serialized)!;
bool valuesAreTheSame = originalAppointment == deserializedAppointment;
Console.WriteLine($"""
Original record has the same values as the deserialized record: {valuesAreTheSame}
""");
V předchozím kódu:
- Je vytvořena instance objektu
Appointmenta přiřazena k proměnnéappointment. - Instance
appointmentje serializována do JSON pomocí JsonSerializer.Serialize. - Výsledný json se zapíše do konzoly.
- JSON se deserializuje zpět do nové instance
Appointmenttypu pomocí JsonSerializer.Deserialize. - Původní a nově deserializované instance se porovnávají pro zjištění, zda jsou stejné.
- Výsledek porovnání se zapíše do konzoly.
Vlastní podpora pro DateTime a DateTimeOffset
Při použití JsonSerializer
Pokud chcete, aby serializátor prováděl vlastní analýzu nebo formátování, můžete implementovat vlastní převaděče. V následujících částech najdete několik příkladů:
- DateTime(Offset).Parse a DateTime(Offset).ToString
- Utf8Parser a Utf8Formatter
- Použijte DateTime(Offset).Parse jako náhradní řešení
- Použití formátu kalendářního data unixové epochy
DateTime(Offset).Parse a DateTime(Offset).ToString
Pokud nemůžete určit formáty vstupních DateTime nebo DateTimeOffset textových reprezentací, můžete použít metodu DateTime(Offset).Parse v logice čtení převaděče.
Tato metoda umožňuje využít rozsáhlou podporu .NET pro analýzu různých textových formátů DateTime a DateTimeOffset, včetně řetězců, které nejsou ve formátu ISO 8601, a formátů ISO 8601, jež nevyhovují rozšířenému profilu ISO 8601-1:2019.
Tento přístup je méně výkonný než použití nativní implementace serializátoru.
Pro serializaci můžete použít metodu DateTime(Offset).ToString v logice zápisu převaděče.
Tato metoda umožňuje psát hodnoty DateTime a DateTimeOffset pomocí libovolného standardního formátu data a času a vlastního formátu data a času.
Tento přístup je také méně výkonný než použití nativní implementace serializátoru.
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace DateTimeConverterExamples;
public class DateTimeConverterUsingDateTimeParse : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTime));
return DateTime.Parse(reader.GetString() ?? string.Empty);
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
class Program
{
private static void ParseDateTimeWithDefaultOptions()
{
DateTime _ = JsonSerializer.Deserialize<DateTime>(@"""04-10-2008 6:30 AM""");
}
private static void FormatDateTimeWithDefaultOptions()
{
Console.WriteLine(JsonSerializer.Serialize(DateTime.Parse("04-10-2008 6:30 AM -4")));
}
private static void ProcessDateTimeWithCustomConverter()
{
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new DateTimeConverterUsingDateTimeParse());
string testDateTimeStr = "04-10-2008 6:30 AM";
string testDateTimeJson = @"""" + testDateTimeStr + @"""";
DateTime resultDateTime = JsonSerializer.Deserialize<DateTime>(testDateTimeJson, options);
Console.WriteLine(resultDateTime);
string resultDateTimeJson = JsonSerializer.Serialize(DateTime.Parse(testDateTimeStr), options);
Console.WriteLine(Regex.Unescape(resultDateTimeJson));
}
static void Main(string[] args)
{
// Parsing non-compliant format as DateTime fails by default.
try
{
ParseDateTimeWithDefaultOptions();
}
catch (JsonException e)
{
Console.WriteLine(e.Message);
}
// Formatting with default options prints according to extended ISO 8601 profile.
FormatDateTimeWithDefaultOptions();
// Using converters gives you control over the serializers parsing and formatting.
ProcessDateTimeWithCustomConverter();
}
}
// The example displays output similar to the following:
// The JSON value could not be converted to System.DateTime. Path: $ | LineNumber: 0 | BytePositionInLine: 20.
// "2008-04-10T06:30:00-04:00"
// 4/10/2008 6:30:00 AM
// "4/10/2008 6:30:00 AM"
Poznámka:
Při implementaci JsonConverter<T> a T je DateTime, parametr typeToConvert bude vždy typeof(DateTime).
Tento parametr je užitečný pro zpracování polymorfních případů a při použití generických typů k efektivnímu získání typeof(T).
Utf8Parser a Utf8Formatter
V logice převaděče můžete použít rychlé metody analýzy a formátování založené na kódování UTF-8, pokud jsou vstupní DateTime nebo DateTimeOffset textové reprezentace kompatibilní s jedním z řetězců standardního formátu data a času založených na kódování R, L nebo G nebo podle jednoho z těchto formátů. Tento přístup je mnohem rychlejší než použití DateTime(Offset).Parse a DateTime(Offset).ToString.
Následující příklad ukazuje vlastní převaděč, který serializuje a deserializuje DateTime hodnoty podle standardního formátu "R":
using System.Buffers;
using System.Buffers.Text;
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace DateTimeConverterExamples;
// This converter reads and writes DateTime values according to the "R" standard format specifier:
// https://learn.microsoft.com/dotnet/standard/base-types/standard-date-and-time-format-strings#the-rfc1123-r-r-format-specifier.
public class DateTimeConverterForCustomStandardFormatR : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTime));
if (Utf8Parser.TryParse(reader.ValueSpan, out DateTime value, out _, 'R'))
{
return value;
}
throw new FormatException();
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
// The "R" standard format will always be 29 bytes.
Span<byte> utf8Date = new byte[29];
bool result = Utf8Formatter.TryFormat(value, utf8Date, out _, new StandardFormat('R'));
Debug.Assert(result);
writer.WriteStringValue(utf8Date);
}
}
class Program
{
private static void ParseDateTimeWithDefaultOptions()
{
DateTime _ = JsonSerializer.Deserialize<DateTime>(@"""Thu, 25 Jul 2019 13:36:07 GMT""");
}
private static void ProcessDateTimeWithCustomConverter()
{
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new DateTimeConverterForCustomStandardFormatR());
string testDateTimeStr = "Thu, 25 Jul 2019 13:36:07 GMT";
string testDateTimeJson = @"""" + testDateTimeStr + @"""";
DateTime resultDateTime = JsonSerializer.Deserialize<DateTime>(testDateTimeJson, options);
Console.WriteLine(resultDateTime);
Console.WriteLine(JsonSerializer.Serialize(DateTime.Parse(testDateTimeStr), options));
}
static void Main(string[] args)
{
// Parsing non-compliant format as DateTime fails by default.
try
{
ParseDateTimeWithDefaultOptions();
}
catch (JsonException e)
{
Console.WriteLine(e.Message);
}
// Using converters gives you control over the serializers parsing and formatting.
ProcessDateTimeWithCustomConverter();
}
}
// The example displays output similar to the following:
// The JSON value could not be converted to System.DateTime.Path: $ | LineNumber: 0 | BytePositionInLine: 31.
// 7/25/2019 1:36:07 PM
// "Thu, 25 Jul 2019 09:36:07 GMT"
Poznámka:
Standardní formát "R" bude vždy dlouhý 29 znaků.
Formát "l" (malými písmeny "L") není zdokumentovaný s jinými standardními řetězci formátu data a času, protože je podporovaný pouze typy a Utf8Parser. Formát je ve formátu RFC 1123 malými písmeny, což je malá verze formátu "R". Například "thu, 25 jul 2019 06:36:07 gmt".
Použijte DateTime(Offset). parsovat jako záložní možnost
Pokud obecně očekáváte, že vaše vstupy DateTime nebo DateTimeOffset data odpovídají rozšířenému profilu ISO 8601-1:2019, můžete použít nativní logiku analýzy serializátoru. Můžete také implementovat záložní mechanismus. Následující příklad ukazuje, že po selhání parsování textové reprezentace DateTime pomocí TryGetDateTime(DateTime)převaděč úspěšně parsuje data pomocí Parse(String):
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace DateTimeConverterExamples;
public class DateTimeConverterUsingDateTimeParseAsFallback : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTime));
if (!reader.TryGetDateTime(out DateTime value))
{
value = DateTime.Parse(reader.GetString()!);
}
return value;
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("dd/MM/yyyy"));
}
}
class Program
{
private static void ParseDateTimeWithDefaultOptions()
{
DateTime _ = JsonSerializer.Deserialize<DateTime>(@"""2019-07-16 16:45:27.4937872+00:00""");
}
private static void ProcessDateTimeWithCustomConverter()
{
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new DateTimeConverterUsingDateTimeParseAsFallback());
string testDateTimeStr = "2019-07-16 16:45:27.4937872+00:00";
string testDateTimeJson = @"""" + testDateTimeStr + @"""";
DateTime resultDateTime = JsonSerializer.Deserialize<DateTime>(testDateTimeJson, options);
Console.WriteLine(resultDateTime);
string resultDateTimeJson = JsonSerializer.Serialize(DateTime.Parse(testDateTimeStr), options);
Console.WriteLine(Regex.Unescape(resultDateTimeJson));
}
static void Main(string[] args)
{
// Parsing non-compliant format as DateTime fails by default.
try
{
ParseDateTimeWithDefaultOptions();
}
catch (JsonException e)
{
Console.WriteLine(e.Message);
}
// Using converters gives you control over the serializers parsing and formatting.
ProcessDateTimeWithCustomConverter();
}
}
// The example displays output similar to the following:
// The JSON value could not be converted to System.DateTime.Path: $ | LineNumber: 0 | BytePositionInLine: 35.
// 7/16/2019 4:45:27 PM
// "16/07/2019"
Použijte Unixový epochální formát dat
Následující převaděče zpracovávají formát unixové epochy s nebo bez posunu časového pásma (hodnoty jako /Date(1590863400000-0700)/ nebo /Date(1590863400000)/):
sealed class UnixEpochDateTimeOffsetConverter : System.Text.Json.Serialization.JsonConverter<DateTimeOffset>
{
static readonly DateTimeOffset s_epoch = new(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
static readonly Regex s_regex = new(
"^/Date\\(([+-]*\\d+)([+-])(\\d{2})(\\d{2})\\)/$",
RegexOptions.CultureInvariant);
public override DateTimeOffset Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
string formatted = reader.GetString()!;
Match match = s_regex.Match(formatted);
if (
!match.Success
|| !long.TryParse(match.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime)
|| !int.TryParse(match.Groups[3].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int hours)
|| !int.TryParse(match.Groups[4].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int minutes))
{
throw new System.Text.Json.JsonException();
}
int sign = match.Groups[2].Value[0] == '+' ? 1 : -1;
TimeSpan utcOffset = new(hours * sign, minutes * sign, 0);
return s_epoch.AddMilliseconds(unixTime).ToOffset(utcOffset);
}
public override void Write(
Utf8JsonWriter writer,
DateTimeOffset value,
JsonSerializerOptions options)
{
long unixTime = value.ToUnixTimeMilliseconds();
TimeSpan utcOffset = value.Offset;
string formatted = string.Create(
CultureInfo.InvariantCulture,
$"/Date({unixTime}{(utcOffset >= TimeSpan.Zero ? "+" : "-")}{utcOffset:hhmm})/");
writer.WriteStringValue(formatted);
}
}
sealed class UnixEpochDateTimeConverter : System.Text.Json.Serialization.JsonConverter<DateTime>
{
static readonly DateTime s_epoch = new(1970, 1, 1, 0, 0, 0);
static readonly Regex s_regex = new(
"^/Date\\(([+-]*\\d+)\\)/$",
RegexOptions.CultureInvariant);
public override DateTime Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
string formatted = reader.GetString()!;
Match match = s_regex.Match(formatted);
if (
!match.Success
|| !long.TryParse(match.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime))
{
throw new System.Text.Json.JsonException();
}
return s_epoch.AddMilliseconds(unixTime);
}
public override void Write(
Utf8JsonWriter writer,
DateTime value,
JsonSerializerOptions options)
{
long unixTime = (value - s_epoch).Ticks / TimeSpan.TicksPerMillisecond;
string formatted = string.Create(CultureInfo.InvariantCulture, $"/Date({unixTime})/");
writer.WriteStringValue(formatted);
}
}
Při použití Utf8JsonWriter
Pokud chcete napsat vlastní DateTime nebo DateTimeOffset textovou reprezentaci pomocí Utf8JsonWriter, můžete vlastní reprezentaci naformátovat na String, ReadOnlySpan<Byte>ReadOnlySpan<Char>nebo JsonEncodedText, a pak ji předat odpovídající Utf8JsonWriter.WriteStringValue nebo Utf8JsonWriter.WriteString metodě.
Následující příklad ukazuje, jak lze vytvořit vlastní DateTime formát pomocí ToString(String, IFormatProvider) a poté zapsán metodou WriteStringValue(String).
using System.Globalization;
using System.Text;
using System.Text.Json;
public class Example
{
public static void Main(string[] args)
{
var options = new JsonWriterOptions
{
Indented = true
};
using (var stream = new MemoryStream())
{
using (var writer = new Utf8JsonWriter(stream, options))
{
string dateStr = DateTime.UtcNow.ToString("F", CultureInfo.InvariantCulture);
writer.WriteStartObject();
writer.WriteString("date", dateStr);
writer.WriteNumber("temp", 42);
writer.WriteEndObject();
}
string json = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json);
}
}
}
// The example displays output similar to the following:
// {
// "date": "Tuesday, 27 August 2019 19:21:44",
// "temp": 42
// }
Při použití Utf8JsonReader
Pokud chcete přečíst vlastní DateTime nebo DateTimeOffset textovou reprezentaci s Utf8JsonReader, můžete získat hodnotu aktuálního tokenu JSON jako String pomocí metody GetString(), a poté hodnotu analyzovat pomocí vlastní logiky.
Následující příklad ukazuje, jak lze načíst vlastní DateTimeOffset textovou reprezentaci pomocí metody GetString(), a pak ji analyzovat pomocí ParseExact(String, String, IFormatProvider).
using System.Globalization;
using System.Text;
using System.Text.Json;
public class Example
{
public static void Main(string[] args)
{
byte[] utf8Data = Encoding.UTF8.GetBytes(@"""Friday, 26 July 2019 00:00:00""");
var json = new Utf8JsonReader(utf8Data);
while (json.Read())
{
if (json.TokenType == JsonTokenType.String)
{
string value = json.GetString();
DateTimeOffset dto = DateTimeOffset.ParseExact(value, "F", CultureInfo.InvariantCulture);
Console.WriteLine(dto);
}
}
}
}
// The example displays output similar to the following:
// 7/26/2019 12:00:00 AM -04:00
Rozšířený profil ISO 8601-1:2019 v system.Text.Json
Komponenty času a data
Rozšířený profil ISO 8601-1:2019 implementovaný v System.Text.Json definuje následující komponenty pro vyjádření data a času. Tyto komponenty se používají k definování různých podporovaných úrovní členitosti při analýze a formátování DateTime a DateTimeOffset reprezentaci.
| Komponenta | Formát | Popis |
|---|---|---|
| Rok | "yyyyy" | 0001-9999 |
| Měsíc | "MM" | 01-12 |
| Den | "dd" | 01-28, 01-29, 01-30, 01-31 na základě měsíce/roku. |
| Hodina | "HH" | 00-23 |
| Minuta | "mm" | 00-59 |
| Sekunda | "ss" | 00-59 |
| Druhý zlomek | "FFFFFFF" | Minimálně jedna číslice, maximálně 16 číslic. |
| Časový posun | "K" | Buď "Z" nebo "('+'/'-')HH':'mm". |
| Částečný čas | "HH':'mm':'ss[FFFFFFF]" | Čas bez údajů o posunu vůči UTC |
| Úplné datum | "yyyy'-'MM'-'dd" | Datum kalendáře. |
| Plný úvazek | 'Částečný úvazek' | UTC času dne nebo místního času dne s časovým posunem mezi místním časem a UTC. |
| Datum a čas | 'Úplné datum''T''Úplný čas' | Datum a čas kalendáře, například 2019-07-26T16:59:57-05:00. |
Podpora analýzy
Pro parsování jsou definovány následující úrovně členitosti:
Úplné datum
- "yyyy'-'MM'-'dd"
'Plné datum''T''Hodina'':''Minuta'
- "yyyy'-'MM'-'dd'T'HH':'mm"
"Úplné datum''T''Částečný čas'"
- "yyyy'-'MM'-'dd'T'HH':'mm':'ss" (Specifikátor formátu třídění ("s"))
- "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'FFFFFFF"
"'Celé datum''T''Hodina'':''Minuta''Časový posun'"
- "yyyy'-'MM'-'dd'T'HH':'mmZ"
- "yyyy'-'MM'-'dd'T'HH':'mm('+'/'-')HH':'mm"
Datum a čas
- yyyy'-'MM'-'dd'T'HH':'mm':'ssZ
- "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'FFFFFFFZ"
- "yyyy'-'MM'-'dd'T'HH':'mm':'ss('+'/'-')HH':'mm"
- "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.' FFFFFFF('+'/'-')HH':'mm"
Tato úroveň členitosti je kompatibilní s DOKUMENTEM RFC 3339, široce používaným profilem ISO 8601 pro prokládání informací o datu a čase. Implementace však má několik omezení
System.Text.Json.- RFC 3339 neurčuje maximální počet desetinných číslic, ale specifikuje, že alespoň jedna číslice musí následovat za tečkou, pokud je přítomna sekce zlomkových sekund. Implementace umožňuje
System.Text.Jsonaž 16 číslic (pro podporu spolupráce s jinými programovacími jazyky a architekturami), ale parsuje pouze prvních sedm. Pokud při čtení JsonException aDateTimeinstancích existuje více než 16 desetinných sekund, bude vyvolán znak ADateTimeOffset. - RFC 3339 umožňuje znakům "T" a "Z" být zaměněny za "t" nebo "z", ale umožňuje aplikacím omezit podporu pouze na velká písmena. Implementace v
System.Text.Jsonnich vyžaduje, aby byly "T" a "Z". Dojde k vyvolání JsonException, pokud vstupní užitná data obsahují "t" nebo "z" při čtení instancíDateTimeaDateTimeOffset. - RFC 3339 určuje, že oddíly data a času jsou oddělené "T", ale umožňují aplikacím je oddělit mezerou (" ").
System.Text.Jsonvyžaduje, aby oddíly data a času byly odděleny pomocí "T". Při čtení instancí JsonException aDateTimebude vyvolána výjimkaDateTimeOffset, pokud vstupní datové části obsahují mezeru (" ").
Pokud jsou desetinné zlomky pro sekundy, musí existovat alespoň jedna číslice.
2019-07-26T00:00:00. není povoleno.
I když je povoleno až 16 desetinných míst, parsuje se pouze prvních sedm. Cokoli nad tím je považováno za nulu.
Například bude analyzováno, 2019-07-26T00:00:00.1234567890 jako by to bylo 2019-07-26T00:00:00.1234567.
Tento přístup zachovává kompatibilitu s implementací DateTime, která je omezená na toto rozlišení.
Přestupné sekundy nejsou podporovány.
Podpora formátování
Pro formátování jsou definovány následující úrovně podrobností:
"Úplné datum''T''Částečný čas'"
"yyyy'-'MM'-'dd'T'HH':'mm':'ss" (Specifikátor formátu třídění ("s"))
Slouží k formátování DateTime bez zlomkových sekund a bez informací o posunu.
"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'FFFFFFF"
Slouží k formátování DateTime se zlomkovými vteřinami, ale bez informací o posunu.
Datum a čas
yyyy'-'MM'-'dd'T'HH':'mm':'ssZ
Používá se k formátování DateTime bez desetinných sekund, ale s časovým posunem UTC.
"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'FFFFFFFZ"
Slouží k formátování DateTime se zlomkovými sekundami a posunem UTC.
"yyyy'-'MM'-'dd'T'HH':'mm':'ss('+'/'-')HH':'mm"
Používá se k formátování DateTime nebo DateTimeOffset bez zlomkových sekund, ale s místním posunem.
"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.' FFFFFFF('+'/'-')HH':'mm"
Používá se k formátování DateTime se zlomkovými sekundami a s místním posunem.
Tato úroveň členitosti odpovídá dokumentu RFC 3339.
Pokud má reprezentace instance ve formátu nebo DateTime kulatý formát, který obsahuje koncové nuly v desetinných sekundách, pak DateTimeOffset a JsonSerializer naformátují reprezentaci instance bez těchto nul.
Například instance, DateTime jejíž round-trip formát je 2019-04-24T14:50:17.1010000Z, bude formátována jako 2019-04-24T14:50:17.101ZJsonSerializerUtf8JsonWriter.
Pokud reprezentace instance ve formátu round-trip obsahuje všechny nuly v desetinných sekundách, pak DateTime a DateTimeOffset naformátují reprezentaci instance bez desetinných sekund.
Například instance, DateTime jejíž round-trip formát je 2019-04-24T14:50:17.0000000+02:00, bude formátována jako 2019-04-24T14:50:17+02:00JsonSerializerUtf8JsonWriter.
Krácení nul v číslicích desetinných míst u zlomkových sekund umožňuje vytvořit co nejmenší výstup potřebný k zachování informací při procesním cyklu.
Maximálně sedm číslic pro zlomky sekundy je zapsáno. Toto maximum odpovídá implementaci DateTime , která je omezená na toto řešení.