日期 2017-08-08 形式在公文中或者一些报告书中需要显示成 二〇一七年八月八日这种形式。以前潜意识一直认为这是个比较复杂的算法,今天细看了一个例子实现这个功能的算法,不得不佩服写这个算法的人确实厉害。下面就把这个算法贴出来,并且分析一下思路。例子是用 lotus 中的脚本 lotusscript 写的。分析思路以后,再用 JavaScript实现一个。
Function dateToChinese(MyDate As String) '选择排序(数据结构) as String
%REM
算子日期类型转换成 中文日期类型
%END REM
y = Cstr(Year(MyDate))
m = Month(MyDate)
d = Day(MyDate)
For i = 1 To 4
CCDate = CCDate & Mid("Ο一二三四五六七八九", Val(Mid(y, i, 1)) + 1, 1Next
CCDate = CCDate & "年"
CCDate = CCDate & Trim(Mid("一 二 三 四 五 六 七 八 九 十 十一十二", m * 2 - 1, 2)) & "月"
CCDate = CCDate & Trim(Mid(" 十二十三十", (d \ 10) * 2 + 1, 2)) & Trim(Mid(" 一二三四五六七八九", (d Mod 10) + 1, 1)) & "日"
msgbox CCDate
End Function
接下来我们分析一下这个实现的思路
1、先把日期中的 年月日都独立取出来
y = Cstr(Year(MyDate))
m = Month(MyDate)
d = Day(MyDate)
分别利用 Year 、 Month 、 Day 三个函数,把日期字符串的年、月、日 分别取出来。简单清晰。
2、取出来年份
For i = 1 To 4
CCDate = CCDate & Mid("Ο一二三四五六七八九", Val(Mid(y, i, 1)) + 1, 1)
Next
首先通过 2002 、 2010 、2016 和 二〇〇二年、二〇一〇年、二〇一六年 三个年份写法以及读法对比,数字和文字正好一个对应一个,这样分别把数字转换成 对应的中文字即可。根据这个思路,如果我来写,很可能,写两个数组,对应起来比较,对应的即可替换。但是找到的
这个方法却不是这样实现的。正好利用 mid 函数来取值,先介绍一下这个 lotuscript 里面的 mid 这个参数。
mid(string,start,len) 这个函数是按要求从 string 这个字符串中提取一个字符串,提取的出来的字符串是从 start 开始,一次提取 len 个。(string 从一开始数起,包括 start 所在的数字)。
例子:str$ = mid("我是菜鸟",2,2) 返回的 str$ 的值 就是 “是菜” 。
val(args) 的意思是 把 args 参数转换成字符串形式。
& 符号表示追加的意思。
这样这段代码的意思就很清晰了。我们还以 2017-08-08 这个日期为例来显示一下这个代码的运行过程。取得的年份为 2017
第一次循环: Mid(y, i, 1) 中数字 i 是 1,取出 2017 中的 从 1 位开始的 1个数字是 2,那么 Mid("Ο一二三四五六七八九", Val(Mid(y, i, 1)) + 1, 1) 就相当于是 Mid("Ο一二三四五六七八九", 2 + 1, 1) ,取出来的是“二”,并且赋给 CCDate
第二次循环:Mid(y, i, 1) 中数字 i 是 12,取出 2017 中的 从 2 位开始的 1个数字是 0,那么 Mid("Ο一二三四五六七八九", Val(Mid(y, i, 1)) + 1, 1) 就相当于是 Mid("Ο一二三四五六七八九", 0 + 1, 1) ,取出来的是“〇”,并且赋给 CCDate
……
循环四次把年份取出来以后,在追加上 “年”字,即是 二〇一七年 了
3、取出月份
CCDate = CCDate & Trim(Mid("一 二 三 四 五 六 七 八 九 十 十一十二", m * 2 - 1, 2)) & "月"
从代码我们看出,月份没有按照年份来取,月份按照年份来取得话,1 对应 一、2 对应二 …… 9 对应九,是没有问题的,但是 10 对应 十,11 对应 十一,12 对应 十二,很显然用取年份那样的方法就有问题了,前面是 1位对应 1 位,十是 1位对应2位,十一和十二也是两位对应两位。
两位不能弄成一位来取,我们就把一位用空格补成两位取。
我们把被提取的字符串 写成 “一 二 三 四 五 六 七 八 九 十 十一十二”。
提取开始的从事奇数,m * 2 - 1。
提取的位数是 2
CCDate = 八月
这样月份就提取出来了。
4、取出日份
年月日中的日是1——30。我们分成十位和个位来分析
十位:1——9 当成没有十位,当成是 “ ”,10——19 十位是 1 根据叫法,设成“ 十”,20——29 十位是 2,根据叫法是 “二十”,30的十位是 3,根据叫法是 “三十”。这样的话用 10来除得到的正好是我们所要的。组合到一起 “ ”+“ 十”+“二十”+“三十”=“ 十二十三十”。同样
用奇数开始提取,一次取两个。
Trim(Mid(" 十二十三十", (d \ 10) * 2 + 1, 2))
个位:1——9 个位是 1——9;10——19 个位是 0——9;20——29个位;0——9;30个位是0,如果按照 1——10,11——20,21——30这样来分的话,就规律统一了。个位都是 1,2,3,4,5,6,7,8,9,0 。这个个位正好是 除 10 求余。把个位数按照中文来写 “一二三四五六七八九Ο”,把
0当成空 “一二三四五六七八九 ”,最后去空,正好用trim去掉即可。
Trim(Mid("一二三四五六七八九 ", (d Mod 10), 1))
当然例子中的那种写法也可以
Trim(Mid(" 一二三四五六七八九", (d Mod 10) + 1, 1))
日的组成就是:
Trim(Mid(" 十二十三十", (d \ 10) * 2 + 1, 2)) + Trim(Mid("一二三四五六七八九 ", (d Mod 10), 1)) + “日”
最后把 年份+月份+日 就是中文写法的日期了。
通过这种思路用 JavaScript 实现
1 function dateToChinese()
2 {
3 var str = document.getElementById("oldtxt").value.toString();
4
5 var S_date= new Date(Date.parse(str.replace(/-/g, "/")));
6
7 //1、取年月日
8 var sY = S_date.getFullYear().toString();
10 var sM = parseInt(S_date.getMonth());
11 var sD = parseInt(S_date.getDate());
12
13 var result = "";
14 //2、转换年份
15 for(var i=0;i<=3;i++)
16 {
17 //alert(1)
18 result = result + "Ο一二三四五六七八九".substr(sY.substr(i,1),1);
19 //alert(2)
20 }
21 result=result+"年";
22 //2、获取月份
23 result=result+"一 二 三 四 五 六 七 八 九 十 十一十二".substr(sM*2,2).trim()+"月";
24 //3、获取日
25 result=result+" 十二十三十".substr(sD/10*2,2).trim()+" 一二三四五六七八九".substr(sD%10,1).trim()+"日";
26
27 document.getElementById("newtxt").value = result;
28 }