日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

时区与程序设计

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 时区与程序设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

時區的定義

我們使用經緯度[1]來標識地球上的任意一個點。

理論時區

不像緯度有赤道作為自然的起點,經度沒有自然的起點而使用經過倫敦格林尼治天文臺舊址的子午線作為起點。

理論時區的寬度是15°,所以一共有 360 / 15 = 24 個時區,一天有 24 小時,所以每個時區正好對應一個小時。自子午線向東,這些時區的名稱為:中時區(以子午線為中心的時區)、東一區、東二區...東十二區、西十一區、西十區...西一區[2]。

由于地球的自轉方向為自西向東,所以越東的時區時間越早。

實際時區

為了避開國界線,有的時區的形狀并不規則,而且比較大的國家以國家內部行政分界線為時區界線,這是實際時區,即法定時區。[2]

同一國家可以有不同的時區,同一國家也可以是同一個時區。

  • 比如美國的夏威夷州是 UTC-10,而加利福尼亞州是 UTC-8
  • 整個中國的理論時區橫跨了從東五區(UTC+5)到東九區(UTC+9)共計五個時區,但國家只有一個時區:北京時間

時區會變化

Why is subtracting these two times (in 1927) giving a strange result?

時區的 offset 不正確[4]

有人推測是時區數據庫錯了而不是 pytz 的問題。但我在其他編程語言的時區庫中沒有搜索到相關問題。

import datetime import pytz shanghai_tz = pytz.timezone('Asia/Shanghai') # 在初始化中傳入的時區的 offset 是不準確的 >>> datetime.datetime(2018, 1, 1, tzinfo=shanghai_tz) datetime.datetime(2018, 1, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>)# 要使用 pytz 文檔中的 localize 才準確 >>> shanghai_tz.localize(datetime.datetime(2018, 1, 1)) datetime.datetime(2018, 1, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)

pytz.tzinfo.localize 的源碼復雜:

def localize(self, dt, is_dst=False):'''Convert naive time to local time.This method should be used to construct localtimes, ratherthan passing a tzinfo argument to a datetime constructor.is_dst is used to determine the correct timezone in the ambigousperiod at the end of daylight saving time.>>> from pytz import timezone>>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'>>> amdam = timezone('Europe/Amsterdam')>>> dt = datetime(2004, 10, 31, 2, 0, 0)>>> loc_dt1 = amdam.localize(dt, is_dst=True)>>> loc_dt2 = amdam.localize(dt, is_dst=False)>>> loc_dt1.strftime(fmt)'2004-10-31 02:00:00 CEST (+0200)'>>> loc_dt2.strftime(fmt)'2004-10-31 02:00:00 CET (+0100)'>>> str(loc_dt2 - loc_dt1)'1:00:00'Use is_dst=None to raise an AmbiguousTimeError for ambiguoustimes at the end of daylight saving time>>> try:... loc_dt1 = amdam.localize(dt, is_dst=None)... except AmbiguousTimeError:... print('Ambiguous')Ambiguousis_dst defaults to False>>> amdam.localize(dt) == amdam.localize(dt, False)Trueis_dst is also used to determine the correct timezone in thewallclock times jumped over at the start of daylight saving time.>>> pacific = timezone('US/Pacific')>>> dt = datetime(2008, 3, 9, 2, 0, 0)>>> ploc_dt1 = pacific.localize(dt, is_dst=True)>>> ploc_dt2 = pacific.localize(dt, is_dst=False)>>> ploc_dt1.strftime(fmt)'2008-03-09 02:00:00 PDT (-0700)'>>> ploc_dt2.strftime(fmt)'2008-03-09 02:00:00 PST (-0800)'>>> str(ploc_dt2 - ploc_dt1)'1:00:00'Use is_dst=None to raise a NonExistentTimeError for these skippedtimes.>>> try:... loc_dt1 = pacific.localize(dt, is_dst=None)... except NonExistentTimeError:... print('Non-existent')Non-existent'''if dt.tzinfo is not None:raise ValueError('Not naive datetime (tzinfo is already set)')# Find the two best possibilities.possible_loc_dt = set()for delta in [timedelta(days=-1), timedelta(days=1)]:loc_dt = dt + deltaidx = max(0, bisect_right(self._utc_transition_times, loc_dt) - 1)inf = self._transition_info[idx]tzinfo = self._tzinfos[inf]loc_dt = tzinfo.normalize(dt.replace(tzinfo=tzinfo))if loc_dt.replace(tzinfo=None) == dt:possible_loc_dt.add(loc_dt)if len(possible_loc_dt) == 1:return possible_loc_dt.pop()# If there are no possibly correct timezones, we are attempting# to convert a time that never happened - the time period jumped# during the start-of-DST transition period.if len(possible_loc_dt) == 0:# If we refuse to guess, raise an exception.if is_dst is None:raise NonExistentTimeError(dt)# If we are forcing the pre-DST side of the DST transition, we# obtain the correct timezone by winding the clock forward a few# hours.elif is_dst:return self.localize(dt + timedelta(hours=6), is_dst=True) - timedelta(hours=6)# If we are forcing the post-DST side of the DST transition, we# obtain the correct timezone by winding the clock back.else:return self.localize(dt - timedelta(hours=6),is_dst=False) + timedelta(hours=6)# If we get this far, we have multiple possible timezones - this# is an ambiguous case occuring during the end-of-DST transition.# If told to be strict, raise an exception since we have an# ambiguous caseif is_dst is None:raise AmbiguousTimeError(dt)# Filter out the possiblilities that don't match the requested# is_dstfiltered_possible_loc_dt = [p for p in possible_loc_dt if bool(p.tzinfo._dst) == is_dst]# Hopefully we only have one possibility left. Return it.if len(filtered_possible_loc_dt) == 1:return filtered_possible_loc_dt[0]if len(filtered_possible_loc_dt) == 0:filtered_possible_loc_dt = list(possible_loc_dt)# If we get this far, we have in a wierd timezone transition# where the clocks have been wound back but is_dst is the same# in both (eg. Europe/Warsaw 1915 when they switched to CET).# At this point, we just have to guess unless we allow more# hints to be passed in (such as the UTC offset or abbreviation),# but that is just getting silly.## Choose the earliest (by UTC) applicable timezone if is_dst=True# Choose the latest (by UTC) applicable timezone if is_dst=False# i.e., behave like end-of-DST transitiondates = {} # utc -> localfor local_dt in filtered_possible_loc_dt:utc_time = (local_dt.replace(tzinfo=None) - local_dt.tzinfo._utcoffset)assert utc_time not in datesdates[utc_time] = local_dtreturn dates[[min, max][not is_dst](dates)]

總結一下,對于 pytz,獲取帶時區的時間要使用 tz.localize(),將一個轉換為另一個時區要 dt_with_tz.astimezone(another_tz)[5]。

程序設計

由于時區的最小單位是小時:

  • 所以如果要區分時區,那么儲存的時間必須包含小時,比如你不能只儲存到天2018-01-01
  • 所以儲存的時間也要包含時區,比如 MongoDB 儲存的時區為 UTC
    • The official BSON specification refers to the BSON Date type as the UTC datetime.[3]

程序中的時區不應該與機器所在的時區掛鉤,否則,假如從中國機房遷移到美國機房,那么你的程序就會出問題。

只需要一個時區

比如對于大部分中國的程序來說,只需要考慮北京時間這一個時區。這里稱這個時區為當地時區。

我認為在程序中(前端、后端)可以只使用當地時區。好處有:

  • 增強可讀性,減少混亂。比如調試時看北京時間肯定比 UTC 時間更直觀
  • 避免不必要的時區轉換

如果數據庫的時區可以修改,那么也修改為當地時區,否則,使用數據庫的時區。

比如 MongoDB 使用 UTC 時區儲存,不可更改(我沒有搜索到更改的配置),那么如果有按月分表,那么也使用 UTC 劃分月,這樣數據庫的時區就統一為了 UTC;如果使用當地時區分月,那么就會造成分歧。

需要多個時區

在程序內部使用 UTC 時區,展示數據時使用用戶選擇的時區。

參考

  • https://zh.wikipedia.org/wiki/經緯度
  • https://zh.wikipedia.org/wiki/時區
  • https://docs.mongodb.com/manual/reference/bson-types/#document-bson-type-date
  • https://bugs.launchpad.net/pytz/+bug/1678858
  • http://pytz.sourceforge.net/#localized-times-and-date-arithmetic
  • 轉載于:https://www.cnblogs.com/jay54520/p/9431333.html

    總結

    以上是生活随笔為你收集整理的时区与程序设计的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 丰满岳乱妇一区二区三区 | 在线亚洲区 | 日日麻批| 亚洲免费中文字幕 | a毛片 | 国产精品一级黄色片 | 最近中文字幕mv免费高清在线 | 狠狠操在线视频 | 91网在线观看 | 午夜网站视频 | 欧美高清视频一区二区三区 | 成人免费视频视频 | 操操网| 欧美一区二区三区日韩 | 美女久久久久久久久 | 乱h伦h女h在线视频 99999视频 | 免费男女乱淫真视频免费播放 | 亚洲黄色小视频 | 激情黄色小说视频 | 国产成人精品一区二区 | 91麻豆精品国产 | www.日韩视频 | 朋友人妻少妇精品系列 | 激情小说欧美色图 | 美女三区| 亚洲欧美第一 | 韩日av片 | 91美女片黄在线观看 | 日韩欧美自拍偷拍 | 隣の若妻さん波多野结衣 | 国产一级淫片免费 | 日本熟妇一区二区 | jizjiz中国少妇高潮水多 | 亚洲精品视屏 | 亚洲欧美视频在线播放 | aa成人 | 久99热 | 热久久91 | 双乳被四个男人吃奶h文 | 伊人爱爱网 | 免费看日韩 | 欧美日韩国产成人在线 | а√天堂资源官网在线资源 | 涩涩屋污 | 日本一区二区三区免费观看 | 亚洲AV第二区国产精品 | 欧美精品在线观看一区二区 | 日韩成人福利 | 日本一区成人 | 91日韩中文字幕 | 日本www在线 | 午夜精品欧美 | 日韩人妻精品无码一区二区三区 | 久久久夜精品 | 亚洲天堂系列 | 三年中国片在线高清观看 | 免费九九视频 | 视频一区二区国产 | 国产亚洲精品av | 国产成人免费片在线观看 | 人妻激情偷乱频一区二区三区 | 激情另类视频 | 青青草一区二区三区 | av在线资源网站 | 日本a级片视频 | 久久88| 男生插女生网站 | 国产裸体永久免费视频网站 | 国产一区二区三区四区 | av网址免费观看 | 欧美午夜精品一区二区三区 | jizz中国女人 | 中文字幕亚洲乱码 | 午夜一级黄色片 | 91国产免费视频 | 成人免费毛片aaaaaa片 | 久久97超碰 | 亚洲三区在线观看无套内射 | 日本精品区 | 天天射天天干 | 成人午夜影片 | 黄色一级片免费 | 黄色网页在线播放 | 奇米影视第四色首页 | a亚洲天堂 | 五月天久久久久久 | 天天做日日做 | 黄色av片三级三级三级免费看 | 亚洲国产欧美在线观看 | sese在线视频 | 成人免费毛片足控 | 久久国产亚洲 | 国产精品图片 | 欧美午夜大片 | 国产女主播在线一区二区 | 国产一二三区免费视频 | 国产在线黄 | 日本大奶子视频 | 强行挺进白丝老师翘臀网站 |