DE7,传输日期与时间,是报文进入网络的那一刻,不是交易发生的那一刻。 规范要求它用协调世界时。Mastercard 的文档写的是 UTC,Visa 写的是 GMT,就这个用途来说是同一个瞬间。
所以 DE7 是报文里唯一一个你可以跨收单机构、跨国家、跨一整天流量去比较的域, 而且不需要知道终端在哪。如果你需要给事件排一个统一的顺序,就用这个域做键。
关于它有两件事容易踩。它不带年份 —— 格式是 MMDDhhmmss 十位数 ——
所以跨过 1 月 1 日的报文单看它是有歧义的,年份得从上下文取。以及它会被拿去和网络自己的时钟核:
DE7 偏离接收系统的时间太多会被拒收,而不是被接受后纠正 ——
这就是为什么一个时钟漂移的端点会开始失败,而现象看起来像路由问题。
DE12,本地交易时间,是交易在受理点发生时的时间。DE13,本地交易日期,是对应的日期。 两者都是受理方的墙上时钟。
这个域只带读数,别的什么都没有。没有偏移量、没有时区标识、也没有说当时是否在执行夏令时。
一个 143000 的 DE12 意思是「某地的下午两点半」,而报文不告诉你是哪里。
由此有一个硬结论:只靠报文你无法把 DE12 换成 UTC。要换,你得知道终端的时区, 而这个信息必须来自别处 —— 你自己的终端台账、收单方的台账,或者拿商户所在国家当粗略近似。 并且你不能拿两个不同收单机构的 DE12 相互比较来给交易排序,因为这两个读数不在同一个时钟上。
很容易把 DE12 说成「不带时区的时间」,而这个说法会把人带偏。DE12 是有时区的 —— 受理方的时区。交易确实发生在一个确定的地点的一个确定的瞬间。 缺的不是时区,而是报文内部没有任何一处说明它。
这个区分要紧,因为它决定了你面对的是哪种问题。一个真正没有时区的值,在原理上就无法定位。 DE12 在原理上可以定位、只是实践中没被定位:信息是存在的,只不过存在你的终端台账里而不是报文里。 任何把 DE12 变成绝对时刻的动作,都是拿它去关联你手上的数据,而不是对这个域做一次计算。
同样的道理适用于你有时会看到的那种答案 —— 说 Mastercard「要求 DE12 用 UTC」。 那条要求是关于 DE7 的。把两者混在一起会产出偏了终端时区那么多的时间戳, 在对账里表现为一小批「看起来在被发起之前就已经授权」的交易。
DE12 并不是到处都一个形状:
| 在哪里 | DE12 | DE13 |
|---|---|---|
ISO 8583:1987 —— 授权,0100 这一类 | hhmmss,六位,只有时间 | MMDD,本地日期 |
1993 版起 —— 清算,1240 这一类 | YYMMDDhhmmss,十二位,日期和时间 | 被重新定义,不再是本地日期 |
两种形式都仍然是本地时间。变的是宽度、以及日期是否跟着一起走,时钟没变。 按其中一个版本配好的解析器去读另一个版本,会解出一个看起来合理的错答案而不是报错 —— 这是它咬人的常见方式。哪些域在两个报文族之间搬家,在 授权与清算的差异里。
因为 DE7 和 DE12 在不同的时钟上,一笔临近零点的交易可以合法地在同一条报文里带两个不同的日期。 一笔发生在 UTC+8 区本地 23:40 的消费,本地日期是这一天,传输日期是前一天。两个域都没错。
你的报表该用哪一个,取决于这张报表是干什么的;而不做决定就随手取一个,正是对账崩掉的地方。 一份给商户看的对账单说某笔消费发生在商户当天没开门的日子,通常是本该用 DE12 的地方用了 DE7。 一份当日流量统计和网络那边对不上,通常是反过来。
而同一条报文里的时钟比这两个还多。DE15,结算日期,既不是本地也不是传输时刻 —— 它是卡组织将要为这笔款项结算的那一天,由卡组织自己的周期决定,可能在好几天之后。 DE16 兑换日期和 DE17 捕获日期,各自由执行那一步的人设定。 一条报文里五个日期时间域、四个不同的归属方:终端、网络、卡组织,以及捕获系统。 把其中任意两个当成可互换的,就是一整类「差一天」缺陷的根源。