/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "utc-offset.h"
#include "utc-mktime.h"
#include "iso8601-date.h"
#include <ctype.h>
date-fullyear = 4DIGIT
date-month = 2DIGIT ; 01-12
date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
time-hour = 2DIGIT ; 00-23
time-minute = 2DIGIT ; 00-59
time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
; rules
time-secfrac = "." 1*DIGIT
time-numoffset = ("+" / "-") time-hour ":" time-minute
time-offset = "Z" / time-numoffset
partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
full-date = date-fullyear "-" date-month "-" date-mday
full-time = partial-time time-offset
date-time = full-date "T" full-time
*/
struct iso8601_date_parser {
int timezone_offset;
};
static inline int
{
int i;
return 0;
for (i=0; i < digits-1; i++) {
return -1;
}
return 1;
}
static int
{
/* time-secfrac = "." 1*DIGIT
NOTE: Currently not applied anywhere, so fraction is just skipped.
*/
/* "." */
return 0;
/* 1DIGIT */
return -1;
/* *DIGIT */
return 1;
}
{
/* time-offset = "Z" / time-numoffset
time-numoffset = ("+" / "-") time-hour ":" time-minute
time-hour = 2DIGIT ; 00-23
time-minute = 2DIGIT ; 00-59
*/
return 0;
/* time-offset = "Z" / time-numoffset */
case '-':
tz_sign = -1;
/* fall through */
case '+':
/* time-hour = 2DIGIT */
return -1;
if (tz_hour > 23)
return -1;
/* ":" */
return -1;
/* time-minute = 2DIGIT */
return -1;
if (tz_min > 59)
return -1;
break;
case 'Z':
case 'z':
break;
default:
return -1;
}
return 1;
}
{
/* full-time = partial-time time-offset
partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
time-hour = 2DIGIT ; 00-23
time-minute = 2DIGIT ; 00-59
time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
; rules
*/
/* time-hour = 2DIGIT */
return -1;
/* ":" */
return -1;
/* time-minute = 2DIGIT */
return -1;
/* ":" */
return -1;
/* time-second = 2DIGIT */
return -1;
/* [time-secfrac] */
if (iso8601_date_parse_secfrac(parser) < 0)
return -1;
/* time-offset */
if (is08601_date_parse_time_offset(parser) <= 0)
return -1;
return 1;
}
{
/* full-date = date-fullyear "-" date-month "-" date-mday
date-fullyear = 4DIGIT
date-month = 2DIGIT ; 01-12
date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
*/
/* date-fullyear = 4DIGIT */
return -1;
return -1;
/* "-" */
return -1;
/* date-month = 2DIGIT */
return -1;
/* "-" */
return -1;
/* time-second = 2DIGIT */
return -1;
return 1;
}
{
/* date-time = full-date "T" full-time */
/* full-date */
if (is08601_date_parse_full_date(parser) <= 0)
return -1;
/* "T" */
return -1;
/* full-time */
if (is08601_date_parse_full_time(parser) <= 0)
return -1;
return -1;
return 1;
}
static bool
{
if (iso8601_date_parse_date_time(&parser) <= 0)
return FALSE;
return FALSE;
return TRUE;
}
{
}
{
}
{
const char *time_offset;
if (timezone_offset == INT_MAX)
time_offset = "Z";
else {
if (timezone_offset < 0) {
sign = '-';
}
timezone_offset / 60,
timezone_offset % 60);
}
return t_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02d%s",
}
{
int timezone_offset;
}