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 DateTime a DateTimeOffset data:
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
S .NET 7+ System.Text.Json podporuje serializaci a deserializaci DateOnly a TimeOnly typy. 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:
- Vytvoří
Appointmentinstanci objektuappointmenta přiřadí se k proměnné. - Instance je serializována
appointmentdo FORMÁTU 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í s rovností.
- 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). Parsování a DateTime(Posun) 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 použít . Rozsáhlá podpora analýzy různých DateTime a DateTimeOffset textových formátů, včetně řetězců jiných než ISO 8601 a formátů ISO 8601, které 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 v logice zápisu DateTime(Offset).ToString převaděče.
Tato metoda umožňuje psát DateTime a hodnoty pomocí libovolného standardního DateTimeOffset data a času a vlastních formátů 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, typeToConvert parametr bude vždy typeof(DateTime).
Tento parametr je užitečný pro zpracování polymorfních případů a při použití obecných typů k typeof(T) získání výkonnějšího způsobu.
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 Utf8Parser a Utf8Formatter typy. Formát je malými písmeny RFC 1123 (malá písmena ve formátu R). Například "thu, 25 jul 2019 06:36:07 gmt".
Použijte dateTime(posun). Parsovat jako záložní
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žití formátu kalendářního data unixové epochy
Následující převaděče zpracovávají formát unixové epochy s posunem časového pásma (hodnoty jako /Date(1590863400000-0700)//Date(1590863400000)/nebo):
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 s ToString(String, IFormatProvider) metodou a pak ji WriteStringValue(String) zapsat:
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 pomocí metody načíst DateTimeOffset vlastní GetString() textovou reprezentaci a pak 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 data a času
Rozšířený profil ISO 8601-1:2019 implementovaný v System.Text.Json definici následujících součástí 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 informací o posunu UTC |
| Úplné datum | "yyyy'-'MM'-'dd" | Datum kalendáře. |
| Plný úvazek | "'Částečný čas'K" | UTC dne nebo místního dne s časovým posunem mezi místním časem a UTC. |
| Datum a čas | "Úplné datum''T'Full time'' | 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"
"'Celé datum''T'Hour'':'Minute'"
- "yyyy'-'MM'-'dd'T'HH':'mm"
"Úplné datum''T'Částečný čas'"
- "yyyy'-'MM'-'dd'T'HH':'mm':'ss" (Specifikátor formátu sortable ("s")
- "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.' FFFFFFF"
"'Celé datum''T'Time hour'':'Minute'''Time offset''
- "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 nezadá maximální počet desetinných číslic za sekundu, ale určuje, že alespoň jedna číslice musí následovat za tečkou, pokud je přítomen zlomek-druhý oddíl. 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 znaky "T" a "Z" být "t" nebo "z", ale umožňuje aplikacím omezit podporu pouze na varianty velkého písmena. Implementace v
System.Text.Jsonnich vyžaduje, aby byly "T" a "Z". A JsonException bude vyvolána, pokud vstupní datové části při čteníDateTimeaDateTimeOffsetinstancích obsahují "t" nebo "z". - 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í JsonException aDateTimeinstancích bude vyvolána funkce ADateTimeOffset, pokud vstupní datové části obsahují mezeru ("").
Pokud jsou desetinné zlomky pro sekundy, musí existovat alespoň jedna číslice.
2019-07-26T00:00:00. není povolená.
I když je povoleno až 16 desetinných míst, parsuje se pouze prvních sedm. Cokoli, co je nad rámec toho, co 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 DateTime s implementací, která je omezená na toto řeš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 sortable ("s")
Slouží k formátování DateTime bez desetinných sekund a bez informací o posunu.
"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.' FFFFFFF"
Slouží k formátování DateTime s desetinnými sekundami, 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 posunem UTC.
"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.' FFFFFFFZ"
Slouží k formátování DateTime s desetinnými sekundami a posunem UTC.
"yyyy'-'MM'-'dd'T'HH':'mm':'ss('+'/'-')HH':'mm"
Slouží k formátování DateTime desetinných sekund nebo DateTimeOffset bez, ale s místním posunem.
"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.' FFFFFFF('+'/'-')HH':'mm"
Slouží k formátování DateTime desetinných DateTimeOffset sekund a místního posunu.
Tato úroveň členitosti odpovídá dokumentu RFC 3339.
Pokud reprezentace odezvy nebo DateTime instance obsahuje koncové nuly v desetinných sekundách, pak DateTimeOffset a JsonSerializer naformátuje reprezentaci instance bez koncových nul.
Například instance, DateTime jejíž reprezentace formátu odezvy je 2019-04-24T14:50:17.1010000Z, bude formátována jako 2019-04-24T14:50:17.101Z a JsonSerializerUtf8JsonWriter.
Pokud reprezentace odezvy nebo DateTime instance obsahuje všechny nuly v desetinných sekundách, pak DateTimeOffsetJsonSerializer naformátuje reprezentaci instance bez desetinných sekund.
Například instance, DateTime jejíž reprezentace formátu odezvy je 2019-04-24T14:50:17.0000000+02:00, bude formátována jako 2019-04-24T14:50:17+02:00 a JsonSerializerUtf8JsonWriter.
Zkrácení nul v desetinných číslicích a sekundách umožňuje nejmenší výstup potřebný k zachování informací o zaokrouhlené cestě.
Zapisují se maximálně sedm desetinných a druhých číslic. Toto maximum odpovídá implementaci DateTime , která je omezená na toto řešení.