You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Gatsby中GraphQL对土耳其语格式日期字段排序异常求助

解决Gatsby中土耳其语日期格式的排序问题

这个问题的核心原因是:GraphQL会把你的土耳其语日期字符串当作普通文本排序,而文本排序是按字符顺序逐位比较的,所以只会优先看日期的dd部分,完全忽略月份和年份的实际时间顺序。要解决这个问题,我们需要把土耳其语格式的日期转换成机器能识别的标准日期对象,再基于这个标准日期来排序。

下面提供两种可靠的实现方式:

方法一:使用date-fns库(推荐,更健壮)

date-fns支持多语言日期解析,能完美处理土耳其语的月份名称。

步骤1:安装依赖

在项目根目录运行:

npm install date-fns @date-fns/locale

步骤2:在gatsby-node.js中处理日期

修改你的gatsby-node.js文件,添加日期解析逻辑,把解析后的标准日期存入节点的fields中:

const { parse } = require('date-fns');
const { tr } = require('@date-fns/locale');

exports.onCreateNode = ({ node, actions }) => {
  const { createNodeField } = actions;

  // 只处理Markdown文章节点
  if (node.internal.type === 'MarkdownRemark') {
    const turkishDate = node.frontmatter.date;
    if (turkishDate) {
      // 解析土耳其语格式(dd MMMM yyyy)的日期
      const parsedDate = parse(turkishDate, 'dd MMMM yyyy', new Date(), {
        locale: tr,
      });

      // 验证解析是否成功,避免无效日期干扰排序
      if (!isNaN(parsedDate.getTime())) {
        createNodeField({
          node,
          name: 'sortedDate',
          value: parsedDate.toISOString(), // 存入ISO格式的日期字符串,方便GraphQL排序
        });
      } else {
        console.warn(`⚠️  无法解析日期:${turkishDate},节点ID:${node.id}`);
      }
    }
  }
};

步骤3:修改GraphQL查询

现在你可以用新生成的sortedDate字段来做降序排序了:

query AllPostsQuery {
  allMarkdownRemark(
    sort: { fields: [fields___sortedDate], order: DESC }
  ) {
    nodes {
      frontmatter {
        title
        date # 保留原土耳其语日期用于展示
      }
      fields {
        sortedDate # 用于排序的标准日期
      }
    }
  }
}

方法二:手动映射土耳其语月份(无需额外依赖)

如果你不想安装第三方库,可以手动创建土耳其语月份到数字的映射,自己解析日期:

修改gatsby-node.js

exports.onCreateNode = ({ node, actions }) => {
  const { createNodeField } = actions;

  if (node.internal.type === 'MarkdownRemark') {
    const turkishDate = node.frontmatter.date;
    if (turkishDate) {
      // 土耳其语月份到数字的映射(注意要和你Frontmatter中的月份拼写完全一致)
      const turkishMonths = {
        Ocak: 0,
        Şubat: 1,
        Mart: 2,
        Nisan: 3,
        Mayıs: 4,
        Haziran: 5,
        Temmuz: 6,
        Ağustos: 7,
        Eylül: 8,
        Ekim: 9,
        Kasım: 10,
        Aralık: 11
      };

      // 拆分日期字符串
      const [day, monthStr, year] = turkishDate.split(' ');
      const month = turkishMonths[monthStr];

      // 验证日期有效性
      if (month !== undefined && !isNaN(day) && !isNaN(year)) {
        const parsedDate = new Date(year, month, day);
        createNodeField({
          node,
          name: 'sortedDate',
          value: parsedDate.toISOString(),
        });
      } else {
        console.warn(`⚠️  日期格式无效或月份未知:${turkishDate},节点ID:${node.id}`);
      }
    }
  }
};

同样修改GraphQL查询

和方法一的查询语句完全一致,用fields___sortedDate排序即可。

注意事项

  • 确保你Frontmatter中的date字段格式严格遵循dd MMMM yyyy,月份名拼写要和土耳其语标准完全一致(比如Mayıs不要写成MayisAğustos不要写成Agustos),否则解析会失败。
  • 每次修改gatsby-node.js后,需要重启Gatsby开发服务器才能生效。

内容的提问来源于stack exchange,提问作者Kemal

火山引擎 最新活动