Parsing non-zero padded timestamps in Python - python

I want to get datetimes from timestamps like the following :3/1/2014 9:55 with datetime.strptime, or something equivalent.
The month, day of month, and hour is not zero padded, but there doesn't seem to be a formatting directive listed here that is able to parse this automatically.
What's the best approach to do so? Thanks!

strptime is able to parse non-padded values. The fact that they are noted as being padded in the formatting codes table applies to strftime's output. So you can just use
datetime.strptime(datestr, "%m/%d/%Y %H:%M")

strptime isdo not require 0-padded values. See example below
datetime.strptime("3/1/2014 9:55", "%m/%d/%Y %H:%M")
output: datetime.datetime(2014, 3, 1, 9, 55)

The non-pattern way is use dateutil.parse module, it lets to parse the common date formats, even if you don't know what it is using currently
Ex:
>>> import dateutil.parser
>>>
>>> utc_time = '2014-08-13T00:00:00'
>>> verbose_time = '13-Aug-2014'
>>> some_locale = '3/1/2014 9:55'
>>> dateutil.parser.parse(utc_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(verbose_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(some_locale)
datetime.datetime(2014, 3, 1, 9, 55)

Just in case this answer helps someone else -- I came here thinking I had a problem with zero padding, but it was actually to do with 12:00 vs 00:00 and the %I formatter.
The %I formatter is meant to match 12-hour-clock hours, optionally zero-padded. But depending on your data source, you might get data that says that midnight or midday is actually zero, eg:
>>> datetime.strptime('2015/01/01 0:12am', "%Y/%m/%d %I:%M%p")
ValueError: time data '2015/01/01 0:12am' does not match format '%Y/%m/%d %I:%M'
What strptime actually wanted was a 12, not a zero:
>>> datetime.strptime('2015/01/01 12:12am', "%Y/%m/%d %I:%M%p")
datetime.datetime(2015, 1, 1, 0, 12)
But we don't always control our data sources! My solution for this edge case was to catch the exception, try parsing it with a %H, with a quick check that we are in the edge case we think we are in.
def get_datetime(string):
try:
timestamp = datetime.strptime(string, "%m/%d/%Y %I:%M%p")
except ValueError:
# someone used zero for midnight?
timestamp = datetime.strptime(string, "%m/%d/%Y %H:%M%p")
assert string.lower().endswith('am')
assert timestamp.hour == 0
return timestamp

You can see the strftime document here,but in fact they aren't all working well in all platforms,for instance,%-d,%-m don't work on win7 by python 2.7,so you can accomplish like this
>>> date_str = '{d.year}-{d.month}-{d.day}'.format(d=datetime.datetime.now())
>>> print(date_str)
2016-5-23

Related

Identify Format of date in python

How do I get the date format for the given date input in python?
Note:
The input is given by the user which is not predefined format .They may
give any kind of input format ..
The below example is working for dd-mm-yyyy format .But this is not in
my case.Date format is not predefined.
datetime.datetime.strptime('24052010', "%d%m%Y").date()
Expected :
Input 1: 21–02–2019 ,Output: DD-MM-YYYY .
Input 2: 02/21/2019 ,Output : MM/DD/YYYY
I think such function cannot be done because some dates (for example 01/01/2019) cannot be interpreted in one way. This can be both MM/DD/YYYY and DD/MM/YYYY. So you can only check if the date is in such format or not (you can use the answers to this question: How do I validate a date string format in python?).
You can use the module dateutil. It has a robust parser that will try to make sense of any date.
>>> from dateutil import parser
>>> parser.parse("21-02-2019")
datetime.datetime(2019, 2, 21, 0, 0)
>>> parser.parse("02/21/2019")
datetime.datetime(2019, 2, 21, 0, 0)
This isn't exactly what you wanted: you get the date not the format. But if you have the date, do you really need the format?
To meet J Kluseczka's point about some dates being ambiguous (like "01/10/2019") you can specify your assumption:
>>> parser.parse("01/10/2019")
datetime.datetime(2019, 1, 10, 0, 0)
>>> parser.parse("01/10/2019",dayfirst=True)
datetime.datetime(2019, 10, 1, 0, 0)
dateutil isn't part of the standard library but it is well worth the trouble of downloading.

Get file modification date in MM-DD-YYYY format without time [duplicate]

I have a date string and want to convert it to the date type:
I have tried to use datetime.datetime.strptime with the format that I want but it is returning the time with the conversion.
when = alldates[int(daypos[0])]
print when, type(when)
then = datetime.datetime.strptime(when, '%Y-%m-%d')
print then, type(then)
This is what the output returns:
2013-05-07 <type 'str'>
2013-05-07 00:00:00 <type 'datetime.datetime'>
I need to remove the time: 00:00:00.
print then.date()
What you want is a datetime.date object. What you have is a datetime.datetime object. You can either change the object when you print as per above, or do the following when creating the object:
then = datetime.datetime.strptime(when, '%Y-%m-%d').date()
If you need the result to be timezone-aware, you can use the replace() method of datetime objects. This preserves timezone, so you can do
>>> from django.utils import timezone
>>> now = timezone.now()
>>> now
datetime.datetime(2018, 8, 30, 14, 15, 43, 726252, tzinfo=<UTC>)
>>> now.replace(hour=0, minute=0, second=0, microsecond=0)
datetime.datetime(2018, 8, 30, 0, 0, tzinfo=<UTC>)
Note that this returns a new datetime object -- now remains unchanged.
>>> print then.date(), type(then.date())
2013-05-07 <type 'datetime.date'>
To convert a string into a date, the easiest way AFAIK is the dateutil module:
import dateutil.parser
datetime_object = dateutil.parser.parse("2013-05-07")
It can also handle time zones:
print(dateutil.parser.parse("2013-05-07"))
>>> datetime.datetime(2013, 5, 7, 1, 12, 12, tzinfo=tzutc())
If you have a datetime object, say:
import pytz
import datetime
now = datetime.datetime.now(pytz.UTC)
and you want chop off the time part, then I think it is easier to construct a new object instead of "substracting the time part". It is shorter and more bullet proof:
date_part datetime.datetime(now.year, now.month, now.day, tzinfo=now.tzinfo)
It also keeps the time zone information, it is easier to read and understand than a timedelta substraction, and you also have the option to give a different time zone in the same step (which makes sense, since you will have zero time part anyway).
For me, I needed to KEEP a timetime object because I was using UTC and it's a bit of a pain. So, this is what I ended up doing:
date = datetime.datetime.utcnow()
start_of_day = date - datetime.timedelta(
hours=date.hour,
minutes=date.minute,
seconds=date.second,
microseconds=date.microsecond
)
end_of_day = start_of_day + datetime.timedelta(
hours=23,
minutes=59,
seconds=59
)
Example output:
>>> date
datetime.datetime(2016, 10, 14, 17, 21, 5, 511600)
>>> start_of_day
datetime.datetime(2016, 10, 14, 0, 0)
>>> end_of_day
datetime.datetime(2016, 10, 14, 23, 59, 59)
If you specifically want a datetime and not a date but want the time zero'd out you could combine date with datetime.min.time()
Example:
datetime.datetime.combine(datetime.datetime.today().date(),
datetime.datetime.min.time())
You can use simply pd.to_datetime(then) and pandas will convert the date elements into ISO date format- [YYYY-MM-DD].
You can pass this as map/apply to use it in a dataframe/series too.
You can usee the following code:
week_start = str(datetime.today() - timedelta(days=datetime.today().weekday() % 7)).split(' ')[0]

How to convert strings to TimeStamps for compare?

I have strings like:
first = '2018-09-16 15:00:00'
second = '1900-01-01 09:45:55.500597'
I want to compare them.
All methods I found like Convert string date to timestamp in Python requires to know the format of the string.
I don't know the format of the strings (see differences between first and second) all I know is that they can be converted to timestamps.
How can I convert them in order to compare them?
Edit:
The "largest" string that I can get is:
1900-01-01 09:45:55.500597
but I can also get:
1900-01-01
1900-01-01 09:45
1900-01-01 09:45:55
etc..
It's always YYYY-MM-DD HH-MM....
You can use pandas.to_datetime. It offers a lot of flexibility in the string timestamp format, and you can use it on single strings or list/series/tuples of timestamps.
>>> import pandas as pd
>>> day = pd.to_datetime('1900-01-01')
>>> minute = pd.to_datetime('1900-01-01 09:45')
>>> second = pd.to_datetime('1900-01-01 09:45:55')
>>> subsecond = pd.to_datetime('1900-01-01 09:45:55.500597')
>>> assert subsecond > second
>>> assert minute < second
>>> assert day < minute
You can use the dateutil module (pip install python-dateutil):
>>> from dateutil.parser import parse
>>> parse('2018-09-16 15:00:00')
datetime.datetime(2018, 9, 16, 15, 0)
>>> parse('1900-01-01 09:45:55.500597')
datetime.datetime(1900, 1, 1, 9, 45, 55, 500597)
From the list of its features:
Generic parsing of dates in almost any string format;
Once you have the datetime objects, you can compare them directly, there's no need to calculate the timestamps.

Convert the unicode to datetime format

A function returns date and time in unicode format.
u'2014-03-06T04:38:51Z'
I wish to convert this to date and time format and subtract it with current datetime to get the number of days in between.
Thanks in advance
Check string is unicode
>>> import types
>>> type(u'2014-03-06T04:38:51Z') is types.UnicodeType
True
Converting strings to datetime:
>>> import datetime
>>> datetime.datetime.strptime(u'2014-03-06T04:38:51Z', '%Y-%m-%dT%H:%M:%SZ')
datetime.datetime(2014, 3, 6, 4, 38, 51)
Subtract from today to
>>> import datetime
>>> today = datetime.datetime.today()
>>> yourdate = datetime.datetime.strptime(u'2014-03-06T04:38:51Z', '%Y-%m-%dT%H:%M:%SZ')
>>> difference = today - yourdate
print str(difference)
First you have to convert your string to a datetime.datetime object.
import datetime
then = datetime.datetime.strptime(u'2014-03-06T04:38:51Z', "%Y-%m-%dT%H:%M:%SZ")
then represents itself as datetime.datetime(2014, 3, 6, 4, 38, 51), which looks about right. Then you have to get today's date as a datetime.datetime.
now = datetime.datetime.now()
Finally subtract it from your date (or vice versa - the question didn't make it clear).delta is a datetime.timedelta object that stores increments in days, seconds and microseconds. The latter two are always positive, the first can be negative.
for delta in (now-then, then-now):
print(delta, "::", delta.days, delta.seconds, delta.microseconds)
This prints out:
-1 day, 20:18:14.250142 :: -1 73094 250142
3:41:45.749858 :: 0 13305 749858
Best try it with a few examples to convince yourself it's correct.

Best way to handle time from input

I'm trying to get a date and a hour from the user.
date = raw_input("enter date (example: 25/12/1990) ")
hour = raw_input("enter hour (example: 20:00) ")
That is how I have done that, but I think this is not a good way to implement it.
After the input I would like to compare the inputted time to the current time, and to other times.
I have planned to use the time module of python.
What would you suggest?
The above gives you a date as a string. You'll need to convert that string into a datetime object, and handle any errors which arise. If you restrict your users to simple dates then you can do everything with the datetime module, like this:
>>> import datetime
>>> date = "15/03/2012"
>>> datetime.datetime.strptime(date, "%d/%m/%Y")
datetime.datetime(2012, 3, 15, 0, 0)
>>> hour = "13:01"
>>> datetime.datetime.strptime(hour, "%H:%M")
datetime.datetime(1900, 1, 1, 13, 1)
>>> datetime.datetime.strptime(date + " " + hour, "%d/%m/%Y %H:%M")
datetime.datetime(2012, 3, 15, 13, 1)
>>> date = "1/4/2012"
>>> hour = "3:01"
>>> datetime.datetime.strptime(date + " " + hour, "%d/%m/%Y %H:%M")
datetime.datetime(2012, 4, 1, 3, 1)
You can use other datetime module code to do things like get the current date and time, or to find difference between two dates or times.
One of the best solutions I've ever seen — dateutil package, they have parser module with parse() function, trying to extract date/time from strings. Look examples here.

Categories

Resources