SoftLayer API 返回时间与实际计费周期如何对应?
明确结论
账单周期应以 billingItem.cycleStartDate 和相邻账单的实际周期边界为准,不能只按自然月零点推算。
示例中的 invoice.createDate 与 billingItem.cycleStartDate 完全一致:
2016-05-01T00:36:56-05:00
这通常说明 recurring invoice 生成时,该 billing item 进入了新的计费周期。上一周期在这个时间点结束,下一周期也从这里开始。
因此,实际周期边界更可能是:
上一周期结束:2016-05-01T00:36:56-05:00
下一周期开始:2016-05-01T00:36:56-05:00
不能假定账单只统计到 2016-04-30T23:59:59。也不能因为 latestBillDate 是 2016-05-01T00:00:00-05:00,就认定实际计费边界一定在午夜。
不过,hourly usage 通常按计费小时或平台规定的计量单位结算,并非严格按前一秒和下一秒切分。时间戳表示周期边界,不代表费用一定按秒计算。
三个时间字段分别表示什么
latestBillDate
"latestBillDate": "2016-05-01T00:00:00-05:00"
它表示账户最近一次出账对应的 billing date,更接近账务日期或账单周年日,不一定是后台完成账单生成的准确时间。
invoice.createDate
"createDate": "2016-05-01T00:36:56-05:00"
这是 invoice 记录实际创建的时间。账单任务可能需要排队和处理,因此该时间比 billing date 晚几十分钟并不反常。
billingItem.cycleStartDate
"cycleStartDate": "2016-05-01T00:36:56-05:00"
这是该 billing item 当前计费周期的开始时间。它与 invoice 的 createDate 相同,说明这次开票也触发了该项目的周期滚动。
这几个字段各有用途,不能互相替代:
latestBillDate表示账务日期。invoice.createDate表示 invoice 对象的创建时间。billingItem.cycleStartDate表示具体计费项目的周期起点。
如何确认某笔费用属于哪个周期
不能只看账户级字段,还要检查 invoice item 和 billing item。可以按下面的顺序核对:
- 获取当前 recurring invoice 的
createDate。 - 获取对应 billing item 的
cycleStartDate。 - 获取上一张 recurring invoice 的创建时间。
- 查看 invoice item 中的 usage、小时数、费用和描述字段。
- 对照设备的启用、取消或暂停时间。
可以通过 object mask 一次获取这些字段:
GET https://api.softlayer.com/rest/v3/SoftLayer_Account/getLatestRecurringInvoice.json?objectMask=mask[
id,
createDate,
closedDate,
invoiceTopLevelItems[
id,
description,
hourlyRecurringFee,
recurringFee,
usageCharge,
billingItem[
id,
createDate,
cancellationDate,
cycleStartDate,
currentHourlyCharge
]
]
]
可用字段会受到对象类型和 API 返回权限的影响。如果某个字段没有返回,应继续查询相应的 SoftLayer_Billing_Invoice、SoftLayer_Billing_Invoice_Item 或 SoftLayer_Billing_Item 对象,不能因此认定该字段的值为零。
核对相邻账单时,可以把周期写成半开区间:
[previousCycleStartDate, currentCycleStartDate)
[currentCycleStartDate, nextCycleStartDate)
这样可以避免同一个时间点被两个周期重复计算。SoftLayer 内部如何处理小时边界、部分小时和月度上限,仍要以对应产品当时的计费规则和 invoice item 明细为准。
为什么不能按自然月直接计算
账户在每月 1 日出账,不代表所有费用都严格按以下区间计算:
2016-05-01T00:00:00
到
2016-05-31T23:59:59
账单日期、账单任务的运行时间和具体 billing item 的周期起点可能并不一致。以下情况也可能改变单个项目的计费区间:
- 资源在周期中途开通或取消;
- hourly item 转换为其他计费方式;
- 账单处理延迟;
- 补收、抵扣或调整项目;
- 不同产品采用不同的小时取整规则;
- API 时间戳使用不同 UTC offset。
示例中同时出现了 -06:00 和 -05:00:
2016-03-10T16:18:23-06:00
2016-05-01T00:36:56-05:00
这可能与夏令时切换有关。比较时间时,应解析 ISO 8601 offset,最好统一转换成 UTC,不能忽略时间戳末尾的时区偏移。
例如:
2016-05-01T00:36:56-05:00
=
2016-05-01T05:36:56Z
注意事项
invoice.createDate 与 billingItem.cycleStartDate 相同,可以用来判断周期是否在开票时滚动,但无法仅凭这一点确定每笔 hourly usage 的内部取整方式。准确金额仍要根据 invoice item 中记录的小时数、usage charge、调整项及对应产品的计费规则计算。
如果相邻 invoice 的周期时间无法连续对应,或根据 usage 明细算出的金额与账单不一致,应向 IBM Cloud Billing 支持提交以下信息:
- Account ID;
- Invoice ID;
- Billing Item ID;
- 相关资源 ID;
- 相邻两张 invoice 的
createDate; - Billing item 的
cycleStartDate; - Invoice item 的费用及 usage 明细。
如果涉及真实扣费争议,支持团队可以查看 API 未公开的内部计量和账务记录。只根据账户级 API 时间戳,无法可靠复算全部小时费用。
备注:内容仅供参考。
