前些日子,一個專案因為使用者分散在不同的國家中,所以有一個需求是必需要自動判斷使用者所在的時區,將時間轉換成當地時間,有找到幾個方案,其中使用IP address database是比較簡單的,有很多公司有推出IP對應的國家、地區、時區,大部分都要錢,不然就是免費版本的資料量不多,當好有找到一家完全免費的IpInfoDB,本篇分享如何用此資料庫完成時區轉換。

 

 自動判斷時區(TimeZone)與時間轉換之IP address database

網址:http://ipinfodb.com/

 

資料庫下載頁:http://ipinfodb.com/ip_database.php

自動判斷時區(TimeZone)與時間轉換之IP address database

有City與Country二種資料庫,像台灣這小地方,不同的城市都是相同的時區,但像美國或加拿大這些地大的國家,不同的城市有不同的時區,所以如果只下載Country的資料庫,沒有辦法得知正確的時區,而他City又分Small或Complete二種,如果只是測試下載Small應該足夠,因為我覺得Select時一個table比較省事,所以我用One DataTables格式。

 

時區下載頁:http://ipinfodb.com/timezonedatabase.php

 

格式有 SQL、CSV二種,SQL是MySql的格式,不是標準的SQL,如果你的資料庫引擎不是MySql,請不要下載,而我是用MS SQL所以我下載CSV檔。

二個壓縮檔解開,裡面共有6個檔案

  • ip_group_country.csv 不新增 IP對應的國家,因為City資料表就包含國家資訊了,所以用不到這個資料表。
  • ip_group_city.csv 新增 IP對應的城市,包含的國家資訊與座標。
  • iso3166_countries.csv 不新增 縮寫對應的國家,如TW=Taiwan,資訊在City中包含。
  • fips_regions.csv 新增  Federal Information Processing Standards(聯邦資料處理標準)地區代碼,城市對應的時區。
  • timezones.csv 選項 時區的名稱,如Asia/Taipei,轉換時區用不到,不過可以用來顯示資訊。
  • timezones_data.csv 新增 時區對應的UTC Offset。

我是用MS SQL的Import and Export Wizard來完成資料的匯入,在匯入過程中有遇到一些小問題,各位要注意。

1.檔案的換行是{LF}。

2.文字有用雙引號"分隔。

3.第一行是資料欄。

  自動判斷時區(TimeZone)與時間轉換之IP address database

 

匯入時預設的格式為String,有三個資料欄一定要轉換,不然計算會出錯。

  • ip_group_city.csv的ip_start(bigint)。
  • timezones.csv的start(bigint)gmtoff(int)

注:因為ip_start是無符號int,MS SQL沒有這種格式,所以用bigint。

自動判斷時區(TimeZone)與時間轉換之IP address database

 

資料格式說明

ip_group_city

自動判斷時區(TimeZone)與時間轉換之IP address database

ip_start ip的Int格式,你可以打開小算盤(Win7),來算一下值是什麼意思了。

自動判斷時區(TimeZone)與時間轉換之IP address database 

latitude、longitude是經緯度。

查詢時只要取出比目前IP大的第一筆就可以了,SQL如下

by ip_start desc

 

fips_regions.csv

 自動判斷時區(TimeZone)與時間轉換之IP address database
從ip_group_city資料表可以取得Country_Code與Region_Code就可以判斷出timezone。
 
 

timezones_data.csv

自動判斷時區(TimeZone)與時間轉換之IP address database
start與gmtoff 的大小是秒數,start是MySql的格式,以1970/1/1時為基準,可以用下列SQL取得正確時間。
'1970/1/1') --1980-09-29 19:00:00.000
abbreviation指是是時間格式
  • CST Central Standard Time - 美國中部標準時間
  • Central Daylight Time - 美國夏令時間,要有加減一小時,還沒完全搞懂,所以此範例沒有判斷此。

Select取start最大的一筆就可以了。

 

範例

自動判斷時區(TimeZone)與時間轉換之IP address database

這是一個IP的測試範例,包含了受測IP、所在地、時區等資訊。

1.首先要取得IP

//如果有參數使用參數
}
 
2.將IP轉成uint
//ip沒有正負號,所以用uint
uint ipInt = (uint.Parse(temp[0]) << 24) + (uint.Parse(temp[1]) << 16) + (uint.Parse(temp[2]) << 8) + uint.Parse(temp[3]);

3.取得資訊
//時區資料
var timezoneData = ipInfo.timezones_datas
.Where(x => x.timezone == region.timezone)
.OrderByDescending(x => x.start)
.First();

4.顯示資訊

, city.latitude, city.longitude));

結語

使用這個方案,有幾個缺點就是

  • IP的地區如果變動不會知道,如果是買的,可能還有售後服務,免費的要資料是最新的可能有點難。
  • VPN資料必需手動自行建立。

相关文章: