2010年6月30日 星期三

民國年與西洋年轉換之MySQL Function

民國年與西洋年轉換之MySQL Function
=====================================
先開table吧.使用底下的sql command.
-----------------------
use mysample;

create table olddate(
  id int auto_increment primary key,
  olddate char(9),
  newdate date
);

insert into olddate(olddate)
 values(
 '99/03/05'
);

insert into olddate(olddate)
 values(
 '101/10/04'
);
----------------------

再來就寫個function 將民國年轉成西洋年.程式碼如下:

----------------------
DELIMITER $$

DROP FUNCTION IF EXISTS `mysample`.`chi2jul`$$
CREATE FUNCTION `mysample`.`chi2jul` (olddate char(9)) RETURNS date
BEGIN
 declare str_len int;
 declare cut_len int;
 declare old_year int;
 declare new_year int;
 declare new_date_str char(10);
 declare new_date date;

 set str_len = length(olddate);

 if str_len = 8 then
    set cut_len = 2;
 else
    set cut_len = 3;
 end if;

 set old_year = convert(left(olddate, cut_len),unsigned integer);
 
 set new_year = old_year + 1911;

 set new_date_str = concat(cast(new_year as char), right(olddate, 6));

 set new_date = cast(new_date_str as date);
 /* we can also use str_to_date() and date_format()
    functions to transfer
 */
 return new_date;


END$$

DELIMITER ;
---------------------------------
測試一下:
mysql> select id,chi2jul(olddate) from olddate;
+----+------------------+
| id | chi2jul(olddate) |
+----+------------------+
|  1 | 2010-03-05       |
|  2 | 2012-10-04       |
+----+------------------+
2 rows in set (0.00 sec)

結果正確!接下來直接轉換.

mysql> update olddate
    ->  set newdate = chi2jul(olddate);
Query OK, 0 rows affected (0.00 sec)
Rows matched: 2  Changed: 0  Warnings: 0

mysql> select * from olddate;
+----+-----------+------------+
| id | olddate   | newdate    |
+----+-----------+------------+
|  1 | 99/03/05  | 2010-03-05 |
|  2 | 101/10/04 | 2012-10-04 |
+----+-----------+------------+
2 rows in set (0.00 sec)

成功轉換!
****************************************************

底下是產生到暫存table的方式 --->
產生一個暫存轉換用的table,sql 如下:
----------------------------
create table tmp_newdate(
  id int,
  newdate date
);

insert into tmp_newdate (id, newdate)
select id, chi2jul(olddate)
from olddate;

mysql> insert into tmp_newdate (id, newdate)
    -> select id, chi2jul(olddate)
    -> from olddate;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from tmp_newdate;
+------+------------+
| id   | newdate    |
+------+------------+
|    1 | 2010-03-05 |
|    2 | 2012-10-04 |
+------+------------+
2 rows in set (0.00 sec)

mysql> update olddate,tmp_newdate
    ->  set olddate.newdate = tmp_newdate.newdate
    ->  where olddate.id = tmp_newdate.id;
Query OK, 2 rows affected (0.15 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from olddate;
+----+-----------+------------+
| id | olddate   | newdate    |
+----+-----------+------------+
|  1 | 99/03/05  | 2010-03-05 |
|  2 | 101/10/04 | 2012-10-04 |
+----+-----------+------------+
2 rows in set (0.00 sec)

成功轉換!
*******************************************
有了民國年轉西洋年,再來要有配對的西洋年轉民國年的Function才完整.
此時要注意1911年及1911年以前的狀況.
1912年為民國1年,1911年為民前1年.
另外為了兼顧轉換時不需要民國yyyy年mm月dd日格式,所以有轉換型態之參數.
程式如下:
------------------------------
DELIMITER $$

DROP FUNCTION IF EXISTS `mysample`.`jul2chi`$$
CREATE FUNCTION `mysample`.`jul2chi` (in_date DATE, in_trantype INT) RETURNS CHAR(18)
BEGIN
DECLARE date_char1 char(30);
DECLARE tran_date date;
DECLARE date_char char(10);
DECLARE cyear char(4);
DECLARE cmonth char(2);
DECLARE cday char(2);
DECLARE iyear int;
DECLARE rtn_date char(18);
DECLARE after_flag int default 1;
DECLARE charyear char(4) default '民國';

-- ************************************
-- vincent chang
-- ************************************
set date_char1 = cast(in_date as char);
set tran_date = str_to_date(date_char1, '%Y-%m-%d');
set date_char = date_format(in_date,'%Y-%m-%d');
-- Force transfered to YYYY-mm-dd format

set cyear = left(date_char,4);
set cmonth = substr(date_char,6,2);
set cday = right(date_char,2);

set iyear = convert(cyear, signed integer);
set iyear = iyear - 1911;

if iyear <= 0 then
   set after_flag = -1;
   set iyear = iyear - 1; 
   set iyear = iyear * after_flag;
   set charyear = '民前';
end if;


if in_trantype = 1 then
   set rtn_date = concat(charyear,convert(iyear,char(4)),'年',
               cmonth,'月',cday,'日');
else
   set rtn_date = concat(iyear,'-',cmonth,'-',cday);
end if;

RETURN rtn_date;

END$$

DELIMITER ;
-----------------------------------
接下來進行測試.建立一個table,把一些特別的日子放進去.

use mysample;

create table julchi(
  julian date,
  chinadate1 char(18),
  chinadate2 char(18)
);

insert into julchi(julian)
values (str_to_date('2010-06-30', '%Y-%m-%d'));

insert into julchi(julian)
values (str_to_date('2014-06-30', '%Y-%m-%d'));

insert into julchi(julian)
values (str_to_date('1999-12-31', '%Y-%m-%d'));

insert into julchi(julian)
values (str_to_date('2000-01-01', '%Y-%m-%d'));

insert into julchi(julian)
values (str_to_date('1912-01-01', '%Y-%m-%d'));

insert into julchi(julian)
values (str_to_date('1911-12-31', '%Y-%m-%d'));

insert into julchi(julian)
values (str_to_date('1900-06-30', '%Y-%m-%d'));
------------------------------------
mysql> update julchi
    -> set chinadate1 = jul2chi(julian,1);
Query OK, 7 rows affected (0.01 sec)
Rows matched: 7  Changed: 7  Warnings: 0

mysql> update julchi
    -> set chinadate2 = jul2chi(julian,2);
Query OK, 7 rows affected (0.00 sec)
Rows matched: 7  Changed: 7  Warnings: 0

mysql> select * from julchi;
+------------+------------------------+------------+
| julian     | chinadate1             | chinadate2 |
+------------+------------------------+------------+
| 2010-06-30 | 民國99年06月30日       | 99-06-30   |
| 2014-06-30 | 民國103年06月30日      | 103-06-30  |
| 1999-12-31 | 民國88年12月31日       | 88-12-31   |
| 2000-01-01 | 民國89年01月01日       | 89-01-01   |
| 1912-01-01 | 民國1年01月01日        | 1-01-01    |
| 1911-12-31 | 民前1年12月31日        | 1-12-31    |
| 1900-06-30 | 民前12年06月30日       | 12-06-30   |
+------------+------------------------+------------+
7 rows in set (0.00 sec)

轉換成功!

沒有留言:

張貼留言