# Flask實作_ext_16_Flask_babel_日期時間 ###### tags: `flask` `flask_ext` `python` `babel` :::danger 官方文件: * [flask_babel](https://pythonhosted.org/Flask-Babel/) * [flask_babel_簡中文件](http://www.pythondoc.com/flask-babel/) * [babel](http://babel.pocoo.org/en/latest/) ::: `flask_babel`包裝了`babel`讓Flask用戶可以便捷的使用它,不管如何,官方文件都很建議要閱讀過一次,至少知道這個package的用途,當然,其它還有如`gettext`、`pytz`、`speaklater`也有其相關性,在了解如何應用之後也記得往下深入理解。 ## 安裝 ```shell pip install Flask-Babel ``` 安裝的時候會將相依套件`babel`一併安裝,不需要各別安裝。 ## 說明 直觀來看,`babel`的應用包括了本地時間、日期、數值的格式化以及多語系的應用,本地(locale)所指的即為`en_US`、`zh_TW`....等設置。 下面是一個官方文件上簡單的設置說明,利用`Locale`來設置語系,案例中利用`Locale.parse`來設置語系為`zh_TW`,如下: ```python= >>>from babel import Locale >>>locale = Locale.parse('zh_TW') >>>locale Locale('zh', territory='TW', script='Hant') ``` 設置本地語系之後,還可以再套其它語系來顯示想顯示的資訊,雖然本地語系已經設置為`zh_TW`,但是還是可以再讓顯示的資訊以`en_US`來呈現,如下範例: ```python= >>>locale.get_display_name() '中文 (繁體, 台灣)' >>>locale.get_display_name('en_US') 'Chinese (Traditional, Taiwan)' ``` 上述只是一個簡單的案例來快速理解『本地』所指的意函,因此當語系切換的時候,呈現的資訊就可以依著語系來變動。 時間與日期的部份可以結合Python的`datetime`、`date`、`time`等package一起使用,更細部份的部份當然還是會希望直接的看官方文件一次,至少理解到包裝起來的`babel`能提供的功能。 下面案例是一個日期時間的格式化,將Python`datetime`物件做為`format_datetime`的參數,再搭配`locale`來做不同語系的呈現。 ```python= >>>from datetime import datetime >>>from babel.dates import format_datetime >>>dt = datetime(2018, 6, 25, 22, 30) >>>format_datetime(dt, locale=locale) '2018年6月25日 下午10:30:00' >>>format_datetime(dt, locale='en_US') 'Jun 25, 2018, 10:30:00 PM' ``` 把鏡頭帶回來`flask_babel`,Flask的擴展應該可以快速上手了,實作,接著初始化參數,`flask_babel`的參數不多,只有兩個: * BABEL_DEFAULT_LOCALE * 預設的語系,沒有設置的話則為`en` * BABEL_DEFAULT_TIMEZONE * 預設時區,沒有設置的話則為`UTC` 了解參數之後,我們就來做實作並初始化,如下: ```python= from flask import Flask from flask.ext.babel import Babel app = Flask(__name__) app.config['SECRET_KEY'] = 'development' app.config['BABEL_DEFAULT_LOCALE'] = 'en' app.config['BABEL_DEFAULT_TIMEZONE']='UTC' babel = Babel(app) ``` 上面我們預設了`locale`為`en`,`timezone=UTC`,當有不同語系的使用者登入的時候,我們可以在登入的時候利用`refresh()`來變更。依官方文件說明,`babel`第一次需要當前用戶的地區的時候,會呼叫`localeselector`,如果需要時區的時候則是呼叫`timezoneselector`,如果回傳`None`的話,就會取參數設置的預設值了。 ## 範例 千言萬語都不如動手來操作,剛才我們看過了`babel`的簡單示範,現在來認識一下`flask-babel`。 範例的部份都是直接在Command上操作,所以有『>>>』就是指令,沒有的就是結果 ```python= >>>from flask import Flask >>>from flask_babel import Babel >>>from flask_babel import format_datetime, get_locale >>>from datetime import datetime >>>app = Flask('tt') >>>babel = Babel(app) >>>dt = datetime(2018, 6, 26, 21, 30) >>>print(dt) datetime.datetime(2018, 6, 26, 21, 30) # 未推入一個request之前如果使用get_locale,雖然不會報錯,但是不會有回傳的值 >>>get_locale() # 測試用,加入一個request,如果沒有加入會報錯 >>>app.test_request_context().push() >>>format_datetime(dt) 'Jun 26, 2018, 9:30:00 PM' >>>babel.default_locale Locale('en') ``` 第7行:單純的設置一個`datetime`物件`dt`,年、月、日、時、分 第11行:測試的時候可以透過`test_request_context().push()`來手動模擬一個`request` 第12行:格式化日期,回傳的格式是很明顯的是`en` 第14行:檢查預設的`default_locale`,可以發現到,即使我們沒有設置參數,預設上還是以`en`為主。 接續著上例,如果現在切換語言至`zh_TW`,那可以透過`refresh()`來做一個`locale`的更新 ```python= >>>y = lambda: 'zh' >>>babel.localeselector(y) >>>get_locale() Locale('en') >>>refresh() >>>get_locale() Locale('zh') >>>format_datetime(dt) '2018年6月26日 下午9:30:00' >>>format_datetime(dt, 'short') '2018/6/26 下午9:30' ``` 第1行:利用`lambda`來設置一個簡單的函數,回傳`zh` 第2行:利用`babel.localeselector`來模擬用戶登入之後取得他的語系 第3行:執行`refresh`之前還是回傳`en` 第5行:執行`refresh`之後還是回傳`zh` 第7行:執行`format_datetime`顯示的格式已經是`zh_TW`的格式 第9行:加入參數`short`,另外還有不少調控的格式,這部份請參閱官方文件 ## 總結 這篇很快速的了解了`babel`於日期、時間格式化的應用,簡單的幾個案例,我們大概對將`babel`加入專案的時候該怎麼結合登入功能的部份心裡有底,另篇會針對`babel`應用在多語系說明,繼續了解。 **Flask_babel_多語系:**[Flask實作_ext_17_Flask_babel_多語系](https://hackmd.io/s/SyX5xZWz7)