Computer Programming
Wednesday, July 12, 2023
服务之间传递时间戳时的注意事项
踩坑总结
青山

我在编写这个博客平台的翻页功能时,遇到了一个问题。每当我点击下一页后,本该出现在下一页的第一个元素总是不显示。为此我确认了SQL语句,但是SQL语句并没有任何问题,边界,参数我都确认过了,没有发现什么。但是因为每次都是第一个元素出问题,而且总在使用 PageToken 的情况下出问题,我再次查看起了边界条件。

我盯着作为边界条件的“创建时间”看了许久,这好像位数不太一样啊?我刚才只看了时间有没有值,没注意到这个精度是不同的。我在打开 Rider 中的数据库工具看这时间那一列的值的时候,发现在小数点后还有很多位 "2023-07-14 13:26:40.123456",精确到了微秒,我在 PostgreSQL的文档中也确认了这一事实。但转头看一眼我在 PageToken 里存的时间戳,仅仅精确到秒!

相当于是把 发生在 59.5秒的事,记成了59秒。这在倒序排列时就会出现问题,错误的把59秒当成起点元素,直接就错过了真正发生在 59.5 秒的数据。

为此我找到了两种解决方案。第一种是将 .NET 中的 DateTime 转换成数字后,再返回给请求方。

// 将 DateTime 转化为 Ticks
DateTime dateTime = DateTime.UtcNow;
long ticks = dateTime.Ticks;

// 将 Ticks 转化回 DateTime
DateTime dateTimeFromTicks = new DateTime(ticks);
to_ticks.cs

第二种是生成精度更高的时间戳。

next.CreatedAt.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss.fffffff")
to_timestamp.cs

两种方式都可以解决问题,不过在使用时间戳的情况下,可以更方便检查其中的值。