0

I have following datetimes:

a = "2018-07-13T00:00:00+00:00"
b = "2018-07-13T00:00:00.000000+00:00"

I want to check if a datetime has timespec='milliseconds'. So my function should return False for a and True for b Any ideas how to solve this?

sg_sg94
  • 2,248
  • 4
  • 28
  • 56
  • 1
    For start, these are not `datetime` objects, but strings. Second, do you expect different formats or they will be always in this format? – buran Sep 29 '21 at 09:53

2 Answers2

1

Assuming you have strings as in the question.

If you only have the two formats above, you could only check the length:

def has_ms(s):
    return len(s) == 32

You could also perform a complete match of the format in b:

def is_ms_strict_format(s):
    import re
    return bool(re.match(r'\d{4}-\d{2}-\d{2}T(\d{2}:){2}\d{2}\.\d{6}\+\d{2}:\d{2}', s))

examples:

>>> has_ms(a)
False
>>> has_ms(b)
True
>>> is_ms_strict_format(a)
False
>>> is_ms_strict_format(b)
True
mozway
  • 194,879
  • 13
  • 39
  • 75
0

Assuming you are dealing with datetime string in iso format

from datetime import datetime

def has_microseconds(dt):
    return not datetime.fromisoformat(dt).isoformat(timespec='seconds') == dt

a = "2018-07-13T00:00:00+00:00" # seconds
b = "2018-07-13T00:00:00.000000+00:00" # microseconds
c = "2018-07-13T00:00:00.000+00:00" # milliseconds

print(has_microseconds(a))
print(has_microseconds(b))
print(has_microseconds(c))

output

False
True
True

Note this will not work (needs refinement) if the string is in iso format, but has only hours [and minutes] but not seconds.

UPDATE: Here is function that will return exact timespec given iso-format string

from datetime import datetime

def get_timespec(dt):
    specs = ['hours', 'minutes', 'seconds', 'milliseconds', 'microseconds']
    for timespec in specs:
        if datetime.fromisoformat(dt).isoformat(timespec=timespec) == dt:
            return timespec

sample = ["2018-07-13T00+00:00", # hours
          "2018-07-13T00:00+00:00", # minutes
          "2018-07-13T00:00:00+00:00", # seconds
          "2018-07-13T00:00:00.000+00:00", # milliseconds
          "2018-07-13T00:00:00.000000+00:00"] # microseconds

for dt in sample:
    print(get_timespec(dt))

output

hours
minutes
seconds
milliseconds
microseconds
buran
  • 13,682
  • 10
  • 36
  • 61
  • I'd make a positive test: see if the input matches the out of .isoformat with times timespec set to microseconds. Of course this is all very specific to isoformat that Python uses (e.g. no Z for UTC). – FObersteiner Sep 29 '21 at 11:16
  • @MrFuppes, this was also my idea, but the problem is with milliseconds/microseconds - i.e. their example is with microseconds, while their question is about `timespec=milleseconds`. I will update my answer to return exact `timespec`, given iso-format string. – buran Sep 29 '21 at 11:35
  • hm maybe a pure string operation is more reliable here? e.g. split on the last `'.'`, remove UTC offset and check len? `len(re.split('\+|\-', s[::-1].split('.', 1)[0])[-1]) == 3` – FObersteiner Sep 29 '21 at 11:40
  • 1
    btw. related https://stackoverflow.com/q/69373627/10197418 - I wonder what this is *actually* about ^^ – FObersteiner Sep 29 '21 at 11:42
  • 1
    @MrFuppes, I missed that related question. It really makes this question look like XY problem. – buran Sep 29 '21 at 11:50
  • @MrFuppes, as to string operations - yes it's possible, but looks like a bit more messy/hackish - i.e. if string is not valid ISO format `datetime.fromisoformat()` will raise error, while split at right-most dot will fail with formats that has dots, e.g. YYYY.MM.DD, but without microseconds/milliseconds part. But we are speculating now about possible input formats, etc. – buran Sep 29 '21 at 11:55