2010-01-27 140 views
128

我有一個文件。在Python中,我想創建它的時間,並將其轉換爲ISO time (ISO 8601) string,同時保留它在東部時區中創建的事實。Python中的ISO時間(ISO 8601)?

如何把文件的ctime但其轉換爲ISO時間字符串時,這表明東部時區(並考慮到夏令時,如果需要的話)?

+0

可能重複(http://stackoverflow.com/questions/969285/如何做 - 我 - 翻譯 - 一個ISO - 8601 - 日期時間字符串到一個python - 日期時間對象) – 2010-06-13 10:57:36

+7

@尼克 - 有用的鏈接,但不是重複 - 他問的轉換方式。 – Yarin 2011-12-19 03:54:51

+1

@ Joseph-我剛纔問這個的問候RFC 3999-應該對這項工作 - [生成Python中的RFC 3339時間戳(http://stackoverflow.com/q/8556398/165673) – Yarin 2011-12-19 03:59:39

回答

9

你需要使用os.stat來獲取文件的創建時間和格式time.strftimetime.timezone組合:

>>> import time 
>>> import os 
>>> t = os.stat('C:/Path/To/File.txt').st_ctime 
>>> t = time.localtime(t) 
>>> formatted = time.strftime('%Y-%m-%d %H:%M:%S', t) 
>>> tz = str.format('{0:+06.2f}', float(time.timezone)/3600) 
>>> final = formatted + tz 
>>> 
>>> final 
'2008-11-24 14:46:08-02.00' 

編輯:交換從gmtime()localtime()

+0

是否帳戶時區夏令時時間?無論夏令時間與否,tz似乎都是一樣的。 – 2010-01-29 06:30:28

+2

這將是無論什麼抵消現在生效。如果DST處於活動狀態,它將與DST不在時的偏移量不同。 – 2010-01-29 06:35:59

4

糾正我,如果我錯了(我不是),但從UTC的偏移更改與夏令時。所以,你應該用

tz = str.format('{0:+06.2f}', float(time.altzone)/3600) 

我也相信的,該標誌應爲不同

tz = str.format('{0:+06.2f}', -float(time.altzone)/3600) 

我可能是錯的,但我不這麼認爲

2

我亞雷克同意,並我還注意到ISO偏移分隔符是冒號,因此我認爲最終答案應該是:

isodate.datetime_isoformat(datetime.datetime.now()) + str.format('{0:+06.2f}', -float(time.timezone)/3600).replace('.', ':') 
37

ISO 8601時間表示

國際標準ISO 8601描述了日期和時間的字符串表示法。這種格式的兩個簡單的例子是

2010-12-16 17:22:15 
20101216T172215 

(兩者代表2010年12月16),但格式還允許亞秒級解決時間和指定的時區。這種格式當然不是Python特定的,但它適用於以便攜式格式存儲日期和時間。有關此格式的詳細信息可以在Markus Kuhn entry

找到我建議你使用這種格式來存儲時間在文件中。獲得當前時間在此表示

一種方法是在Python標準庫使用的strftime從時間模塊:

>>> from time import strftime 
>>> strftime("%Y-%m-%d %H:%M:%S") 
'2010-03-03 21:16:45' 

您可以使用DateTime類的strptime構造:

>>> from datetime import datetime 
>>> datetime.strptime("2010-06-04 21:08:12", "%Y-%m-%d %H:%M:%S") 
datetime.datetime(2010, 6, 4, 21, 8, 12) 

最堅固的是的eGenix mxDateTime模塊:

>>> from mx.DateTime.ISO import ParseDateTimeUTC 
>>> from datetime import datetime 
>>> x = ParseDateTimeUTC("2010-06-04 21:08:12") 
>>> datetime.fromtimestamp(x) 
datetime.datetime(2010, 3, 6, 21, 8, 12) 

參考

+1

什麼感覺是「更強大」? – 2017-07-29 19:10:17

-6
import datetime, time  
def convert_enddate_to_seconds(self, ts): 
    """Takes ISO 8601 format(string) and converts into epoch time.""" 
    dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+\ 
       datetime.timedelta(hours=int(ts[-5:-3]), 
       minutes=int(ts[-2:]))*int(ts[-6:-5]+'1') 
    seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0 
    return seconds 

>>> import datetime, time 
>>> ts = '2012-09-30T15:31:50.262-08:00' 
>>> dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+ datetime.timedelta(hours=int(ts[-5:-3]), minutes=int(ts[-2:]))*int(ts[-6:-5]+'1') 
>>> seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0 
>>> seconds 
1348990310.26 
39

我發現datetime.isoformat在doc;似乎做你想要什麼:

datetime.isoformat([sep]) 

Return a string representing the date and time in ISO 8601 format, YYYY-MM-DDTHH:MM:SS.mmmmmm or, if microsecond is 0, YYYY-MM-DDTHH:MM:SS 

If utcoffset() does not return None, a 6-character string is appended, giving the UTC offset in (signed) hours and minutes: YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM or, if microsecond is 0 YYYY-MM-DDTHH:MM:SS+HH:MM 

The optional argument sep (default 'T') is a one-character separator, placed between the date and time portions of the result. For example, 
>>> 

>>> from datetime import tzinfo, timedelta, datetime 
>>> class TZ(tzinfo): 
...  def utcoffset(self, dt): return timedelta(minutes=-399) 
... 
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ') 
'2002-12-25 00:00:00-06:39' 
+2

你能解釋你如何得到正確的timedelta? – 2016-01-20 13:47:56

163

本地到ISO-8601:

import datetime 
datetime.datetime.now().isoformat() 

UTC到ISO-8601:

import datetime 
datetime.datetime.utcnow().isoformat() 

本地到ISO-8601無微秒:

import datetime 
datetime.datetime.now().replace(microsecond=0).isoformat() 

UTC to ISO-8601 with TimeZone info(蟒蛇3):

import datetime 
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat() 

本地到ISO-8601與時區信息(蟒蛇3):

import datetime, time 
# calculate the offset taking into account daylight saving time 
utc_offset_sec = time.altzone if time.localtime().tm_isdst else time.timezone 
datetime.datetime.now().replace(tzinfo=datetime.timezone(offset=utc_offset_sec)).isoformat() 

對於Python 2,查看和使用pytz

+3

'.isoformat()'可以帶一個分隔符參數,(如果你想要的東西不是'T'):'.isoformat('')' – ThorSummoner 2016-08-24 23:21:27

+0

@ThorSummoner很高興知道!但要注意,更換分隔符不再符合ISO-8601標準......這是沒有道理的(此外,還有更好的方法來打印日期,但這裏不是問題)。 [RFC](https://tools.ietf.org/html/rfc3339#section-5.6) – estani 2016-08-25 07:48:01

+2

允許空間作爲ISO-8601標準的一部分。 '允許通過雙方同意省略'T'字符。' – raychi 2016-09-07 19:52:16

12

ISO8601 time format不存儲時區名稱,只保留相應的utc偏移量。

要將文件的ctime轉換爲ISO 8601時間字符串,同時保留UTC在Python 3偏移:

>>> import os 
>>> from datetime import datetime, timezone 
>>> ts = os.path.getctime(some_file) 
>>> dt = datetime.fromtimestamp(ts, timezone.utc) 
>>> dt.astimezone().isoformat() 
'2015-11-27T00:29:06.839600-05:00' 

的代碼假定您的本地時區是東部時區和您的系統提供了一個正確的UTC給定POSIX時間戳的偏移量(ts),即python可以訪問系統上的歷史時區數據庫,或者時區在給定日期有相同的規則。

如果您需要便攜式解決方案; use pytz module提供訪問the tz database

>>> import os 
>>> from datetime import datetime 
>>> import pytz # pip install pytz 
>>> ts = os.path.getctime(some_file) 
>>> dt = datetime.fromtimestamp(ts, pytz.timezone('America/New_York')) 
>>> dt.isoformat() 
'2015-11-27T00:29:06.839600-05:00' 

其結果是在這種情況下是相同的。

如果您需要的時區名/縮寫/區域ID;另存。

>>> dt.astimezone().strftime('%Y-%m-%d %H:%M:%S%z (%Z)') 
'2015-11-27 00:29:06-0500 (EST)' 

注:在UTC沒有:偏移和EST時區的縮寫是不是ISO8601的時間格式的一部分。這不是唯一的。

不同的庫/不同版本的同一個庫的可能使用不同的時區規則同一日期/時區。如果它是未來的日期,那麼規則可能還未知。換句話說,同樣的UTC時間可以對應不同的本地時間取決於什麼樣的規則,你用 - 在ISO8601格式保存時間保持UTC時間和對應於當前區規則在使用你的平臺上的本地時間。如果規則不同,您可能需要重新計算不同平臺上的本地時間。

25

這裏是我用來轉換爲XSD日期時間格式:

from datetime import datetime  
datetime.now().replace(microsecond=0).isoformat() 
# You get your iso string 

我碰到這個問題,尋找XSD日期時間格式的時候來了。我需要從isoformat中刪除微秒。乾杯!

0

我已經開發了這一功能:?如何將ISO 8601日期字符串轉換成一個Python的datetime對象]

def iso_8601_format(dt): 
    """YYYY-MM-DDThh:mm:ssTZD (1997-07-16T19:20:30-03:00)""" 

    if dt is None: 
     return "" 

    fmt_datetime = dt.strftime('%Y-%m-%dT%H:%M:%S') 
    tz = dt.utcoffset() 
    if tz is None: 
     fmt_timezone = "+00:00" 
    else: 
     fmt_timezone = str.format('{0:+06.2f}', float(tz.total_seconds()/3600)) 

    return fmt_datetime + fmt_timezone