最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

 時(shí)間戳的問(wèn)題

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

直到現(xiàn)在,我們?cè)谖覀兊腢ser和Post對(duì)象中使用Python它自己的方式來(lái)渲染時(shí)間對(duì)象,但這并不是一個(gè)好的解決方案。

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

>>> 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()方法返回了正確的時(shí)間,但是now()調(diào)用返回的時(shí)間是UTC單位。


那么,使用哪個(gè)更好呢?

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

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

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


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

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

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

我寫(xiě)這個(gè)文章的目的也就是讓我們的用戶不再因?yàn)閿?shù)據(jù)和時(shí)間的顯示而困惑。

使用具體的時(shí)間戳

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

但是我們?cè)趺粗烙脩粼谀哪兀?/p>

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


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

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

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


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

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

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

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

moment.js簡(jiǎn)介

Moment.js 是一個(gè)小、免費(fèi)、開(kāi)源的Javascript庫(kù),它將日期和事件提升到另一個(gè)等級(jí)。它提供了能想象到的所有的時(shí)間日期格式,下面就是一些。

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

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

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

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

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

Tuesday, January 1 2013 7:55 AM


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

201542191024389.jpg (377×175)

這個(gè)類(lèi)庫(kù)對(duì)轉(zhuǎn)化選項(xiàng)的支持不止這些。除了format()之外,它還提供了fromNow()和calendar()這些更友好的時(shí)間戳轉(zhuǎn)化方法: 

201542191055278.jpg (187×88)

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

最后我們補(bǔ)上漏掉的一點(diǎn)Javascript小技巧,在頁(yè)面中顯而易見(jiàn)的是,代碼實(shí)際上由moment返回了string類(lèi)型。最簡(jiǎn)單的完成方式是用Javascript的document.write方法:
 

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

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

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

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

然后我們?cè)谖覀兊哪0逦募?fileapp/templates/base.html)中添加這個(gè)庫(kù)(moment.min.js)的引用:

 

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

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


我們的包裝是一個(gè)灰常簡(jiǎn)單的Python類(lèi)(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方法沒(méi)有直接返回一個(gè)string類(lèi)型而是返回一個(gè)由我們的模板引擎Jinja2提供的Markup對(duì)象。這么做的原因是Jinja2默認(rèn)會(huì)轉(zhuǎn)義所有string,舉例來(lái)說(shuō),我們的<script>標(biāo)簽不能被傳到客戶端,而會(huì)被替換成&lt;script&gt;("<"">"這些符號(hào)被轉(zhuǎn)義了,譯者注)。所以,用Markup對(duì)象來(lái)包裝這些string會(huì)告訴Jinja2這些string不能被轉(zhuǎn)義。

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

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

這樣Jinja2就會(huì)把我們的類(lèi)當(dāng)做全局變量來(lái)暴露給所有的模板。


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

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

第二個(gè)地方是post的子模板中,它被index,user和search頁(yè)面調(diào)用。在這兒我們用fromNow()方法來(lái)轉(zhuǎn)換,因?yàn)閜ost是多久前被創(chuàng)建的比它具體是哪一個(gè)時(shí)刻被創(chuàng)建的重要。要提取轉(zhuǎn)換以后的post時(shí)間到子頁(yè)面,我們只需要改動(dòng)一個(gè)地方就可以影響所有需要轉(zhuǎn)換的post時(shí)間(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>

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

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

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

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

下載 microblog-0.13.zip。

相關(guān)文章

  • Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)通過(guò)公共鍵對(duì)字典列表排序算法示例

    Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)通過(guò)公共鍵對(duì)字典列表排序算法示例

    這篇文章主要介紹了Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)通過(guò)公共鍵對(duì)字典列表排序算法,結(jié)合實(shí)例形式分析了Python基于operator模塊中的itemgetter()函數(shù)對(duì)字典進(jìn)行排序的相關(guān)操作技巧,需要的朋友可以參考下
    2018-03-03
  • Python之site-packages目錄的位置

    Python之site-packages目錄的位置

    這篇文章主要介紹了Python之site-packages目錄的位置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • python 中的@運(yùn)算符使用

    python 中的@運(yùn)算符使用

    這篇文章主要介紹了python 中的@運(yùn)算符使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python中mpi4py的所有基礎(chǔ)使用案例詳解

    python中mpi4py的所有基礎(chǔ)使用案例詳解

    這篇文章主要介紹了python中mpi4py的所有基礎(chǔ)使用,本文通過(guò)10個(gè)案例給大家詳細(xì)講解,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • python中@Property屬性使用方法

    python中@Property屬性使用方法

    這篇文章主要介紹了python中@Property屬性使用方法,在Python中,可以通過(guò)@property裝飾器將一個(gè)方法轉(zhuǎn)換為屬性,從而實(shí)現(xiàn)用于計(jì)算的屬性,下面文章圍繞主題展開(kāi)更多相關(guān)詳情,感興趣的小伙伴可以參考一下
    2022-06-06
  • python 上下文管理器及自定義原理解析

    python 上下文管理器及自定義原理解析

    這篇文章主要介紹了python 上下文管理器原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Python從函數(shù)參數(shù)類(lèi)型引出元組實(shí)例分析

    Python從函數(shù)參數(shù)類(lèi)型引出元組實(shí)例分析

    這篇文章主要介紹了Python從函數(shù)參數(shù)類(lèi)型引出元組,結(jié)合實(shí)例形式分析了Python函數(shù)定義與使用中常見(jiàn)的三種參數(shù)類(lèi)型,并簡(jiǎn)單分析了元組類(lèi)型參數(shù)的使用,需要的朋友可以參考下
    2019-05-05
  • pandas和spark dataframe互相轉(zhuǎn)換實(shí)例詳解

    pandas和spark dataframe互相轉(zhuǎn)換實(shí)例詳解

    這篇文章主要介紹了pandas和spark dataframe互相轉(zhuǎn)換實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • python畫(huà)圖把時(shí)間作為橫坐標(biāo)的方法

    python畫(huà)圖把時(shí)間作為橫坐標(biāo)的方法

    今天小編就為大家分享一篇python畫(huà)圖把時(shí)間作為橫坐標(biāo)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • Python基礎(chǔ)入門(mén)之seed()方法的使用

    Python基礎(chǔ)入門(mén)之seed()方法的使用

    這篇文章主要介紹了Python基礎(chǔ)入門(mén)之seed()方法的使用,是Python學(xué)習(xí)當(dāng)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-05-05

最新評(píng)論

黄陵县| 垦利县| 临夏县| 渑池县| 巴楚县| 靖边县| 博乐市| 来宾市| 青岛市| 六安市| 嘉禾县| 泰兴市| 兰州市| 镇康县| 阳东县| 大庆市| 香河县| 临武县| 汉沽区| 聊城市| 徐州市| 三亚市| 海兴县| 达孜县| 阿巴嘎旗| 化德县| 云梦县| 台东市| 湖口县| 屏东县| 洞头县| 定陶县| 马尔康县| 霸州市| 长海县| 乳山市| 合山市| 渭源县| 宣化县| 方正县| 当涂县|