民國年與西洋年轉換之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)
轉換成功!
2010年6月30日 星期三
2010年6月18日 星期五
FCron : Vixie Cron的替代品
現在CentOS系統上的cron,是vixie cron, Paul Vixie寫的.有一些其他的cron程式可以提供
更多功能,例如fcron
http://fcron.free.fr/
也可以精確到秒.或是視系統loading調整.
另外有前端GUI,協助我們使用,fcronq
http://code.google.com/p/fcronq/
http://sourceforge.net/projects/fcronq/
是用python開發的
更多功能,例如fcron
http://fcron.free.fr/
也可以精確到秒.或是視系統loading調整.
另外有前端GUI,協助我們使用,fcronq
http://code.google.com/p/fcronq/
http://sourceforge.net/projects/fcronq/
是用python開發的
cron with date tip
If need to run a job on the 3rd Wednesday of every month, but cron won’t let me do this. Run every day in the 3rd week, but then check that the day is a Wednesday. e.g.
00 02 15-21 * * if [ `date +\%u` -eq 3 ] ; then run_myjob; fi
Note that the \ is used to escape the %, otherwise cron treats it as a newline.
2010年6月17日 星期四
start-stop-daemon on CentOS
有些package會使用start-stop-daemon 來啟動/停止 daemon,例如Secrond就是.
但是這是Debian/Ubuntu 的,在RHEL/Fedora/CentOS裡沒有,這樣就會發生錯誤,
造成無法正常控制Daemon. 我們可以修改/etc/init.d/daemon-script
但是這樣以後每個使用此機制的都要修改,也是麻煩.那我們要生一個這個指令出來,
有人是找一台Debian copy過來.其實在我們的CentOS裡面已經有source code了.
先檢查一下sysvinit有沒有安裝,一般都是有的啦.然後在 /usr/share/doc/SysVinit-2.86
裡面有 start-stop-daemon.c
這樣就可以gcc start-stop-daemon.c -o start-stop-daemon
然後 cp start-stop-daemon /usr/sbin
這世界沒那麼美好..... compile時會發生錯誤 (>"<)
我已經修正好程式了, 按我download
用這個compile 就可以用了,因為我沒有做什麼了不起的修改,所以都沒有在source code裡附加上名字,都是原作者的名字.
但是這是Debian/Ubuntu 的,在RHEL/Fedora/CentOS裡沒有,這樣就會發生錯誤,
造成無法正常控制Daemon. 我們可以修改/etc/init.d/daemon-script
但是這樣以後每個使用此機制的都要修改,也是麻煩.那我們要生一個這個指令出來,
有人是找一台Debian copy過來.其實在我們的CentOS裡面已經有source code了.
先檢查一下sysvinit有沒有安裝,一般都是有的啦.然後在 /usr/share/doc/SysVinit-2.86
裡面有 start-stop-daemon.c
這樣就可以gcc start-stop-daemon.c -o start-stop-daemon
然後 cp start-stop-daemon /usr/sbin
這世界沒那麼美好..... compile時會發生錯誤 (>"<)
我已經修正好程式了, 按我download
用這個compile 就可以用了,因為我沒有做什麼了不起的修改,所以都沒有在source code裡附加上名字,都是原作者的名字.
可以精確到秒的cron daemon : Secrond , cron handling tasks in intervals of seconds
cron是系統管理的好幫手,但是只能設定到分鐘.網路上有些是用shell script / sleep
方法來設法達到秒,但是sleep會有誤差的.
有人就開發了可以精確到秒的cron wrap daemon.
Secrond:
https://launchpad.net/secrond
目前是0.41版.
安裝以後會有說明:
----------------------------
Installing init script at /etc/init.d/secrond ...
Creating settings directory at /etc/secrond ...
Installing schedule file at /etc/secrond/schedule ...
EDIT schedule in: /etc/secrond/schedule
START secrond with: /etc/init.d/secrond start
RELOAD schedule with: /etc/init.d/secrond reload
-----------------------------
這樣我們就知道怎樣設定跟啟動daemon.
接下來就寫個 shell script來測試一下:
script name: testsecron.sh
內容很簡單,就是touch一個file, file name format要有時間戳.
如下:
======================
#!/bin/bash
touch /home/vincent/myshell/test_`date +%Y:%m:%d-%H:%M:%S`
======================
然後到/etc/secrond/
vim schedule
======================
# SECOND(0-59) MINUTE(0-59) HOUR(0-23) DAY(1-31) COMMAND
10 * * * /home/vincent/myshell/testsecron.sh
======================
檔案第一行就有format的說明,我們就設定精確到逢每分鐘的10秒就執行剛才的script.
接下來當然要把daemon啟動.
然後去喝杯咖啡,抽根煙.再來檢查執行結果:
-rw-r--r-- 1 root root 0 6月 18 10:58 test_2010:06:18-10:58:10
-rw-r--r-- 1 root root 0 6月 18 10:59 test_2010:06:18-10:59:10
-rw-r--r-- 1 root root 0 6月 18 11:00 test_2010:06:18-11:00:10
-rw-r--r-- 1 root root 0 6月 18 11:01 test_2010:06:18-11:01:10
-rw-r--r-- 1 root root 0 6月 18 11:02 test_2010:06:18-11:02:10
--------------------
效果不錯 (^.^)
===========================
再來試試一次每隔20秒執行一次.
到/etc/secrond/
vim schedule
=========================================================
# SECOND(0-59) MINUTE(0-59) HOUR(0-23) DAY(1-31) COMMAND
10,30,50 * * * /home/vincent/myshell/testsecron.sh
-------------------------------------------
# service secrond start
Starting periodic command scheduler secrond
-------------------------------------------
-rw-r--r-- 1 root root 0 6月 22 19:43 test_2010:06:22-19:43:10
-rw-r--r-- 1 root root 0 6月 22 19:43 test_2010:06:22-19:43:30
-rw-r--r-- 1 root root 0 6月 22 19:43 test_2010:06:22-19:43:50
-rw-r--r-- 1 root root 0 6月 22 19:44 test_2010:06:22-19:44:10
-rw-r--r-- 1 root root 0 6月 22 19:44 test_2010:06:22-19:44:30
-rw-r--r-- 1 root root 0 6月 22 19:44 test_2010:06:22-19:44:50
-rw-r--r-- 1 root root 0 6月 22 19:45 test_2010:06:22-19:45:10
-rw-r--r-- 1 root root 0 6月 22 19:45 test_2010:06:22-19:45:30
果然就每隔20秒執行一次了.
方法來設法達到秒,但是sleep會有誤差的.
有人就開發了可以精確到秒的cron wrap daemon.
Secrond:
https://launchpad.net/secrond
目前是0.41版.
安裝以後會有說明:
----------------------------
Installing init script at /etc/init.d/secrond ...
Creating settings directory at /etc/secrond ...
Installing schedule file at /etc/secrond/schedule ...
EDIT schedule in: /etc/secrond/schedule
START secrond with: /etc/init.d/secrond start
RELOAD schedule with: /etc/init.d/secrond reload
-----------------------------
這樣我們就知道怎樣設定跟啟動daemon.
接下來就寫個 shell script來測試一下:
script name: testsecron.sh
內容很簡單,就是touch一個file, file name format要有時間戳.
如下:
======================
#!/bin/bash
touch /home/vincent/myshell/test_`date +%Y:%m:%d-%H:%M:%S`
======================
然後到/etc/secrond/
vim schedule
======================
# SECOND(0-59) MINUTE(0-59) HOUR(0-23) DAY(1-31) COMMAND
10 * * * /home/vincent/myshell/testsecron.sh
======================
檔案第一行就有format的說明,我們就設定精確到逢每分鐘的10秒就執行剛才的script.
接下來當然要把daemon啟動.
然後去喝杯咖啡,抽根煙.再來檢查執行結果:
-rw-r--r-- 1 root root 0 6月 18 10:58 test_2010:06:18-10:58:10
-rw-r--r-- 1 root root 0 6月 18 10:59 test_2010:06:18-10:59:10
-rw-r--r-- 1 root root 0 6月 18 11:00 test_2010:06:18-11:00:10
-rw-r--r-- 1 root root 0 6月 18 11:01 test_2010:06:18-11:01:10
-rw-r--r-- 1 root root 0 6月 18 11:02 test_2010:06:18-11:02:10
--------------------
效果不錯 (^.^)
===========================
再來試試一次每隔20秒執行一次.
到/etc/secrond/
vim schedule
=========================================================
# SECOND(0-59) MINUTE(0-59) HOUR(0-23) DAY(1-31) COMMAND
10,30,50 * * * /home/vincent/myshell/testsecron.sh
-------------------------------------------
# service secrond start
Starting periodic command scheduler secrond
-------------------------------------------
-rw-r--r-- 1 root root 0 6月 22 19:43 test_2010:06:22-19:43:10
-rw-r--r-- 1 root root 0 6月 22 19:43 test_2010:06:22-19:43:30
-rw-r--r-- 1 root root 0 6月 22 19:43 test_2010:06:22-19:43:50
-rw-r--r-- 1 root root 0 6月 22 19:44 test_2010:06:22-19:44:10
-rw-r--r-- 1 root root 0 6月 22 19:44 test_2010:06:22-19:44:30
-rw-r--r-- 1 root root 0 6月 22 19:44 test_2010:06:22-19:44:50
-rw-r--r-- 1 root root 0 6月 22 19:45 test_2010:06:22-19:45:10
-rw-r--r-- 1 root root 0 6月 22 19:45 test_2010:06:22-19:45:30
果然就每隔20秒執行一次了.
訂閱:
文章 (Atom)