diff --git a/docs/types/scalars.rst b/docs/types/scalars.rst index a75c70e4..7a825d36 100644 --- a/docs/types/scalars.rst +++ b/docs/types/scalars.rst @@ -9,9 +9,10 @@ Graphene defines the following base Scalar Types: - ``graphene.Boolean`` - ``graphene.ID`` -Graphene also provides custom scalars for Dates and JSON: +Graphene also provides custom scalars for Dates, Times, and JSON: - ``graphene.types.datetime.DateTime`` +- ``graphene.types.datetime.Time`` - ``graphene.types.json.JSONString`` diff --git a/graphene/types/datetime.py b/graphene/types/datetime.py index 3dfbbb97..17987836 100644 --- a/graphene/types/datetime.py +++ b/graphene/types/datetime.py @@ -29,11 +29,37 @@ class DateTime(Scalar): ) return dt.isoformat() - @staticmethod - def parse_literal(node): + @classmethod + def parse_literal(cls, node): if isinstance(node, ast.StringValue): - return iso8601.parse_date(node.value) + return cls.parse_value(node.value) @staticmethod def parse_value(value): return iso8601.parse_date(value) + + +class Time(Scalar): + ''' + The `Time` scalar type represents a Time value as + specified by + [iso8601](https://en.wikipedia.org/wiki/ISO_8601). + ''' + epoch_date = '1970-01-01' + + @staticmethod + def serialize(time): + assert isinstance(time, datetime.time), ( + 'Received not compatible time "{}"'.format(repr(time)) + ) + return time.isoformat() + + @classmethod + def parse_literal(cls, node): + if isinstance(node, ast.StringValue): + return cls.parse_value(node.value) + + @classmethod + def parse_value(cls, value): + dt = iso8601.parse_date('{}T{}'.format(cls.epocj_time, value)) + return datetime.time(dt.hour, dt.minute, dt.second, dt.microsecond, dt.tzinfo)