Harvest Nation Flag From IP Address

一個留言版或是討論區常有的功能,能在發言者的旁邊顯示出發言時所留下的國家國旗;網路上也有一些公開的 API 可以呼叫,只要丟一個 IP Address 在 API 後面就可以反查到所在的國家代碼的圖示,例如:Neekey API Services,或是 hostip.info 也是相同的簡單方式就可以使用;另外一種方式就是把廠商放出來的資料庫整合到自己的系統中,這次實做的系統是用 MaxMind 所放出來的 GeoLite Country 資料庫,檔案格式是 Comma Separated Value (CSV),詳細的用法請參閱 GeoIP Country CSV Text Files

其實 CVS 的用法該網站已經寫得很清楚了,以下就是一些實做的步驟記錄。這天拿到的版本有包含 105,920 筆紀錄,格式如下:


StartIPAddress EndIPAddress  StartIPNumber EndIPNumber CountryCode CountryName
140.109.0.0   140.138.255.255 2355953664  2357919743  TW      Taiwan

例如一個 IP 位置為 140.109.18.38 經過計算(ipnum = 16777216*w + 65536*x + 256*y + z)之後可以得到 2355958310 這個值,所以丟到 SQL 上之後就可以得到國別代碼 TW,國家名稱為 Taiwan。這邊唯一要注意的是,存放 StartIPNumber 和 EndIPNumber 的資料格式不能是 Int,因為已經超過其值域範圍,這裡我是使用 bigint(8 bytes, -2^63 to 2^63-1 )。

所以剩下的事情就更簡單了,就是找國旗的圖囉,如 famfamfam.com: Flag Icons 或是 Free World Flags Download | IP2Location™ 都有,所以開發起來應該不難,參考看看囉。

入秋了


那天巧遇 Jaimie 的時候,我說著她總是能用獨特的眼光在平凡之處找出不平凡,至少我是這麼認為的..所以這天早晨去 7-11 的科學研究所旁的小徑上,特地帶著 GRD,也想捕捉點什麼..看著樹上的葉子掛著晶瑩的水珠,雖沒有陽光的陪襯,但還是好美。

圖片套用了 Lightroom Presets 故意營造出 300 壯士的畫面效果,還蠻喜歡的,感謝好友 tacojohn 的不吝分享,謝謝你們讓我看到更多美好的事物。

請到這邊下載:
Inside Lightroom » Colour Presets

如何找出給定日期的該週起始日期

網路上常有一些公開的行程表(schedule),一般會列出好幾筆最近的行程(可能橫跨過去現在未來的日期),如果要把這一週的行程做強調(highlight)的效果,我們勢必要知道一個日期(given date)在當週的頭(Week Begin Date)尾(Week End Date)日期。

上圖是 Roger Federer 的行程表,像是10月13號他在馬德里打球,我個人會比較傾向把這一行做強調,讓瀏覽者一眼就看的到他現在到底在哪打球,所以系統必須要能判斷現在的時間點是否要若在該行程那一週,若是有的話就顯示,沒有的話就找下一個賽事的行程。

拜了一下股溝大神之後,有神人在 2004 年就弄出來了,請參閱以下的連結:
Raj Chidipudi:Getting the Week Start Date and Week End Date in SQL
有一些很陌生的 SQL function,所以以下是自己加上的註解,若要改成 Stored Procedure 的話也是很簡單的,好用喔。


DECLARE @REPORT_DATE DATETIME, @WEEK_BEGINING VARCHAR(10)
SELECT @REPORT_DATE = '2008-10-13T00:00:00'
SELECT @WEEK_BEGINING = 'MONDAY'


這邊就是單純的宣告變數,@REPORT_DATE 就是我們所給予的日期(例如可以把費神的行程中任一天丟進去),而 @WEEK_BEGINING 則是我們告訴系統一星期開始的第一天是星期幾,你可以設定任一個星期,一般我是用星期天,那你只要把他改成 SUNDAY 就可以,純粹只是變數內容而已。


IF @WEEK_BEGINING = 'MONDAY' 
    SET DATEFIRST 1 
ELSE IF @WEEK_BEGINING = 'TUESDAY' 
    SET  DATEFIRST 2 
ELSE IF @WEEK_BEGINING = 'WEDNESDAY'
    SET  DATEFIRST 3 
ELSE IF @WEEK_BEGINING =  'THURSDAY'
    SET  DATEFIRST 4 
ELSE IF @WEEK_BEGINING =  'FRIDAY'
    SET  DATEFIRST 5 
ELSE IF @WEEK_BEGINING =  'SATURDAY'
    SET  DATEFIRST 6 
ELSE IF @WEEK_BEGINING =  'SUNDAY'
    SET  DATEFIRST 7 


接下來這個比較有趣,有一個 DATEFIRST,MSDN 中文版上的白話文是「將一週的第一天設為 1-7 其中一個數字」。所以如果你和我一樣設定成 SUNDAY 的話,這時候的 DATEFIRST 會是 7。


DECLARE @WEEK_START_DATE DATETIME, @WEEK_END_DATE DATETIME
--GET THE WEEK START DATE
SELECT  @WEEK_START_DATE = @REPORT_DATE - (DATEPART(DW,  @REPORT_DATE) - 1) 

--GET THE WEEK END DATE
SELECT  @WEEK_END_DATE = @REPORT_DATE + (7 - DATEPART(DW,  @REPORT_DATE))


上面的查詢句就是重點了,他的大意就是用使用者給定的日期去減掉 (運算式) 來對日期對往前或往後的動作。而 SELECT (DATEPART(DW, @REPORT_DATE) - 1) 這一句是指我給定的日期這一天是代表一個星期中的第幾天,由於是往前取日期,所以才預先 -1,所以反之如果要算該日期的當週最後一天的日期時,就是用 7 去減就可以得到值,再加上原本給定的日期,就會得到往後推遲幾天的日期了。DATEPART 中的 DW 是指 weekday,詳細說明請參閱這裡


PRINT 'Week Start: ' + CONVERT(VARCHAR, @WEEK_START_DATE)
PRINT 'Week End: ' + CONVERT(VARCHAR, @WEEK_END_DATE)


最後作者是列印出結果,當然你也可以把他改成 SELECT 這樣程式執行完 SP 後就可以得到這兩個起迄日期的值。

以上是自己的小小筆記,年紀大了需要寫下來才不會忘記,若是有相同情境的需求,這個 SP 應該可以適用喔 ^_^

沈葆楨廳 Shen Pao-Cheng Hall@Tapei City Hall


就是這半年心情的寫照,期望掙脫研究泥淖的那天。