2010-08-03 9 views
39

Ho bisogno di produrre una stringa temporale che corrisponda al formato ISO yyyy-mm-ddThh:mm:ss.ssssss-ZO:NE. I metodi di classe now() e utcnow() fanno quasi ciò che voglio.Come ottenere una stringa datetime isoformat includendo il fuso orario predefinito?

>>> import datetime 
>>> #time adjusted for current timezone 
>>> datetime.datetime.now().isoformat() 
'2010-08-03T03:00:00.000000' 
>>> #unadjusted UTC time 
>>> datetime.datetime.utcnow().isoformat() 
'2010-08-03T10:00:00.000000' 
>>> 
>>> #How can I do this? 
>>> datetime.datetime.magic() 
'2010-08-03T10:00:00.000000-07:00' 

risposta

-4

Qualcosa come il seguente esempio. Nota: sono nell'Australia orientale (UTC + 10 ore al momento).

>>> import datetime 
>>> dtnow = datetime.datetime.now();dtutcnow = datetime.datetime.utcnow() 
>>> dtnow 
datetime.datetime(2010, 8, 4, 9, 33, 9, 890000) 
>>> dtutcnow 
datetime.datetime(2010, 8, 3, 23, 33, 9, 890000) 
>>> delta = dtnow - dtutcnow 
>>> delta 
datetime.timedelta(0, 36000) 
>>> hh,mm = divmod((delta.days * 24*60*60 + delta.seconds + 30) // 60, 60) 
>>> hh,mm 
(10, 0) 
>>> "%s%+02d:%02d" % (dtnow.isoformat(), hh, mm) 
'2010-08-04T09:33:09.890000+10:00' 
>>> 
+1

Piccola correzione per la formattazione: "% s% + 03d:% 02d"% (dtnow.isoformat(), hh, mm) –

+8

L'uso della sottrazione per determinare la differenza tra il proprio fuso orario e qualsiasi altro è irto di pericoli. Molto meglio sono le soluzioni in cui fornisci il fuso orario. –

+2

Sono d'accordo: non usare questa soluzione. Non reinventare la ruota. – osa

31

È necessario rendere gli oggetti datetime timezone consapevoli. da datetime docs:

Esistono due tipi di oggetti di data e ora: "ingenuo" e "consapevole". Questa distinzione si riferisce al fatto che l'oggetto abbia qualche nozione di fuso orario, ora legale o altro tipo di aggiustamento temporale algoritmico o politico. Se un oggetto datetime ingenuo rappresenta l'UTC (Coordinated Universal Time), l'ora locale o il fuso orario in qualche altro fuso orario è puramente fino al programma, proprio come succede al programma se un determinato numero rappresenta metri, miglia o massa. Gli oggetti datetime ingenui sono facili da capire e da usare, al costo di ignorare alcuni aspetti della realtà.

Quando si dispone di un oggetto datetime consapevole, è possibile utilizzare isoformat() e ottenere l'output necessario.

per rendere gli oggetti consapevoli vostra datetime, è necessario subclass tzinfo, like the second example in here, o semplice - utilizzare un pacchetto che fa per voi, come pytz o python-dateutil

Utilizzando pytz, questo sarebbe simile:

import datetime, pytz 
datetime.datetime.now(pytz.timezone('US/Central')).isoformat() 

è possibile controllare anche il formato di output, se si utilizza strftime con la '%z' format directive come

datetime.datetime.now(pytz.timezone('US/Central')).strftime('%Y-%m-%dT%H:%M:%S.%f%z') 
+3

Non completamente corretto: la direttiva del formato% z stampa l'offset del fuso orario senza i due punti, tuttavia il formato ISO separa le ore e i minuti nello specificatore TZ con i due punti. Tuttavia, funzionerà il metodo isoformat() su un datetime timezone-aware! – tjollans

+4

Un datetime timezone aware si formatterà correttamente con .isoformat(). –

+1

Per espandere il commento da @ DavidK.Hess, 'strftime' nel tuo secondo esempio è eccessivamente complicato. I seguenti lavori e (IMO) è più pulito:.. 'Datetime.now() sostituire (tzinfo = pytz.timezone ("US/orientale")) isoformat()' – jedwards

46

Per ottenere il tempo corrente in UTC in Python 3.2+:

>>> from datetime import datetime, timezone 
>>> datetime.now(timezone.utc).isoformat() 
'2015-01-27T05:57:31.399861+00:00' 

per ottenere il tempo locale in Python 3.3+:

>>> from datetime import datetime, timezone 
>>> datetime.now(timezone.utc).astimezone().isoformat() 
'2015-01-27T06:59:17.125448+01:00' 

Spiegazione: datetime.now(timezone.utc) produce un fuso orario a conoscenza datetime oggetto nel tempo UTC. astimezone() quindi modifica il fuso orario dell'oggetto datetime, nel fuso orario locale del sistema se chiamato senza argomenti. Gli oggetti datetime con fuso orario producono quindi automaticamente il formato ISO corretto.

+0

A partire da Python 3.6, il 'astimezone()' può ora essere chiamato istanze naive che si presumono rappresentare sistema ora locale. –

+0

@ABB anche su Python 3.6, si dovrebbe utilizzare oggetti datetime consapevoli che funzionano anche se il tempo locale attuale è ambigua (ad esempio, durante una transizione DST). – jfs

16

Con arrow:

>>> import arrow 
>>> arrow.now().isoformat() 
'2015-04-17T06:36:49.463207-05:00' 
>>> arrow.utcnow().isoformat() 
'2015-04-17T11:37:17.042330+00:00' 
2

Puoi farlo in Python 2.7+ con python-dateutil (che è insalled su Mac per impostazione predefinita):

>>> from datetime import datetime 
>>> from dateutil.tz import tzlocal 
>>> datetime.now(tzlocal()).isoformat() 
'2016-10-22T12:45:45.353489-03:00' 

Oppure, se si desidera convertire da un stringa memorizzata esistente:

>>> from datetime import datetime 
>>> from dateutil.tz import tzlocal 
>>> from dateutil.parser import parse 
>>> parse("2016-10-21T16:33:27.696173").replace(tzinfo=tzlocal()).isoformat() 
'2016-10-21T16:33:27.696173-03:00' <-- Atlantic Daylight Time (ADT) 
>>> parse("2016-01-21T16:33:27.696173").replace(tzinfo=tzlocal()).isoformat() 
'2016-01-21T16:33:27.696173-04:00' <-- Atlantic Standard Time (AST) 
Problemi correlati