Node.js中如何计算订阅取消时间与下次计费时间的差值?
解决方案
要通过nextBillingTime和paypalSubscriptionCancelledAt计算出指定格式的subscriptionPeriodDuration,可按以下步骤实现:
核心逻辑
- 将两个ISO日期字符串转换为
Date对象 - 计算时间差(毫秒级)
- 将毫秒差换算为天、小时、分钟、秒
- 格式化为
X days, X hours, X minutes, X seconds的字符串
工具函数实现
先编写日期差计算的工具函数:
function calculateSubscriptionDuration(cancelTime, nextBillingTime) { const cancelDate = new Date(cancelTime); const billingDate = new Date(nextBillingTime); const diffMs = billingDate.getTime() - cancelDate.getTime(); // 换算各时间单位 const days = Math.floor(diffMs / (1000 * 60 * 60 * 24)); const remainingMsAfterDays = diffMs % (1000 * 60 * 60 * 24); const hours = Math.floor(remainingMsAfterDays / (1000 * 60 * 60)); const remainingMsAfterHours = remainingMsAfterDays % (1000 * 60 * 60); const minutes = Math.floor(remainingMsAfterHours / (1000 * 60)); const seconds = Math.floor((remainingMsAfterHours % (1000 * 60)) / 1000); return `${days} days, ${hours} hours, ${minutes} minutes, ${seconds} seconds`; }
整合到现有代码中
将工具函数加入路由处理逻辑,并在更新用户数据时调用:
paypalRouter.post("/cancel-subscription/webhook", async (req, res) => { try { const webhookEvent = req.body; if (verifyResponse.data.verification_status === "SUCCESS") { if (webhookEvent.event_type === "BILLING.SUBSCRIPTION.CANCELLED") { const userId = webhookEvent.resource.custom_id; const subscriptionId = webhookEvent.resource.id; const nextBillingTime = webhookEvent.resource.billing_info.next_billing_time; const paypalSubscriptionCancelledAt = webhookEvent.resource.status_update_time; // 计算订阅剩余时长 const subscriptionPeriodDuration = calculateSubscriptionDuration(paypalSubscriptionCancelledAt, nextBillingTime); try { const updatedUserCancelSubscription = await User.findOneAndUpdate( { _id: userId, subscriptionId: subscriptionId }, { $set: { suscriptionStatusCancelled: true, subscriptionStatusPending: false, subscriptionStatusConfirmed: false, nextBillingTime: nextBillingTime, isPremium: true, paypalSubscriptionCancelledAt: paypalSubscriptionCancelledAt, subscriptionPeriodDuration: subscriptionPeriodDuration }, }, { new: true } ); // ... (other code) } catch (error) { // ... (error handling) } } } else { // ... (other code) } } catch (error) { // ... (error handling) } }); // 日期差计算工具函数 function calculateSubscriptionDuration(cancelTime, nextBillingTime) { const cancelDate = new Date(cancelTime); const billingDate = new Date(nextBillingTime); const diffMs = billingDate.getTime() - cancelDate.getTime(); const days = Math.floor(diffMs / (1000 * 60 * 60 * 24)); const remainingMsAfterDays = diffMs % (1000 * 60 * 60 * 24); const hours = Math.floor(remainingMsAfterDays / (1000 * 60 * 60)); const remainingMsAfterHours = remainingMsAfterDays % (1000 * 60 * 60); const minutes = Math.floor(remainingMsAfterHours / (1000 * 60)); const seconds = Math.floor((remainingMsAfterHours % (1000 * 60)) / 1000); return `${days} days, ${hours} hours, ${minutes} minutes, ${seconds} seconds`; }
注意事项
- 确保传入的日期字符串是标准ISO格式,
Date对象可正确解析 - 计算时注意顺序:用
nextBillingTime减去paypalSubscriptionCancelledAt得到剩余时长 - 若需处理时区差异,可根据业务场景调整日期解析逻辑
内容的提问来源于stack exchange,提问作者pomoworko.com
相关产品推荐
相关产品推荐

