-6

I need to check valid string to convert it in ISO8601.

Examples:

P2Y6M10D - True

P2Y10D - True

P15D - True

P2Y6MD - False

2Y6M10D - False

I can write the code using the "re" module. But I don't think that will work.

Cow
  • 2,543
  • 4
  • 13
  • 25
  • At least share the code you have tried with, then we can both better understand what it is you want to do and help you debug. – Cow May 12 '23 at 05:38
  • only ISO8601 _durations_? because the standard also contains date/time format, intervals, etc... – mrxra May 12 '23 at 05:51

2 Answers2

2

Instead of using a regex, you can use isodate module to parse durations:

# pip install isodate
from isodate import parse_duration, ISO8601Error

durations = ['P2Y6M10D', 'P2Y10D', 'P15D', 'P2Y6MD', '2Y6M10D']

for d in durations:
    try:
        td = isodate.parse_duration(d)
        print(f"'{d}' is {td}")
    except ISO8601Error:
        print(f"'{d}' is not a valid ISO 8601 duration.")

Output:

'P2Y6M10D' is 2 years, 6 months, 10 days, 0:00:00
'P2Y10D' is 2 years, 10 days, 0:00:00
'P15D' is 15 days, 0:00:00
'P2Y6MD' is not a valid ISO 8601 duration.
'2Y6M10D' is not a valid ISO 8601 duration.
Corralien
  • 109,409
  • 8
  • 28
  • 52
0

this regex should work - for durations only. if you need to validate/convert ISO8601 in general I'd try to find a library that does that for you (e.g. for date/time see How do I parse an ISO 8601-formatted date?)

import re

for val, expected in {
    'P2Y6M10D': True,
    'P2Y10D': True,
    'P15D': True,
    'P2Y6MD': False,
    '2Y6M10D': False,
}.items():
    if re.match(r'^P(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$', val):
        print(f"{val} -> True {'' if expected else '(expected: False)'}")
    else:
        print(f"{val} -> False {'(expected: True)' if expected else ''}")

output:

P2Y6M10D -> True 
P2Y10D -> True 
P15D -> True 
P2Y6MD -> False 
2Y6M10D -> False 
mrxra
  • 852
  • 1
  • 6
  • 9