PAYATHON 2026

C# MVC 3 中临近到期时更改日期文本颜色

支付阿杰

结论

不要将 DateTime.Now.AddDays(...) 与 true 比较。AddDays 返回 DateTime,不是布尔值,这样的条件无法成立。

可以直接判断当前日期距离 BillingEndDate 还有多少天,再根据到期日是否进入提醒区间设置 CSS 类。日期只需输出一次。

Razor 中的简单实现

假设所有计费周期都在到期前 7 天显示为红色:

@{
    DateTime today = DateTime.Today;
    DateTime expiryDate = Model.BillingEndDate.Date;

    bool isNearExpiry =
        expiryDate >= today &&
        expiryDate <= today.AddDays(7);

    string expiryClass = isNearExpiry ? "billing-expiring" : "billing-normal";
}

<div>
    Billing Expiry Date:
    <span class="@expiryClass">
        @Model.BillingEndDate.ToLongDateString()
    </span>
</div>

对应的 CSS:

.billing-expiring {
    color: red;
}

.billing-normal {
    color: white;
}

这里判断的是日期范围,而不是两个 DateTime 是否完全相等。到期日只要落在今天至未来 7 天内,文本就会变红。

不同计费周期使用不同提醒时间

如果 monthly、6 month 和 yearly 对应不同的提前提醒天数,可以先根据 BillingCycleID 设置阈值:

@{
    int warningDays;

    switch (Model.BillingCycleID)
    {
        case 1: // Monthly
            warningDays = 7;
            break;

        case 2: // 6 months
            warningDays = 14;
            break;

        case 3: // Yearly
            warningDays = 30;
            break;

        default:
            warningDays = 7;
            break;
    }

    DateTime today = DateTime.Today;
    DateTime expiryDate = Model.BillingEndDate.Date;

    bool isNearExpiry =
        expiryDate >= today &&
        expiryDate <= today.AddDays(warningDays);

    string expiryClass = isNearExpiry ? "billing-expiring" : "billing-normal";
}

<span class="@expiryClass">
    @Model.BillingEndDate.ToLongDateString()
</span>

warningDays 应按照实际业务规则设置。计费周期长度与提前提醒天数是两个概念,不能因为周期是 6 个月,就直接换算成 176 天来判断是否临近到期。

区分临近到期和已经过期

如果已经过期的账户也需要显示为红色,可以将日期分为三种状态:

@{
    DateTime today = DateTime.Today;
    DateTime expiryDate = Model.BillingEndDate.Date;
    int warningDays = 7;

    string expiryClass;

    if (expiryDate < today)
    {
        expiryClass = "billing-expired";
    }
    else if (expiryDate <= today.AddDays(warningDays))
    {
        expiryClass = "billing-expiring";
    }
    else
    {
        expiryClass = "billing-normal";
    }
}

<span class="@expiryClass">
    @Model.BillingEndDate.ToLongDateString()
</span>
.billing-expired {
    color: red;
    font-weight: bold;
}

.billing-expiring {
    color: red;
}

.billing-normal {
    color: white;
}

在 ViewModel 中完成判断

日期状态属于业务展示逻辑。页面变得复杂后,可以在控制器或 ViewModel 中完成计算,避免在 Razor 视图中堆放大量判断代码。

public class BillingViewModel
{
    public int BillingCycleID { get; set; }
    public DateTime BillingStartDate { get; set; }
    public DateTime BillingEndDate { get; set; }

    public bool IsBillingNearExpiry { get; set; }
    public bool IsBillingExpired { get; set; }
}

在控制器或业务层赋值:

DateTime today = DateTime.Today;
DateTime expiryDate = model.BillingEndDate.Date;
int warningDays = 7;

model.IsBillingExpired = expiryDate < today;
model.IsBillingNearExpiry =
    !model.IsBillingExpired &&
    expiryDate <= today.AddDays(warningDays);

视图只处理显示:

@{
    string expiryClass = Model.IsBillingExpired
        ? "billing-expired"
        : Model.IsBillingNearExpiry
            ? "billing-expiring"
            : "billing-normal";
}

<span class="@expiryClass">
    @Model.BillingEndDate.ToLongDateString()
</span>

根据开始日期计算结束日期

如果数据库中没有确定的 BillingEndDate,应使用 AddMonths 或 AddYears 计算结束日期,不要用固定天数模拟月份:

switch (model.BillingCycleID)
{
    case 1:
        model.BillingEndDate = model.BillingStartDate.AddMonths(1);
        break;

    case 2:
        model.BillingEndDate = model.BillingStartDate.AddMonths(6);
        break;

    case 3:
        model.BillingEndDate = model.BillingStartDate.AddYears(1);
        break;

    default:
        throw new ArgumentOutOfRangeException("BillingCycleID");
}

一个月可能有 28、29、30 或 31 天,因此 AddMonths(1) 比 AddDays(30) 更符合月度计费规则。

注意事项

  • 使用 .Date 可以忽略时、分、秒,避免因时间不同而无法识别到期日当天。
  • 不要使用 DateTime.Now.AddDays(7) == BillingEndDate。即使两边类型一致,毫秒差异也很容易让结果变成 false。
  • 如果系统涉及多个时区,需要先确定账单日期使用服务器时间、用户本地时间还是 UTC,然后再进行比较。
  • 如果只有特定账户需要显示为红色,可以将账户条件加入判断:
bool shouldHighlight =
    Model.AccountID == 2 &&
    expiryDate >= today &&
    expiryDate <= today.AddDays(warningDays);

这样,Account 2 临近到期时会显示为红色,其他账户仍使用默认颜色。

备注:内容仅供参考。