在商业数据库系统内, 我们经常会计算各种特殊的日期以满足商业要求. 比如说, 某份人寿保险将在11月最后的一个周五到期, 在那天我们开
始计算所有的到期利息. 在计算这个到期利息时, 我们先要得到这11月最后的一个周五日期. 通常的做法是, 程序会先用一个标准日期, 比如
说12月1日, 然后再往后计算得到第一个周五. 但是这种方法往往可能要用if-else语句, 所以并不是优化的方法.
在这篇文章, 我们的问题是输入任意两个日期A和B, 要求出最靠近B天的A天的日期. 比如说, 我们想知道最靠近2012-10-19周四的日期.
上面所说的通常方法是, 先得到2012-10-19是周五,然后检查前面的周五和下一个周五哪一个更加靠近10月19. 这种方法我们通常会用到if-
else语言句.
现在大多数数据库系统都提供一些基本的日期计算函数, 比如说日期加减, 两个日期的差距天数. 但他们都没提直接的函数得到那些特定的日
期. 在这里, 我们用oracle数据库作为辅助工具来阐述我们的算法.
配置:
通常, 我们方法是把输入的日期变成1-7的数, 然后用取模函数计算到前一个周四和后一个周四的天数. oracle数据库用1-7代表周日到周一.
所以主要为表达程序的思想, 并且使程序简单明了, 我们就采用oracle的日期方式用6来代表周五.
1). minus_day := mod((inputDate - days - 7), 7);
2). add_day := mod((inputDate - days + 7), 7);
上面的inputDate和days分别是1到7的数字分别代表要求日期A和输入日期B, 7代表1周的天数. 然后我们用取模函数来计算要加多少天
(add_days)到下个要求日期和减多少天(minus_day)到前一个要求日期. minus_days可能负数, 因为他代表要减去天数.add_day 则代表要加上
天数.
然后我们用公式 3) 来计算离最近要求日期的天数 (diff_day)
3). diff_day := (1- floor(abs(add_day)/3.5)) * add_day + (1-floor(abs(minus_day)/3.5)) * minus_day;
接下来我们只需要加上diff_date和输入日期就能得到结果.
这个公式在某些特定的情况下可以扩展到去求成其他日期. 比如说, 求一个月内第二个周一的日期, 同时也能运用到其他编程语言如C/C++, Java等.