/*
 *  eXist Open Source Native XML Database
 *  Copyright (C) 2014 The eXist Project
 *  http://exist-db.org
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  $Id$
 */
package org.exist.indexing.range.conversion;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongField;
import org.exist.indexing.range.RangeIndexConfigElement;
import org.exist.xquery.XPathException;
import org.exist.xquery.value.DateValue;
import org.exist.xquery.value.TimeUtils;

import javax.xml.datatype.XMLGregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Simple normalization of dates: if there is only a year, transform it into a date: yyy-01-01.
 * If full date is given, but with missing digits: fill them in.
 */
public class DateConverter implements TypeConverter {

    protected static final Logger LOG = LogManager.getLogger(DateConverter.class);

    private final static Pattern DATE_REGEX = Pattern.compile("(\\d+)-(\\d+)-(\\d+)");

    @Override
    public Field toField(String fieldName, String content) {
        try {
            DateValue dv;
            if (content.indexOf('-') < 0) {
                // just year
                int year = Integer.parseInt(content);
                XMLGregorianCalendar calendar = TimeUtils.getInstance().newXMLGregorianCalendar();
                calendar.setYear(year);
                calendar.setDay(1);
                calendar.setMonth(1);
                dv = new DateValue(calendar);
            } else {
                // try to handle missing digits as in 1980-8-4
                Matcher matcher = DATE_REGEX.matcher(content);
                if (matcher.matches()) {
                    try {
                        content = String.format("%04d-%02d-%02d", Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3)));
                    } catch (NumberFormatException e) {
                        // invalid content: ignore
                    }
                }
                dv = new DateValue(content);
            }
            final long dl = RangeIndexConfigElement.dateToLong(dv);
            return new LongField(fieldName, dl, LongField.TYPE_NOT_STORED);
        } catch (XPathException e) {
            // wrong type: ignore
            LOG.debug("Invalid date format: " + content, e);
        } catch (NumberFormatException e) {
            // wrong type: ignore
            LOG.debug("Invalid date format: " + content, e);
        } catch (Exception e) {
            LOG.debug("Invalid date format: " + content, e);
        }
        return null;
    }
}

@@ -1749,16 +1749,18 @@
 mpile(%22(
+-?
 %5C%5Cd+)-(%5C
@@ -1929,17 +1929,17 @@
 ('-') %3C 
-0
+1
 ) %7B%0A    
@@ -2518,83 +2518,158 @@
     
-content = String.format(%22%2504d-%2502d-%2502d%22, Integer.parseInt(matcher.group(1)
+int year = Integer.parseInt(matcher.group(1));%0A                        content = (year %3C 0 ? %22-%22 : %22%22) + String.format(%22%2504d-%2502d-%2502d%22, Math.abs(year
 ), I

fix range index DateConverter for dates BC