The best way is to use a specific DateTime type and create it so that you control the serialization and parsing. The type would be something like this:
TSchemaDateTimeType = class(TSchemaScalarType)
strict protected
function ParseLiteral(Value: TASTValue): TValue; override;
public
constructor Create; reintroduce;
public
function ParseValue(const Value: TValue): TValue; override;
function Serialize(const Value: TValue): TValue; override;
end;
{ TSchemaDateTimeype }
constructor TSchemaDateTimeType.Create;
begin
inherited Create('DateTime');
end;
function TSchemaDateTimeType.ParseLiteral(Value: TASTValue): TValue;
var
DateValue: TDateTime;
begin
if Value is TASTStringValue then
begin
if not TBclUtils.TryISOToDateTime(TASTSTringValue(Value).Value, DateValue) then
raise EGraphQLCoercingParseLiteral.Create(Self.DisplayName, Value);
Result := TValue.From<TDateTime>(DateValue);
end
else
raise EGraphQLCoercingParseLiteral.Create(Self.DisplayName, Value);
end;
function TSchemaDateTimeType.ParseValue(const Value: TValue): TValue;
begin
if (Value.TypeInfo = System.TypeInfo(TDateTime)) or
(Value.TypeInfo = System.TypeInfo(TDate)) or
(Value.TypeInfo = System.TypeInfo(TTime)) then
Result := Value
else
raise EGraphQLCoercingParseValue.Create(Self.DisplayName, Value);
end;
function TSchemaDateTimeType.Serialize(const Value: TValue): TValue;
begin
if Value.IsEmpty then
Exit(TValue.Empty);
if not Value.TryCast(TypeInfo(TDateTime), Result) then
raise EGraphQLCoercingSerialize.Create(Self.DisplayName, Value);
Result := TBclUtils.DateTimeToISO(Value.AsType<TDateTime>, True);
end;
Then you can register it for all GraphQL schema:
TSchemaDocument.OnGlobalCreate :=
procedure RegisterGlobalTypes(Schema: TSchemaDocument);
begin
Schema.Add(TSchemaDateTimeType.Create);
end;
Your schema then can be something like this:
type Person {
date_created: DateTime
}
Note that the OnGlobalCreate event was introduced in version 1.3.