You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中如何计算订阅取消时间与下次计费时间的差值?

解决方案

要通过nextBillingTime和paypalSubscriptionCancelledAt计算出指定格式的subscriptionPeriodDuration,可按以下步骤实现:

核心逻辑

  1. 将两个ISO日期字符串转换为Date对象
  2. 计算时间差(毫秒级)
  3. 将毫秒差换算为天、小时、分钟、秒
  4. 格式化为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:35:59