GraphQL Schema日期类型定义及时间戳转日期方法咨询
嘿,针对你这两个GraphQL的问题,我来给你详细解答:
1. 如何在GraphQL Schema中定义Date数据类型?
GraphQL 本身并没有内置的 Date 标量类型,所以我们需要自定义标量来实现这个功能。具体分为两步:
第一步:在Schema中声明自定义标量
首先在你的GraphQL Schema文件里,先声明这个标量:
scalar Date
第二步:实现标量的处理逻辑
接下来要根据你使用的GraphQL框架(比如Apollo Server、GraphQL.js)来实现这个标量的序列化、解析值和解析字面量方法。以最基础的GraphQL.js为例,代码示例如下:
const { GraphQLScalarType, Kind } = require('graphql'); const DateScalar = new GraphQLScalarType({ name: 'Date', description: '自定义日期标量类型,支持JS Date对象与字符串/时间戳的转换', // 序列化:把服务端的JS Date对象转换成客户端能接收的格式 serialize(value) { // 这里可以根据需求返回ISO字符串、时间戳或者自定义格式,比如: return value.toISOString(); // 如果要返回时间戳,就写:return value.getTime(); }, // 解析值:把客户端传来的值转换成服务端能用的JS Date对象 parseValue(value) { return new Date(value); }, // 解析字面量:解析查询语句中的字面量(比如字符串) parseLiteral(ast) { if (ast.kind === Kind.STRING) { return new Date(ast.value); } return null; }, });
完成后,你就可以在Schema里像使用内置标量一样使用Date了,比如:
type Event { id: ID! eventName: String! startTime: Date! }
2. 如何将外部API返回的Unix时间戳转换为指定日期格式?
你提到的LASTUPDATE: 1579443364是秒级Unix时间戳,要转换成Mon Jan 19 2020 00:44:04这种格式,有两种实用方式:
方式一:在Resolver中直接处理转换
如果只是个别字段需要这种转换,直接在Resolver里处理最方便,不需要额外定义标量。
首先定义Schema:
type ExternalData { lastUpdate: String! } type Query { fetchExternalData: ExternalData! }
然后在Resolver里完成转换:
const resolvers = { Query: { fetchExternalData: async () => { // 调用外部API获取数据 const externalRes = await fetch('你的外部API地址'); const data = await externalRes.json(); // 把秒级时间戳转成毫秒级(JS Date需要毫秒),再生成目标格式 const timestamp = data.LASTUPDATE * 1000; const date = new Date(timestamp); // toString()方法直接返回类似"Mon Jan 19 2020 00:44:04 GMT+0800"的格式,去掉时区部分就符合需求 const formattedDate = date.toString().split(' GMT')[0]; return { lastUpdate: formattedDate }; } } };
方式二:自定义专用标量统一处理
如果多个字段都需要这种转换,自定义一个专用标量会更高效,避免重复代码。
首先在Schema里声明标量:
scalar FormattedDateTime
然后实现这个标量的逻辑:
const { GraphQLScalarType, Kind } = require('graphql'); const FormattedDateTimeScalar = new GraphQLScalarType({ name: 'FormattedDateTime', description: '将秒级Unix时间戳转换为Mon Jan DD YYYY HH:mm:ss格式的标量', // 序列化:把服务端的时间戳转成目标格式 serialize(value) { const date = new Date(value * 1000); return date.toString().split(' GMT')[0]; }, // 解析值:如果客户端要传这个类型的值,转成秒级时间戳 parseValue(value) { const date = new Date(value); return Math.floor(date.getTime() / 1000); }, // 解析字面量:处理查询中的字符串或数字字面量 parseLiteral(ast) { if (ast.kind === Kind.STRING) { const date = new Date(ast.value); return Math.floor(date.getTime() / 1000); } if (ast.kind === Kind.INT) { return parseInt(ast.value, 10); } return null; } });
之后在Schema里使用这个标量:
type ExternalData { lastUpdate: FormattedDateTime! }
Resolver里就可以直接返回原始时间戳,标量会自动帮你转换成目标格式:
const resolvers = { Query: { fetchExternalData: async () => { const externalRes = await fetch('你的外部API地址'); const data = await externalRes.json(); // 直接返回秒级时间戳即可 return { lastUpdate: data.LASTUPDATE }; } } };
内容的提问来源于stack exchange,提问作者Pep
相关产品推荐
相关产品推荐

