简体   繁体   中英

How to parse time string without date and date string without time?

Is there any way to automatically parse strings with time only to datetime.time object (or something similar)? Same for datetime.date .

I've tried dateutil , arrow , moment , pandas.to_datetime . All these parsers create timestamps with a current date.

>>> from dateutil.parser import parse
>>> parse('23:53')
datetime.datetime(2019, 1, 8, 23, 53)  # datetime.time(23, 53) expected
>>> parse('2018-01-04')
datetime.datetime(2018, 1, 4, 0, 0)  # datetime.date(2018, 1, 4) expected

UPD:

Thanks for the responses. Think that I should clarify the problem.

The program doesn't know what will be in the input ( timestamp , date or time ), and it should decide to set appropriate type. The problem is to distinguish these types.

For example, I can parse 23:53 and get a timestamp. How can I decide to extract the time from it or not?

You can use fromisoformat() from datetime .

import datetime
datetime.time.fromisoformat('23:53')
datetime.date.fromisoformat('2018-01-04')

What you basically want is for '23:53' to become a datetime.time object and for '2018-01-04' to become a datetime.date object. This cannot be achieved by using dateutil.parser.parse() :

Returns a datetime.datetime object or, if the fuzzy_with_tokens option is True , returns a tuple, the first element being a datetime.datetime object, the second a tuple containing the fuzzy tokens.

From the documentation . So you'll always get a datetime.datetime object when using dateutil.parser.parse()

I would guess you need to interpret the input string yourself to define wether you're trying to parse a time or a date. When you do that, you can still use the dateutil.parser.parse() function to get the object you want:

from dateutil.parser import parse
my_time = parse('23:53')
my_time.time()  # datetime.time(23, 53)
my_time.date()  # datetime.date(2019, 1, 8)

Here you have an example. Just set the date attributes with replace, and select the output with strftime.

import datetime
date = datetime.datetime.now()
newdate = date.replace(hour=11, minute=59)
print(newdate.strftime('%H:%M'))
newdate2 = date.replace(year=2014, month=1, day=3)
print(newdate2.strftime('%Y-%m-%d'))

You can use either time or datetime modules, but one thing to bear in mind, is that these always create an object, that specifies a moment in time. (Also, if parsing strings, consider using the strptime function and displaying as string, strftime function respectively)

eg

>>> hours = time.strptime("23:59", "%H:%M")
>>> days = time.strptime("2018-01-04", "%Y-%m-%d")
>>> time.strftime("%H:%M", hours)
'23:59'
>>> time.strftime("%H:%M %Y", hours)
'23:59 1900'

Not recommended, but if you wish to separate these two object for some reason and wish to only care for a specific portion of your assignement, you can still adress the respective numbers with

>>> hours.tm_hour
23
>>> hours.tm_min
59

>>> days.tm_mon
1
>>> days.tm_mday
4
>>> days.tm_year
2018

A far better approach, in my opinion would be formatting the complete date string and using the strptime to form a complete timestamp - even if you get the time and date as separate inputs:

>>> ttime = "22:45" 
>>> dday = "2018-01-04"

You can use the % formatter, or the "new" python f-Strings

>>> complete_t_string = "{} {}".format(dday, ttime)
>>> complete_t_string
'2018-01-04 22:45'

Now that we have a complete string, we can specify how it should be read and create a complete timestamp:

>>> complete_time = time.strptime(complete_t_string, "%Y-%m-%d %H:%M")
>>> complete_time
time.struct_time(tm_year=2018, tm_mon=1, tm_mday=4, tm_hour=22, tm_min=45, tm_sec=0, tm_wday=3, tm_yday=4, tm_isdst=-1)

EDIT: Somebody will probably kill me, but if you absolutely know that you will only get two types of values, you could just do a simple try / except construct. It can probably be written more Pythonically:

try:
    time.strptime(t_string, "%H:%M")
except ValueError:
    time.strptime(t_string, "%Y-%m-%d")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM