How can the time zone be controlled when writing numpy datetime64 objects as an ISO 8601 string? Specifically, I would like the time zone to be "+0000", just like the input below. For this very simple example I just want it to print back the original string.
import numpy
print(numpy.datetime64('2014-03-07T17:52:00.000+0000'))
For me, it returns
2014-03-07T12:52:00.000-0500
I am using python 3.4, numpy 1.9.2, and windows.
This question is similar, but the first two answers don't actually answer the question and the third answer is specific to unix.
s = '2014-03-07T17:52:00.000+0000'
print(numpy.datetime64(s).item().replace(tzinfo=pytz.UTC).isoformat('T'))
Thanks to ShadowRanger for getting me going in the right direction. item gets naive datetime from datetime64, then replace time zone with UTC since I know that's what it is in this case, then get it in ISO format with the 'T' separator.
This should work:
import numpy, time, os
os.environ['TZ'] = 'GMT'
time.tzset()
print(numpy.datetime64('2014-03-07T17:52:00.000+0000'))
based on this stackoverflow answer:
https://stackoverflow.com/a/32764078/5915424
Related
Python methods to convert ISO 8601 time format to UNIX timestamp (epoch) and back again without losing fractional seconds?
I found several examples, but all the examples seem to drop the fractional seconds at some point in the conversion. Example below...
The issue seems to be the initial conversion to UNIX timestamp (epoch). Code below.
def ISO8601ToEpoch(theString):
from datetime import datetime
import calendar
return calendar.timegm(datetime.strptime(theString, "%Y-%m-%dT%H:%M:%S.%f").timetuple())
def EpochToISO8601(theEpoch):
from datetime import datetime
return datetime.fromtimestamp(theEpoch).isoformat()
#
print 'Original Time {0}'.format('2018-04-27T04:19:51.050937')
theTime=ISO8601ToEpoch('2018-04-27T04:19:51.050937')
print 'Time {0}'.format(theTime)
print 'Original Time {0}'.format(EpochToISO8601(theTime)
This results as...
Original Time 2018-04-27T04:19:51.050937
Time 1524802791
Original Time 2018-04-27T04:19:51
Is there a way to get timetuple to not hack the fractional seconds?
The problem here is that you're converting a datetime—which understands microseconds—into a timetuple—which doesn't.1
The obvious fix is just to not do that.
If you want to convert a datetime object to a timestamp, just use the timestamp method, the same way you already use the fromtimestamp classmethod to go the other way.
1. You might be able to trick a timetuple into holding a float instead of an int for seconds. But then you'd be breaking the invariants of the type. And, more importantly, defeating the entire purpose of the type, which is to be identical to a 1980s-style C struct tm. And likely also breaking the timegm function, which probably just calls the C function of the same name. (Most of the time module is a thin wrapper around C's <time.h>, as opposed to datetime, which is a friendly module designed for Python.) And then timegm is documented to return an integral type, so even if you got that far, it would all be for nothing.
I think this is correct... but if not I am sure someone will point out what I missed.
>>> import datetime as datetime
>>> import dateutil.parser
>>> import time
# Create a sample UNIX timestamp...
>>> t=time.time()
>>> t
1478266530.573583
# Convert the time stamp sample to ISO format...
>>> i=datetime.datetime.utcfromtimestamp(t).isoformat()
>>> i
'2016-11-04T13:35:30.573583'
# Convert ISO format to UNIX time stamp...
>>> d=dateutil.parser.parse(i)
>>> d
datetime.datetime(2016, 11, 4, 13, 35, 30, 573583)
>>> s=(time.mktime(d.timetuple())*1e3+d.microsecond/1e3)/1e3
>>> s
1478266530.5735831
It is not a perfect conversion given the number of fractional digits of the resulting timestamp but close enough for my need. I am sure the ISO format is a point of debate, but the format matches the typical format I expect to encounter, this is of course the lack of the 'Z' qualifier.
I know that there have been similar questions asked, but they seemed to have to do with the way datetime deals (or doesn't deal) with timezones.
The setup is a little complicated, and probably not relevant to the problem, but I thought it was important to include the code as is, so a little background:
I've got a dictionary of arrays. Each of these arrays represents an "attempt" by the same person, but taking place at different times. Ultimately I'm going to be looking for the earliest of these dates. This may be a bit of a roundabout solution, but I'm converting all of the dates to datetime objects, finding the earliest and then just using that index to pull out the first attempt:
Here's what the code looks like to setup that array of attempt datetimes:
for key in duplicates_set.keys():
attempt_dates = [datetime.strptime(attempt['Attempt Date'], "%-m-%-d-%y %-H:%M:%S") for attempt in duplicates_set[key]]
Here's the format of what one of the original date strings looks like:
12-5-2016 3:27:58 PM
What I'm getting back is:
ValueError: '-' is a bad directive in format '%-m-%d-%y %-H:%M:%S'
I assume that's referring to the dashes placed before the 'm', 'd' and 'H' because they're non-zero-padded decimals. Why is it telling me that?
%-* -- to skip padding -- is a GNU libc extension. It's not part of POSIX strftime, and thus not guaranteed to be portable to systems where your time-formatting calls aren't eventually backed by GNU's strftime C library function.
The Python datetime module documentation explicitly specifies the format strings it supports, and this extension is not given. Thus, while this is supported in GNU date and GNU strftime(), it isn't available in Python datetime.
I had the same issue;
date: 1/9/21
according to:
https://strftime.org/ the correct format would've been "%-d/%-m/%y"
which gave the bad directive error.
"%d-/%m-/%y" didn't work either.
Weirdly enough what worked was "%d/%m/%y".
I want to turn '07/18/2013' to '07/2013' and there are a lot of these strings to be processed. What would be the most efficient way to do it?
I am thinking of using
''.join(['07/18/2013'[0:3],'07/18/2013'[6:]])
Look into strftime and strptime.
Assuming you start with the string s you can put it into a datetime object using strptime then take that back out into a string with only the necessary fields using strftime. I didn't actually run this code so I don't know if it is perfect, but the idea is here.
temp = datetime.strptime.(s, "%m/%D/%Y")
final = temp.strftime(%m/%Y")
You can find info on the datetime functions here https://docs.python.org/2/library/datetime.html
Use datetime module:
import datetime
print datetime.datetime.strptime("07/18/2013", '%m/%d/%Y').strftime('%m/%Y')
This question already has answers here:
Convert weird Python date format to readable date
(2 answers)
Closed 7 years ago.
I can't for the life of me figure out how to convert a timestamp on the form 1433140740000+0200 to a datetime object or to any humanly readable representation. Also, what format is this specifically? I'm assuming the +0200 represents a timezone.
I can only seem to find questions regarding timestamps without timezones, such as this answer, where int("1433140740000+0200") would give me an error. Any help is appreciated. Thanks!
Edit: As mentioned in a comment, further examination of the API from which I am getting these values reveals other timestamps with different values for what I thought to represent timezones. E.g: 315529200000+0100. The entire line of data looks like this: "ArrivalTime": "/Date(1433051640000+0200)/", and the full response can be found here.
Second edit: As far as I can tell, the timestamps are unix timestamps, but they're given in milliseconds (hence the trailing zeros), and the +0200 indicates timezone UTC+02:00. So for now, I'll just trim out the extra zeros and the timezone, and convert as shown in the linked question, before adding the timezone manually afterwards. The timestamps with +0100 remain a mystery to me, but I've found they're always the same date, 1/1/1980 12:00am. They also have a different identifier: ActualTime, as opposed to ArrivalTime on the others. Anyway, thanks for the help guys!
You can use string split to remove the timezone
import datetime
intstring = int( ('1433140740000+0200').split('+')[0])
print(
datetime.datetime.fromtimestamp(intstring/1000).strftime('%Y-%m-%d %H:%M:%S')
)
I had to change it to this to make it work
intstring /1000
I find myself needing to specify a timespan in a python configuration file a lot.
Is there a way that I can specify a more human readable timeframe (similar to PostgreSQL's Interval syntax) in a python configuration file with stdlib? Or will this require a 3rd party lib?
Clarification I'm not looking for anything in the ConfigParser.ConfigParser stdlib API specifically. I guess what I really need is a way to go from human readable date/time interval to datetime.timedelta value.
I found a good answer to this in an somewhat related question. Turns out the humanfriendly library does that fairly well:
In [1]: import humanfriendly
In [2]: humanfriendly.parse_timespan('1w')
Out[2]: 604800.0
That's in seconds. To get a timedelta object, you can simply load that:
In [3]: from datetime import timedelta
In [4]: timedelta(seconds=humanfriendly.parse_timespan('1w'))
Out[4]: datetime.timedelta(7)
Since humanfriendly also supports converting the other way, you can also do full round trip, which would look like:
In [5]: humanfriendly.format_timespan(timedelta(seconds=humanfriendly.parse_timespan('1w')).total_seconds())
Out[5]: '1 week'
Note how format_timespan does not access timedelta objects, unfortunately: only an integer (seconds).
I don't think there is a standard library module for that. I wrote one that does that. You can install it, or adapt it to your needs.
The module is called pycopia.timespec
It converts strings such as "1day 3min" to seconds, as a float. It's easy to get a datetime.timedelta from that.