Skip to content

Commit

Permalink
Changed the runtime type for LocalDateType, LocalTimeType, and DateTy…
Browse files Browse the repository at this point in the history
…pe (#7717)
  • Loading branch information
glen-84 authored Nov 17, 2024
1 parent 9ba5997 commit f086132
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 196 deletions.
38 changes: 22 additions & 16 deletions src/HotChocolate/Core/src/Types.Scalars/LocalDateType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace HotChocolate.Types;
/// character sequences YYYY-MM-DD. The scalar follows the specification defined in
/// <a href="https://tools.ietf.org/html/rfc3339">RFC3339</a>
/// </summary>
public class LocalDateType : ScalarType<DateTime, StringValueNode>
public class LocalDateType : ScalarType<DateOnly, StringValueNode>
{
private const string _localFormat = "yyyy-MM-dd";

Expand Down Expand Up @@ -42,13 +42,14 @@ public override IValueNode ParseResult(object? resultValue)
{
null => NullValueNode.Default,
string s => new StringValueNode(s),
DateTimeOffset o => ParseValue(o.DateTime),
DateTime dt => ParseValue(dt),
DateOnly d => ParseValue(d),
DateTimeOffset o => ParseValue(DateOnly.FromDateTime(o.DateTime)),
DateTime dt => ParseValue(DateOnly.FromDateTime(dt)),
_ => throw ThrowHelper.LocalDateType_ParseValue_IsInvalid(this),
};
}

protected override DateTime ParseLiteral(StringValueNode valueSyntax)
protected override DateOnly ParseLiteral(StringValueNode valueSyntax)
{
if (TryDeserializeFromString(valueSyntax.Value, out var value))
{
Expand All @@ -58,7 +59,7 @@ protected override DateTime ParseLiteral(StringValueNode valueSyntax)
throw ThrowHelper.LocalDateType_ParseLiteral_IsInvalid(this);
}

protected override StringValueNode ParseValue(DateTime runtimeValue)
protected override StringValueNode ParseValue(DateOnly runtimeValue)
{
return new(Serialize(runtimeValue));
}
Expand All @@ -70,10 +71,13 @@ public override bool TrySerialize(object? runtimeValue, out object? resultValue)
case null:
resultValue = null;
return true;
case DateTime dt:
resultValue = Serialize(dt);
case DateOnly d:
resultValue = Serialize(d);
return true;
case DateTimeOffset o:
resultValue = Serialize(o);
return true;
case DateTimeOffset dt:
case DateTime dt:
resultValue = Serialize(dt);
return true;
default:
Expand All @@ -92,11 +96,14 @@ public override bool TryDeserialize(object? resultValue, out object? runtimeValu
case string s when TryDeserializeFromString(s, out var d):
runtimeValue = d;
return true;
case DateTimeOffset d:
runtimeValue = d.DateTime;
case DateOnly d:
runtimeValue = d;
return true;
case DateTimeOffset o:
runtimeValue = DateOnly.FromDateTime(o.DateTime);
return true;
case DateTime dt:
runtimeValue = dt;
runtimeValue = DateOnly.FromDateTime(dt);
return true;
default:
runtimeValue = null;
Expand All @@ -111,16 +118,15 @@ private static string Serialize(IFormattable value)

private static bool TryDeserializeFromString(
string? serialized,
[NotNullWhen(true)] out DateTime? value)
[NotNullWhen(true)] out DateOnly? value)
{
if (serialized is not null
&& DateTime.TryParse(
&& DateOnly.TryParse(
serialized,
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal,
out var dt))
out var date))
{
value = dt;
value = date;
return true;
}

Expand Down
30 changes: 18 additions & 12 deletions src/HotChocolate/Core/src/Types.Scalars/LocalTimeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace HotChocolate.Types;
/// The `LocalTime` scalar type is a local time string (i.e., with no associated timezone)
/// in 24-hr HH:mm:ss.
/// </summary>
public class LocalTimeType : ScalarType<DateTime, StringValueNode>
public class LocalTimeType : ScalarType<TimeOnly, StringValueNode>
{
private const string _localFormat = "HH:mm:ss";

Expand Down Expand Up @@ -41,13 +41,14 @@ public override IValueNode ParseResult(object? resultValue)
{
null => NullValueNode.Default,
string s => new StringValueNode(s),
TimeOnly t => ParseValue(t),
DateTimeOffset d => ParseValue(d),
DateTime dt => ParseValue(dt),
_ => throw ThrowHelper.LocalTimeType_ParseValue_IsInvalid(this),
};
}

protected override DateTime ParseLiteral(StringValueNode valueSyntax)
protected override TimeOnly ParseLiteral(StringValueNode valueSyntax)
{
if (TryDeserializeFromString(valueSyntax.Value, out var value))
{
Expand All @@ -57,7 +58,7 @@ protected override DateTime ParseLiteral(StringValueNode valueSyntax)
throw ThrowHelper.LocalTimeType_ParseLiteral_IsInvalid(this);
}

protected override StringValueNode ParseValue(DateTime runtimeValue)
protected override StringValueNode ParseValue(TimeOnly runtimeValue)
{
return new(Serialize(runtimeValue));
}
Expand All @@ -69,6 +70,9 @@ public override bool TrySerialize(object? runtimeValue, out object? resultValue)
case null:
resultValue = null;
return true;
case TimeOnly t:
resultValue = Serialize(t);
return true;
case DateTimeOffset dt:
resultValue = Serialize(dt);
return true;
Expand All @@ -88,14 +92,17 @@ public override bool TryDeserialize(object? resultValue, out object? runtimeValu
case null:
runtimeValue = null;
return true;
case string s when TryDeserializeFromString(s, out var d):
runtimeValue = d;
case string s when TryDeserializeFromString(s, out var t):
runtimeValue = t;
return true;
case TimeOnly t:
runtimeValue = t;
return true;
case DateTimeOffset d:
runtimeValue = d.DateTime;
runtimeValue = TimeOnly.FromDateTime(d.DateTime);
return true;
case DateTime d:
runtimeValue = d;
runtimeValue = TimeOnly.FromDateTime(d);
return true;
default:
runtimeValue = null;
Expand All @@ -110,16 +117,15 @@ private static string Serialize(IFormattable value)

private static bool TryDeserializeFromString(
string? serialized,
[NotNullWhen(true)] out DateTime? value)
[NotNullWhen(true)] out TimeOnly? value)
{
if (serialized is not null
&& DateTime.TryParse(
&& TimeOnly.TryParse(
serialized,
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal,
out var dt))
out var time))
{
value = dt;
value = time;
return true;
}

Expand Down
125 changes: 55 additions & 70 deletions src/HotChocolate/Core/src/Types/Types/Scalars/DateType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

namespace HotChocolate.Types;

public class DateType : ScalarType<DateTime, StringValueNode>
public class DateType : ScalarType<DateOnly, StringValueNode>
{
private const string _dateFormat = "yyyy-MM-dd";

/// <summary>
/// Initializes a new instance of the <see cref="DateTimeType"/> class.
/// Initializes a new instance of the <see cref="DateType"/> class.
/// </summary>
public DateType(
string name,
Expand All @@ -24,14 +24,14 @@ public DateType(
}

/// <summary>
/// Initializes a new instance of the <see cref="DateTimeType"/> class.
/// Initializes a new instance of the <see cref="DateType"/> class.
/// </summary>
[ActivatorUtilitiesConstructor]
public DateType() : this(ScalarNames.Date, TypeResources.DateType_Description)
{
}

protected override DateTime ParseLiteral(StringValueNode valueSyntax)
protected override DateOnly ParseLiteral(StringValueNode valueSyntax)
{
if (TryDeserializeFromString(valueSyntax.Value, out var value))
{
Expand All @@ -43,98 +43,83 @@ protected override DateTime ParseLiteral(StringValueNode valueSyntax)
this);
}

protected override StringValueNode ParseValue(DateTime runtimeValue) =>
protected override StringValueNode ParseValue(DateOnly runtimeValue) =>
new(Serialize(runtimeValue));

public override IValueNode ParseResult(object? resultValue)
{
if (resultValue is null)
return resultValue switch
{
return NullValueNode.Default;
}

if (resultValue is string s)
{
return new StringValueNode(s);
}

if (resultValue is DateTimeOffset o)
{
return ParseValue(o.DateTime);
}

if (resultValue is DateTime dt)
{
return ParseValue(dt);
}

throw new SerializationException(
TypeResourceHelper.Scalar_Cannot_ParseResult(Name, resultValue.GetType()),
this);
null => NullValueNode.Default,
string s => new StringValueNode(s),
DateOnly d => ParseValue(d),
DateTimeOffset o => ParseValue(DateOnly.FromDateTime(o.UtcDateTime)),
DateTime dt => ParseValue(DateOnly.FromDateTime(dt.ToUniversalTime())),
_ => throw new SerializationException(
TypeResourceHelper.Scalar_Cannot_ParseResult(Name, resultValue.GetType()), this)
};
}

public override bool TrySerialize(object? runtimeValue, out object? resultValue)
{
if (runtimeValue is null)
switch (runtimeValue)
{
resultValue = null;
return true;
}

if (runtimeValue is DateTime dt)
{
resultValue = Serialize(dt);
return true;
case null:
resultValue = null;
return true;
case DateOnly d:
resultValue = Serialize(d);
return true;
case DateTimeOffset o:
resultValue = Serialize(o.UtcDateTime);
return true;
case DateTime dt:
resultValue = Serialize(dt.ToUniversalTime());
return true;
default:
resultValue = null;
return false;
}

resultValue = null;
return false;
}

public override bool TryDeserialize(object? resultValue, out object? runtimeValue)
{
if (resultValue is null)
switch (resultValue)
{
runtimeValue = null;
return true;
case null:
runtimeValue = null;
return true;
case string s when TryDeserializeFromString(s, out var d):
runtimeValue = d;
return true;
case DateOnly d:
runtimeValue = d;
return true;
case DateTimeOffset o:
runtimeValue = DateOnly.FromDateTime(o.UtcDateTime);
return true;
case DateTime dt:
runtimeValue = DateOnly.FromDateTime(dt.ToUniversalTime());
return true;
default:
runtimeValue = null;
return false;
}

if (resultValue is string s && TryDeserializeFromString(s, out var d))
{
runtimeValue = d;
return true;
}

if (resultValue is DateTimeOffset dt)
{
runtimeValue = dt.UtcDateTime;
return true;
}

if (resultValue is DateTime)
{
runtimeValue = resultValue;
return true;
}

runtimeValue = null;
return false;
}

private static string Serialize(DateTime value) =>
value.Date.ToString(_dateFormat, CultureInfo.InvariantCulture);
private static string Serialize(IFormattable value) =>
value.ToString(_dateFormat, CultureInfo.InvariantCulture);

private static bool TryDeserializeFromString(
string? serialized,
[NotNullWhen(true)] out DateTime? value)
[NotNullWhen(true)] out DateOnly? value)
{
if (DateTime.TryParse(
if (DateOnly.TryParse(
serialized,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out var dateTime))
out var date))
{
value = dateTime.Date;
value = date;
return true;
}

Expand Down
Loading

0 comments on commit f086132

Please sign in to comment.