Iso Time (Iso 8601) in Python

Does datetime.isoformat() really conform to ISO-8601?

ISO 8601 only permits UTC offsets using hours and minutes. From the spec:

4.2.5.2 Local time and the difference from UTC

...

The difference between the time scale of local time and UTC shall be
expressed in hours-and-minutes, or hours-only independent of the
accuracy of the local time expression associated with it.

So you're correct that datetime.isoformat doesn't always produce ISO 8601 compatible UTC offsets.

how to convert ISO 8601 to Date time(Utc) in Python

This can be done using the built-in datetime module:

import datetime as dt

input_string = '2022-06-19T00:00:00+00:00'
date = dt.datetime.fromisoformat(input_string)
print(date.strftime('%b %d, %Y'))

Python: How to compare date string in ISO 8601 format with current time

Try using datetime.fromisoformat(date_string) to parse date_str and then passing the determined timezone info into datetime.now(tz=None):

>>> from datetime import datetime
>>> date_str = '2022-03-29T17:49:35.914417-04:00'
>>> dt = datetime.fromisoformat(date_str)
>>> dt
datetime.datetime(2022, 3, 29, 17, 49, 35, 914417, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))
>>> dt_now = datetime.now(dt.tzinfo)
>>> dt_now
datetime.datetime(2022, 5, 20, 15, 50, 58, 525908, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))
>>> dt_now > dt
True
>>> dt_now - dt
datetime.timedelta(days=51, seconds=79282, microseconds=611491)

Converting string formatted ISO date to Epoch in Python

dateutil is your friend, also with 7 digits of fractional seconds:

from dateutil.parser import isoparse

isoparse("2021-12-14T12:05:51.8031499")
Out[2]: datetime.datetime(2021, 12, 14, 12, 5, 51, 803149)

isoparse("2021-12-14T12:05:51.8031499").timestamp()
Out[3]: 1639479951.803149

Note: given ISO format date/time will result in a naive datetime object, which Python will treat as local time, i.e. it will be converted from your machine's local time setting to UTC before Unix time is calculated for timestamp() !

How do I translate an ISO 8601 datetime string into a Python datetime object?

I prefer using the dateutil library for timezone handling and generally solid date parsing. If you were to get an ISO 8601 string like: 2010-05-08T23:41:54.000Z you'd have a fun time parsing that with strptime, especially if you didn't know up front whether or not the timezone was included. pyiso8601 has a couple of issues (check their tracker) that I ran into during my usage and it hasn't been updated in a few years. dateutil, by contrast, has been active and worked for me:

from dateutil import parser
yourdate = parser.parse(datestring)

How to plot hour:min time in ISO 8601 time format?

A few assumptions:

  • You mean hour:minutes and not hour:seconds as written. If differently, please clarify your point
  • The time string is wrong: according to ISO 8601 hours and minutes should be two-character string chunks. You have to first clean the string list. I've done it manually since a Python script for that is out-of-scope
  • I've used a slight different temp array just for displaying some variability in the graph. Completely negligible

That said, the proposed way is:

  • Convert the iso strings into timestamp (float) values. This will be handled by pyqtgraph to plot numbers.
  • Convert the full ISO strings into strings with format HH:MM as you require and that you'll use as axis ticks. You have two choices that are in-code explained (please, read comments)
  • Get the x-axis from the PlotWidget and use the setTick property to set your custom ticks. To do so, you have to create a list of tuple with two values, the underlying numeric data and the custom string data

Here is the code:

from datetime import datetime

from PySide6.QtWidgets import (
QApplication,
QMainWindow
)
import pyqtgraph as pg # import PyQtGraph after Qt

class MainWindow(QMainWindow):
def __init__(self):
super().__init__()

self.graphWidget = pg.PlotWidget()
self.setCentralWidget(self.graphWidget)

t_string_list = ['2021-12-11T06:15', '2021-12-11T07:15', '2021-12-11T08:15', '2021-12-11T09:15', '2021-12-11T10:15']

# Get the timestamp value. A numeric value is needed for the underlying x-axis data
t_time_value = [datetime.fromisoformat(t_string).timestamp() for t_string in t_string_list]

# Get the x-axis ticks string values as HH:MM. Two ways
# ---- straight and unsafe way - It only works if the ISO Format will end with minutes! [...THH:MM]
t_ticks_values = [val[-5:] for val in t_string_list]

# --- Safe and general way: create a datetime object from isoformat and then convert to string
t_ticks_values = [datetime.fromisoformat(val).strftime('%H:%M') for val in t_string_list]

temp = [33.6, 31.6, 35.6, 32.6, 37.6]

# plot data: time, temp values
self.graphWidget.plot(t_time_value, temp)

# Get the x-axis
x_axis = self.graphWidget.getAxis('bottom')
# Check https://stackoverflow.com/questions/31775468/show-string-values-on-x-axis-in-pyqtgraph
ticks = [list(zip(t_time_value, t_ticks_values))]
x_axis.setTicks(ticks)

# Always start by initializing Qt (only once per application)
app = QApplication([])
window = MainWindow()
## Display the widget as a new window
window.show()
## Start the Qt event loop
app.exec_()

And here is the result:

Sample Image

For more advanced strategies, such as sub-classing AxisItem for custom tickStrings generator, please refer to this answer

Edit 1: Ticks downsamples

Note that you can downsample the ticks tuple in order to show less major/minor (in the example major only are present) ticks.
As for instance, if you want to show one tick every 2 timestamps:

ticks = [list(zip(t_time_value, t_ticks_values))[::2]]

The result:

Sample Image

How to format time in ISO 8601 in Twilio API

How is this timestamp being generated? Are you hard-coding it? The syntax error you're seeing is Python being unable to understand what's in between the parentheses, it doesn't seem syntactically correct.

You could simply use the isoformat() method from Python's datetime library instead to convert a regular datetime object to ISO afterwards, example:

>>> import datetime
>>> x = datetime.datetime(2022, 2, 8, 17, 50)
>>> x.isoformat()
'2022-02-08T17:50:00'

Twilio's own docs directly suggest this pattern (see the "Send Scheduled SMS in Python" section):

message = client.messages.create(
from_=messaging_service_sid,
to='+1xxxxxxxxxx', # ← your phone number here
body='Friendly reminder that you have an appointment with us next week.',
schedule_type='fixed',
send_at=send_when.isoformat() + 'Z',
)

Looks like the only additional detail is appending that 'Z' at the end, which is the only difference between my first snippet and your original example. If there are different docs that you followed that you can share a link to, happy to give more specific advice.



Related Topics



Leave a reply



Submit