Parse datetime operations.

    A datetime operation can one of the following:

     * single value: start_date:2014-10-10, start_date:>2014-10-10, start_date:>=2014-10-10
     * negation single value: start_date:~2014-10-10
     * interval: start_date:2010-10-10 10:10 .. 2012-10-10
     * negation interval: start_date:~2010-10-10 10:10 .. 2012-10-10

    This parser does not allow `|`

def parse_datetime_operation(operation: str) -> 'QueryOpSpec':
    """Parse datetime operations.

    A datetime operation can one of the following:

     * single value: start_date:2014-10-10, start_date:>2014-10-10, start_date:>=2014-10-10
     * negation single value: start_date:~2014-10-10
     * interval: start_date:2010-10-10 10:10 .. 2012-10-10
     * negation interval: start_date:~2010-10-10 10:10 .. 2012-10-10

    This parser does not allow `|`
    """
    _operation = operation.strip()
    if not _operation:
        raise QueryParserException('Operation is not valid: {}'.format(operation))
    # Check not allowed ops
    if '|' in _operation:
        raise QueryParserException('`|` is not allowed for datetime operations. '
                                   'Operation: {}'.format(operation))

    # Check negation
    negation, _operation = parse_negation_operation(_operation)

    # Check range operator
    if '..' in _operation:
        op = '..'
        params = _operation.split('..')
        params = [param.strip() for param in params if param]
        if len(params) != 2:
            raise QueryParserException('Expression is not valid, ranges requires only 2 params, '
                                       'Operation: {}'.format(operation))
        return QueryOpSpec(op, negation, params)

    # Check comparison operators
    op, _operation = parse_comparison_operation(_operation)
    if not op:
        # Now the operation must be an equality param param
        op = '='

    if not _operation:
        raise QueryParserException('Expression is not valid, it must be formatted as '
                                   'name:operation, '
                                   'Operation: {}'.format(operation))
    return QueryOpSpec(op, negation, _operation)