xref: /freebsd/contrib/ntp/sntp/libopts/parse-duration.h (revision a466cc55373fc3cf86837f09da729535b57e69a1)
12b15cb3dSCy Schubert /* Parse a time duration and return a seconds count
2*a466cc55SCy Schubert    Copyright (C) 2008-2018 Free Software Foundation, Inc.
32b15cb3dSCy Schubert    Written by Bruce Korb <bkorb@gnu.org>, 2008.
42b15cb3dSCy Schubert 
52b15cb3dSCy Schubert    This program is free software: you can redistribute it and/or modify
62b15cb3dSCy Schubert    it under the terms of the GNU Lesser General Public License as published by
72b15cb3dSCy Schubert    the Free Software Foundation; either version 2.1 of the License, or
82b15cb3dSCy Schubert    (at your option) any later version.
92b15cb3dSCy Schubert 
102b15cb3dSCy Schubert    This program is distributed in the hope that it will be useful,
112b15cb3dSCy Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
122b15cb3dSCy Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
132b15cb3dSCy Schubert    GNU Lesser General Public License for more details.
142b15cb3dSCy Schubert 
152b15cb3dSCy Schubert    You should have received a copy of the GNU Lesser General Public License
16*a466cc55SCy Schubert    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
172b15cb3dSCy Schubert 
182b15cb3dSCy Schubert /*
192b15cb3dSCy Schubert 
202b15cb3dSCy Schubert   Readers and users of this function are referred to the ISO-8601
212b15cb3dSCy Schubert   specification, with particular attention to "Durations".
222b15cb3dSCy Schubert 
232b15cb3dSCy Schubert   At the time of writing, this worked:
242b15cb3dSCy Schubert 
25*a466cc55SCy Schubert   https://en.wikipedia.org/wiki/ISO_8601#Durations
262b15cb3dSCy Schubert 
272b15cb3dSCy Schubert   The string must start with a 'P', 'T' or a digit.
282b15cb3dSCy Schubert 
292b15cb3dSCy Schubert   ==== if it is a digit
302b15cb3dSCy Schubert 
312b15cb3dSCy Schubert   the string may contain:  NNN Y NNN M NNN W NNN d NNN h NNN m NNN s
322b15cb3dSCy Schubert   This represents NNN years, NNN months, NNN weeks, NNN days, NNN hours,
332b15cb3dSCy Schubert     NNN minutes and NNN seconds.
342b15cb3dSCy Schubert   The embedded white space is optional.
352b15cb3dSCy Schubert   These terms must appear in this order.
362b15cb3dSCy Schubert   Case is significant:  'M' is months and 'm' is minutes.
372b15cb3dSCy Schubert   The final "s" is optional.
382b15cb3dSCy Schubert   All of the terms ("NNN" plus designator) are optional.
392b15cb3dSCy Schubert   Minutes and seconds may optionally be represented as NNN:NNN.
402b15cb3dSCy Schubert   Also, hours, minute and seconds may be represented as NNN:NNN:NNN.
412b15cb3dSCy Schubert   There is no limitation on the value of any of the terms, except
422b15cb3dSCy Schubert   that the final result must fit in a time_t value.
432b15cb3dSCy Schubert 
442b15cb3dSCy Schubert   ==== if it is a 'P' or 'T', please see ISO-8601 for a rigorous definition.
452b15cb3dSCy Schubert 
462b15cb3dSCy Schubert   The 'P' term may be followed by any of three formats:
472b15cb3dSCy Schubert     yyyymmdd
482b15cb3dSCy Schubert     yy-mm-dd
492b15cb3dSCy Schubert     yy Y mm M ww W dd D
502b15cb3dSCy Schubert 
512b15cb3dSCy Schubert   or it may be empty and followed by a 'T'.  The "yyyymmdd" must be eight
522b15cb3dSCy Schubert   digits long.
532b15cb3dSCy Schubert 
542b15cb3dSCy Schubert   NOTE!  Months are always 30 days and years are always 365 days long.
552b15cb3dSCy Schubert   5 years is always 1825 days, not 1826 or 1827 depending on leap year
562b15cb3dSCy Schubert   considerations.  3 months is always 90 days.  There is no consideration
572b15cb3dSCy Schubert   for how many days are in the current, next or previous months.
582b15cb3dSCy Schubert 
592b15cb3dSCy Schubert   For the final format:
602b15cb3dSCy Schubert   *  Embedded white space is allowed, but it is optional.
612b15cb3dSCy Schubert   *  All of the terms are optional.  Any or all-but-one may be omitted.
622b15cb3dSCy Schubert   *  The meanings are yy years, mm months, ww weeks and dd days.
632b15cb3dSCy Schubert   *  The terms must appear in this order.
642b15cb3dSCy Schubert 
652b15cb3dSCy Schubert   ==== The 'T' term may be followed by any of these formats:
662b15cb3dSCy Schubert 
672b15cb3dSCy Schubert     hhmmss
682b15cb3dSCy Schubert     hh:mm:ss
692b15cb3dSCy Schubert     hh H mm M ss S
702b15cb3dSCy Schubert 
712b15cb3dSCy Schubert   For the final format:
722b15cb3dSCy Schubert   *  Embedded white space is allowed, but it is optional.
732b15cb3dSCy Schubert   *  All of the terms are optional.  Any or all-but-one may be omitted.
742b15cb3dSCy Schubert   *  The terms must appear in this order.
752b15cb3dSCy Schubert 
762b15cb3dSCy Schubert  */
772b15cb3dSCy Schubert #ifndef GNULIB_PARSE_DURATION_H
782b15cb3dSCy Schubert #define GNULIB_PARSE_DURATION_H
792b15cb3dSCy Schubert 
802b15cb3dSCy Schubert #include <time.h>
812b15cb3dSCy Schubert 
822b15cb3dSCy Schubert /* Return value when a valid duration cannot be parsed.  */
832b15cb3dSCy Schubert #define BAD_TIME        ((time_t)~0)
842b15cb3dSCy Schubert 
852b15cb3dSCy Schubert /* Parses the given string.  If it has the syntax of a valid duration,
862b15cb3dSCy Schubert    this duration is returned.  Otherwise, the return value is BAD_TIME,
872b15cb3dSCy Schubert    and errno is set to either EINVAL (bad syntax) or ERANGE (out of range).  */
882b15cb3dSCy Schubert extern time_t parse_duration (char const * in_pz);
892b15cb3dSCy Schubert 
902b15cb3dSCy Schubert #endif /* GNULIB_PARSE_DURATION_H */
91