Package javax.time.calendar.format

Source Code of javax.time.calendar.format.ZoneOffsetPrinterParser

/*
* Copyright (c) 2008-2009, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  * Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*
*  * Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
*  * Neither the name of JSR-310 nor the names of its contributors
*    may be used to endorse or promote products derived from this software
*    without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javax.time.calendar.format;

import java.io.IOException;

import javax.time.calendar.Calendrical;
import javax.time.calendar.ZoneOffset;

/**
* Prints or parses a zone offset.
* <p>
* ZoneOffsetPrinterParser is immutable and thread-safe.
*
* @author Stephen Colebourne
*/
class ZoneOffsetPrinterParser implements DateTimePrinter, DateTimeParser {

    /**
     * The text to use for UTC.
     */
    private final String utcText;
    /**
     * Whether to include a colon.
     */
    private final boolean includeColon;
    /**
     * Whether to allow seconds.
     */
    private final boolean allowSeconds;

    /**
     * Constructor.
     *
     * @param utcText  the text to use for UTC, not null
     * @param includeColon  whether to include a colon
     * @param allowSeconds  whether to allow seconds
     */
    ZoneOffsetPrinterParser(String utcText, boolean includeColon, boolean allowSeconds) {
        // validated by caller
        this.utcText = utcText;
        this.includeColon = includeColon;
        this.allowSeconds = allowSeconds;
    }

    //-----------------------------------------------------------------------
    /** {@inheritDoc} */
    public void print(Calendrical calendrical, Appendable appendable, DateTimeFormatSymbols symbols) throws IOException {
        ZoneOffset offset = calendrical.getOffset();
        if (offset == null) {
            throw new CalendricalFormatException("Unable to print ZoneOffset");
        }
        int totalSecs = offset.getAmountSeconds();
        if (totalSecs == 0) {
            appendable.append(utcText);
        } else if (includeColon && (allowSeconds || offset.getSecondsField() == 0)) {
            appendable.append(offset.getID());
        } else {
            int absHours = Math.abs(offset.getHoursField());
            int absMinutes = Math.abs(offset.getMinutesField());
            int absSeconds = Math.abs(offset.getSecondsField());
            appendable
                .append(totalSecs < 0 ? "-" : "+")
                .append((char) (absHours / 10 + '0')).append((char) (absHours % 10 + '0'))
                .append(includeColon ? ":" : "")
                .append((char) (absMinutes / 10 + '0')).append((char) (absMinutes % 10 + '0'));
            if (allowSeconds && absSeconds > 0) {
                appendable
                    .append(includeColon ? ":" : "")
                    .append((char) (absSeconds / 10 + '0')).append((char) (absSeconds % 10 + '0'));
            }
        }
    }

    /** {@inheritDoc} */
    public boolean isPrintDataAvailable(Calendrical calendrical) {
        return (calendrical.getOffset() != null);
    }

    //-----------------------------------------------------------------------
    /** {@inheritDoc} */
    public int parse(DateTimeParseContext context, String parseText, int position) {
        ZoneOffset offset = null;
        int length = parseText.length();
        int utcLen = utcText.length();
        if (utcLen == 0) {
            if (position == length) {
                context.setOffset(ZoneOffset.UTC);
                return position;
            }
        } else {
            if (position == length) {
                return ~position;
            }
            if (parseText.regionMatches(false, position, utcText, 0, utcLen)) {
                context.setOffset(ZoneOffset.UTC);
                return position + utcLen;
            }
        }
       
        char sign = parseText.charAt(position)// IOOBE if invalid position
        if (sign == '+' || sign == '-') {
            int negative = (sign == '-' ? -1 : 1);
            int[] array = new int[4];
            array[0] = position + 1;
            if (parseNumber(array, 1, parseText, true) ||
                    parseNumber(array, 2, parseText, true) ||
                    parseNumber(array, 3, parseText, false)) {
                return ~position;
            }
            int total = (array[1] * 60 * 60) + (array[2] * 60) + array[3];
            if (total > 18 * 60 * 60) {  // max +18:00:00
                return ~position;
            }
            offset = ZoneOffset.zoneOffset(negative * array[1], negative * array[2], negative * array[3]);
            context.setOffset(offset);
            return array[0];
        } else {
            if (utcLen == 0) {
                context.setOffset(ZoneOffset.UTC);
                return position + utcLen;
            }
            return ~position;
        }
    }

    /**
     * Parse a two digit zero-prefixed number.
     *
     * @param array  the array of parsed data, 0=pos,1=hours,2=mins,3=secs, not null
     * @param arrayIndex  the index to parse the value into
     * @param parseText  the offset id, not null
     * @param required  whether this number is required
     * @return true if an error occurred
     */
    private boolean parseNumber(int[] array, int arrayIndex, String parseText, boolean required) {
        if (allowSeconds == false && arrayIndex == 3) {
            return false// ignore seconds
        }
        int pos = array[0];
        if (includeColon && arrayIndex > 1) {
            if (pos + 1 > parseText.length() || parseText.charAt(pos) != ':') {
                return required;
            }
            pos++;
        }
        if (pos + 2 > parseText.length()) {
            return required;
        }
        char ch1 = parseText.charAt(pos++);
        char ch2 = parseText.charAt(pos++);
        if (ch1 < '0' || ch1 > '9' || ch2 < '0' || ch2 > '9') {
            return required;
        }
        int value = (ch1 - 48) * 10 + (ch2 - 48);
        if (value < 0 || value > 59) {
            return required;
        }
        array[arrayIndex] = value;
        array[0] = pos;
        return false;
    }

//            try {
//                if (includeColon) {
//                    offset = ZoneOffset.zoneOffset(parseText.substring(position, position + 6));
//                    endPos += 6;
//                } else {
//                    offset = ZoneOffset.zoneOffset(parseText.substring(position, position + 5));
//                    endPos += 5;
//                }
//            } catch (Exception ex) {
//                return ~position;
//            }
//            try {
//                if (includeColon) {
//                    offset = ZoneOffset.zoneOffset(parseText.substring(position, position + 9));
//                    endPos += 3;
//                } else {
//                    offset = ZoneOffset.zoneOffset(parseText.substring(position, position + 7));
//                    endPos += 2;
//                }
//            } catch (Exception ex) {
//                // ignore
//            }

    //-----------------------------------------------------------------------
    /** {@inheritDoc} */
    @Override
    public String toString() {
        if (utcText.equals("Z") && includeColon && allowSeconds) {
            return "OffsetId()";
        }
        String converted = utcText.replace("'", "''");
        return "Offset('" + converted + "'," + includeColon + "," + allowSeconds + ")";
    }

}
TOP

Related Classes of javax.time.calendar.format.ZoneOffsetPrinterParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.