欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在Python的Flask框架中使用日期和時間的教程

 更新時間:2015年04月21日 09:19:05   投稿:goldensun  
這篇文章主要介紹了在Python的Flask框架中使用日期和時間的教程,包括對各個時區(qū)之間轉(zhuǎn)換的一些處理,需要的朋友可以參考下

 時間戳的問題

我們的微博應(yīng)用的一個忽略了很久的問題就是日間和日期的顯示。

直到現(xiàn)在,我們在我們的User和Post對象中使用Python它自己的方式來渲染時間對象,但這并不是一個好的解決方案。

考慮下這樣的例子。我正在寫這篇文章,此時正是12月31號下午3:54。我的時區(qū)是PST(或者你們更習慣的:UTC-8)。 在Python解釋器中運行,我得到下面輸出:
 

>>> from datetime import datetime
>>> now = datetime.now()
>>> print now
2012-12-31 15:54:42.915204
>>> now = datetime.utcnow()
>>> print now
2012-12-31 23:55:13.635874

在我所在的地方,now()方法返回了正確的時間,但是now()調(diào)用返回的時間是UTC單位。


那么,使用哪個更好呢?

如果我們用now(),所有數(shù)據(jù)庫里的時間戳將會與服務(wù)器運行的當?shù)貢r間一致,這將會產(chǎn)生一些問題。

比如,如果有一天,我們需要將服務(wù)器放到別的地方(不在一個時區(qū)),那么在重啟服務(wù)器之前,數(shù)據(jù)庫里的時間都需要更新到與新地點保持一致。

還會有更為重要的問題。不同時區(qū)的用戶將會很難知道什么時候發(fā)送郵件,如果用戶看到的是PST時區(qū)的時間,他們就很難知道郵件是什么時候發(fā)送的,這就需要用戶根據(jù)這個時間做相應(yīng)的調(diào)整。


很顯然這不是一個好的選擇,這也是我們?yōu)槭裁丛趧?chuàng)建數(shù)據(jù)庫時就使用UTC時區(qū)保存時間戳。

在標準化時間戳為UTC時,解決了移動服務(wù)器的問題。但是他不能解決第二個問題,數(shù)據(jù)和時間在世界上不同地方使用UTC展現(xiàn)給用戶。

假設(shè)一個用戶在PST時區(qū)下午3點發(fā)送了一封郵件,這封郵件立刻顯示在他面前,上面寫著11:00pm,或者更具體點(23:00)。

我寫這個文章的目的也就是讓我們的用戶不再因為數(shù)據(jù)和時間的顯示而困惑。

使用具體的時間戳

通常的解決方法是,每一個用戶都從UTC轉(zhuǎn)化到當?shù)氐臅r間。這就需要我們動態(tài)變化,從而使數(shù)據(jù)庫的UTC與之保持一致。

但是我們怎么知道用戶在哪呢?

許多網(wǎng)站都有一個設(shè)置頁面設(shè)置他們的時區(qū)。這就需要我們添加一個新的頁面,并在表單上提供下拉框讓用戶選擇時區(qū),用戶第一次登錄的時候需要設(shè)置時區(qū),并把它作為注冊的一部分。


這是一個正常的解決方法,但是這對于用戶來說有點累贅,用戶需要輸入一條他們已經(jīng)在操作系統(tǒng)中配置過的信息。所以如果我們能抓取到用戶電腦里設(shè)置的時區(qū)那解決問題會變得更有效率。

出于安全因素,瀏覽器不允許我們進入用戶操作系統(tǒng)獲取信息。即使它允許,我們也得知道在Windows,Linux,Mac,iOS,Android中從哪兒能獲得到時區(qū),這還不包括其他非主流操作系統(tǒng)。

在瀏覽器中得到用戶的時區(qū),然后通過標準的Javascript API獲取到。在Web 2.0世界中用戶允許Javascript執(zhí)行(很少有網(wǎng)站不使用Javascript),所以通過Javascript獲取用戶時區(qū)是可行的。


我們用Javascript有兩種方式配置可用的時區(qū):

    老派的做法:當用戶第一次登錄服務(wù)器時讓瀏覽器以某種方式發(fā)送時區(qū)信息給我們。這個可以通過Ajax調(diào)用,或者更簡單的通過meta refresh tag來實現(xiàn)。一旦服務(wù)器知道了時區(qū)信息,它就能保存它在用戶session中,然后調(diào)整所有頁面的時間顯示。
    新派的做法:不改變服務(wù)器端的任何東西,但仍然會發(fā)送UTC時間戳到客戶端瀏覽器。轉(zhuǎn)換UTC到本地時間的工作通過Javascript在客戶端執(zhí)行。

兩種方法都是有效的,但第二種更有優(yōu)勢一點。瀏覽器能依照系統(tǒng)本地配置最好滴完成時間轉(zhuǎn)換。像上午/下午 vs 24小時制,日/月/年 vs 月/日/年 還有其他各種文化的格式,這些格式都是瀏覽器可訪問的,但服務(wù)器就不一定了。

如果這些還不夠,那新派的做法還有一個更大的優(yōu)勢,而且別人已經(jīng)為我們做了這件事(moment.js要登場了)!

moment.js簡介

Moment.js 是一個小、免費、開源的Javascript庫,它將日期和事件提升到另一個等級。它提供了能想象到的所有的時間日期格式,下面就是一些。

要在我們的應(yīng)用中使用moment.js就需要在我們的模板文件中寫那么一丟丟的Javascript代碼。我們先來通過ISO 8601 時間來創(chuàng)建一個moment對象。例如:通過上面Python例子的UTC時間來創(chuàng)建一個moment對象,就像這樣:
 

moment("2012-12-31T23:55:13 Z")

一旦對象被創(chuàng)建,它就可以被轉(zhuǎn)化成各種各樣格式類型的string。例如,將一個灰常冗長的時間顯示轉(zhuǎn)換為本地系統(tǒng)的時間:
 

moment("2012-12-31T23:55:13 Z").format('LLLL');

下面就是轉(zhuǎn)換以后的時間顯示:

Tuesday, January 1 2013 7:55 AM


這兒有更多的例子將同樣的時間戳轉(zhuǎn)化為不同的格式:

201542191024389.jpg (377×175)

這個類庫對轉(zhuǎn)化選項的支持不止這些。除了format()之外,它還提供了fromNow()和calendar()這些更友好的時間戳轉(zhuǎn)化方法: 

201542191055278.jpg (187×88)

 注意上面所有的例子中服務(wù)器轉(zhuǎn)換相同的UTC時間,而你自己的本地瀏覽器則會轉(zhuǎn)換不同的時間。

最后我們補上漏掉的一點Javascript小技巧,在頁面中顯而易見的是,代碼實際上由moment返回了string類型。最簡單的完成方式是用Javascript的document.write方法:
 

<script>
document.write(moment("2012-12-31T23:55:13 Z").format('LLLL'));
</script>

通過使用Javascript的document.write是灰常簡單和直接的方式來生成一部分HTML代碼,然而需要注意的是這種方式有一些限制。最需要主義的一點就是document.write方法只能在document被加載時使用,當document加載完成后,它便不能修改document了。這個限制的結(jié)果就是當通過 Ajax 來加載數(shù)據(jù)時這種解決方案就失效了。
 
整合moment.js

這兒我們需要做一點點事把moment.js添加到我們的微博客中.

首先,我們需要下載moment.min.js這個庫到/app/static/js這個文件夾中,這樣它就可以作為靜態(tài)文件為客戶端服務(wù)。

然后我們在我們的模板文件(fileapp/templates/base.html)中添加這個庫(moment.min.js)的引用:

 

<script src="/static/js/moment.min.js"></script>

現(xiàn)在我們可以在模板文件中添加<script>標簽來顯示我們想要的時間戳。但我們想替換這種方法,于是我們給moment.min.js加了一層包裝來更好的從模板中調(diào)用它。這樣將節(jié)約我們將來修改時間戳代碼的時間,因為這樣我們只要在一個地方修改它就好了。


我們的包裝是一個灰常簡單的Python類(fileapp/momentjs.py):
 

from jinja2 import Markup
 
class momentjs:
 def __init__(self, timestamp):
 self.timestamp = timestamp
 
 def render(self, format):
  return Markup("<script>\ndocument.write(moment(\"%s\").%s);\n</script>" % (self.timestamp.strftime("%Y-%m-%dT%H:%M:%S Z"), format))
 
 def format(self, fmt):
  return self.render("format(\"%s\")" % fmt)
 
 def calendar(self):
  return self.render("calendar()")
 
 def fromNow(self):
  return self.render("fromNow()")

注意這兒的render方法沒有直接返回一個string類型而是返回一個由我們的模板引擎Jinja2提供的Markup對象。這么做的原因是Jinja2默認會轉(zhuǎn)義所有string,舉例來說,我們的<script>標簽不能被傳到客戶端,而會被替換成&lt;script&gt;("<"">"這些符號被轉(zhuǎn)義了,譯者注)。所以,用Markup對象來包裝這些string會告訴Jinja2這些string不能被轉(zhuǎn)義。

現(xiàn)在我們有了一個包裝器,我們需要通過Jinja2來連接,這樣我們的模板就可以來調(diào)用它(fileapp/__init__.py):
 

from momentjs import momentjs
app.jinja_env.globals['momentjs'] = momentjs

這樣Jinja2就會把我們的類當做全局變量來暴露給所有的模板。


現(xiàn)在我們準備開始修改我們的模板。在我們的應(yīng)用中有兩個地方來顯示日期和事件。一個是在用戶屬性頁面,我們顯示”最后看過“的時間。對于這個時間戳我們將用calendar()方法來轉(zhuǎn)換(fileapp/templates/user.html):
 

{% if user.last_seen %}
<p><em>Last seen: {{momentjs(user.last_seen).calendar()}}</em></p>
{% endif %}

第二個地方是post的子模板中,它被index,user和search頁面調(diào)用。在這兒我們用fromNow()方法來轉(zhuǎn)換,因為post是多久前被創(chuàng)建的比它具體是哪一個時刻被創(chuàng)建的重要。要提取轉(zhuǎn)換以后的post時間到子頁面,我們只需要改動一個地方就可以影響所有需要轉(zhuǎn)換的post時間(fileapp/templates/post.html):

 

<p><a href="{{url_for('user', nickname = post.author.nickname)}}">{{post.author.nickname}}</a> said {{momentjs(post.timestamp).fromNow()}}:</p>
<p><strong>{{post.body}}</strong></p>

隨著這些模板的改動,我們便解決了所有的時間戳問題。我們不需要單獨的去修改服務(wù)器端的代碼!
 
結(jié)束語

不知不覺中,今天我們通過做一些客戶端時間日期配置的改變,已經(jīng)朝使微博客變得更受多國用戶青睞邁出重要一步。

在這個系列的下一部分中,我們將要使微博客支持多國語言(國際化),從而讓它不同國家用戶的更受歡迎。

同時,這兒提供了集成moment.js的應(yīng)用得下載鏈接:

下載 microblog-0.13.zip。

相關(guān)文章

  • Python使用sqlite3第三方庫讀寫SQLite數(shù)據(jù)庫的方法步驟

    Python使用sqlite3第三方庫讀寫SQLite數(shù)據(jù)庫的方法步驟

    數(shù)據(jù)庫非常重要,程序的數(shù)據(jù)增刪改查需要數(shù)據(jù)庫支持,python處理數(shù)據(jù)庫非常簡單,而且不同類型的數(shù)據(jù)庫處理邏輯方式大同小異,下面這篇文章主要給大家介紹了關(guān)于Python使用sqlite3第三方庫讀寫SQLite數(shù)據(jù)庫的方法步驟,需要的朋友可以參考下
    2022-07-07
  • 詳解python中的線程與線程池

    詳解python中的線程與線程池

    這篇文章主要介紹了python線程與線程池,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • Python 中由 yield 實現(xiàn)異步操作

    Python 中由 yield 實現(xiàn)異步操作

    這篇文章主要介紹了Python 中由 yield 實現(xiàn)異步操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • 復(fù)制粘貼功能的Python程序

    復(fù)制粘貼功能的Python程序

    接下來,由于我覺得手動復(fù)制粘貼這29000條插入語句實在是太痛苦了,所以打算用Python來完成這項工作。這是我第一次自己動手寫Python代碼,感覺還挺順利的。
    2008-04-04
  • Python sklearn中的.fit與.predict的用法說明

    Python sklearn中的.fit與.predict的用法說明

    這篇文章主要介紹了Python sklearn中的.fit與.predict的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • 詳解Python的Django框架中的通用視圖

    詳解Python的Django框架中的通用視圖

    這篇文章主要介紹了詳解Python的Django框架中的通用視圖,是為MVC架構(gòu)的Django框架下的基礎(chǔ)知識,需要的朋友可以參考下
    2015-05-05
  • Python腳本實現(xiàn)下載合并SAE日志

    Python腳本實現(xiàn)下載合并SAE日志

    這篇文章主要介紹了Python腳本實現(xiàn)下載合并SAE日志,本文講解了代碼編寫過程,然后給出了完整代碼,需要的朋友可以參考下
    2015-02-02
  • Python 編程速成(推薦)

    Python 編程速成(推薦)

    這篇文章主要介紹了Python 編程速成,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • python編寫根據(jù)年份判斷生肖實例

    python編寫根據(jù)年份判斷生肖實例

    這篇文章主要為大家介紹了python編寫根據(jù)年份判斷生肖實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • 基于Python的身份證號碼自動生成程序

    基于Python的身份證號碼自動生成程序

    今天收到一個小需求:需要一個自動生成身份證號碼的小程序。近期用python較多,因此打算用python實現(xiàn)
    2014-08-08

最新評論