public void printDateTime()

in asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java [989:1293]


    public void printDateTime(long chronon, byte[] format, int formatStart, int formatLength, Appendable appender,
            DateTimeParseMode parseMode) throws HyracksDataException {
        int year = CAL.getYear(chronon);
        int month = CAL.getMonthOfYear(chronon, year);
        int day = CAL.getDayOfMonthYear(chronon, year, month);
        int dayOfYear = CAL.getDayOfYear(chronon, year);
        int dayOfWeek = CAL.getDayOfWeek(chronon);
        int hour = CAL.getHourOfDay(chronon);
        int min = CAL.getMinOfHour(chronon);
        int sec = CAL.getSecOfMin(chronon);
        int ms = CAL.getMillisOfSec(chronon);

        int formatCharCopies;

        int formatPointer = 0;

        char separatorChar = '\0';

        DateTimeProcessState processState;

        int pointerMove;

        boolean usePM = false;
        if (indexOf(format, formatStart, formatLength, 'a') >= 0) {
            if (hour >= 12) {
                usePM = true;
                hour -= 12;
            }
            if (hour == 0) {
                hour = 12;
            }
        }

        while (formatPointer < formatLength) {

            formatCharCopies = 0;

            switch (format[formatStart + formatPointer]) {
                case YEAR_CHAR:
                    processState = DateTimeProcessState.YEAR;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, YEAR_CHAR,
                            MAX_YEAR_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case QUARTER_CHAR:
                    processState = DateTimeProcessState.QUARTER;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, QUARTER_CHAR,
                            MAX_QUARTER_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case MONTH_CHAR:
                    processState = DateTimeProcessState.MONTH;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MONTH_CHAR,
                            MAX_MONTH_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case DAY_CHAR:
                    processState = DateTimeProcessState.DAY;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, DAY_CHAR,
                            MAX_DAY_CHARS_PRINT);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case WEEKDAY_CHAR:
                    processState = DateTimeProcessState.WEEKDAY;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, WEEKDAY_CHAR,
                            MAX_WEEKDAY_CHAR);
                    if (pointerMove < MIN_WEEKDAY_CHAR) {
                        throw new AsterixTemporalTypeParseException(
                                String.format("Expected at least %d '%s' characters but got %d", MIN_WEEKDAY_CHAR,
                                        WEEKDAY_CHAR, pointerMove));
                    }
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case HOUR_CHAR:
                    processState = DateTimeProcessState.HOUR;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, HOUR_CHAR,
                            MAX_HOUR_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case MINUTE_CHAR:
                    processState = DateTimeProcessState.MINUTE;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MINUTE_CHAR,
                            MAX_MINUTE_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case SECOND_CHAR:
                    processState = DateTimeProcessState.SECOND;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, SECOND_CHAR,
                            MAX_SECOND_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case MILLISECOND_CHAR:
                    processState = DateTimeProcessState.MILLISECOND;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MILLISECOND_CHAR,
                            MAX_MILLISECOND_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case MILLISECOND_CHAR_ALT:
                    processState = DateTimeProcessState.MILLISECOND;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer,
                            MILLISECOND_CHAR_ALT, MAX_MILLISECOND_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;
                case AMPM_CHAR:
                    processState = DateTimeProcessState.AMPM;
                    pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, AMPM_CHAR,
                            MAX_AMPM_CHARS);
                    formatPointer += pointerMove;
                    formatCharCopies += pointerMove;
                    break;

                case ' ':
                case HYPHEN_CHAR:
                case COLON_CHAR:
                case SOLIDUS_CHAR:
                case PERIOD_CHAR:
                case COMMA_CHAR:
                case T_CHAR:
                    // separator
                    separatorChar = (char) format[formatStart + formatPointer];
                    processState = DateTimeProcessState.SEPARATOR;
                    formatPointer++;
                    formatCharCopies++;
                    while (formatPointer < formatLength
                            && format[formatStart + formatPointer] == (byte) separatorChar) {
                        formatPointer++;
                        formatCharCopies++;
                    }
                    break;

                default:
                    throw new HyracksDataException("Unexpected format string at " + (formatStart + formatPointer) + ": "
                            + (char) (format[formatStart + formatPointer]));
            }

            // check whether the process state is valid for the parse mode

            switch (processState) {
                case YEAR:
                case QUARTER:
                case MONTH:
                case DAY:
                case WEEKDAY:
                    if (parseMode == DateTimeParseMode.TIME_ONLY) {
                        throw new HyracksDataException("Unexpected date format string when parsing a time value");
                    }
                    break;
                case HOUR:
                case MINUTE:
                case SECOND:
                case MILLISECOND:
                case AMPM:
                    if (parseMode == DateTimeParseMode.DATE_ONLY) {
                        throw new HyracksDataException("Unexpected time format string when parsing a date value");
                    }
                    break;
                default:
                    // do nothing
            }

            try {
                switch (processState) {
                    case YEAR:
                        if (year < 0) {
                            appender.append('-');
                            year *= -1;
                        }
                    case QUARTER:
                    case MONTH:
                        if (processState == DateTimeProcessState.MONTH && formatCharCopies >= 3) {
                            byte[][] monthNames = formatCharCopies > 3 ? MONTH_FULL_NAMES : MONTH_NAMES;
                            for (byte b : monthNames[month - 1]) {
                                appender.append((char) toUpper(b));
                            }
                            break;
                        }
                    case DAY:
                        int val;
                        if (processState == DateTimeProcessState.YEAR) {
                            val = year;
                        } else if (processState == DateTimeProcessState.QUARTER) {
                            val = ((month - 1) / 3) + 1;
                        } else if (processState == DateTimeProcessState.MONTH) {
                            val = month;
                        } else {
                            val = formatCharCopies == 3 ? dayOfYear : day;
                        }
                        String strVal = String.valueOf(val);
                        int valFieldCount = strVal.length();
                        for (int i = 0; i < formatCharCopies - valFieldCount; i++) {
                            appender.append('0');
                        }
                        appender.append(strVal);
                        break;
                    case WEEKDAY:
                        byte[][] weekdayNames = formatCharCopies == 3 ? WEEKDAY_NAMES : WEEKDAY_FULL_NAMES;
                        byte[] weekday = weekdayNames[dayOfWeek];
                        for (int i = 0; i < weekday.length; i++) {
                            byte b = weekday[i];
                            appender.append((char) (i == 0 ? toUpper(b) : b));
                        }
                        break;
                    case HOUR:
                    case MINUTE:
                    case SECOND:
                        val = 0;
                        if (processState == DateTimeProcessState.HOUR) {
                            val = hour;
                        } else if (processState == DateTimeProcessState.MINUTE) {
                            val = min;
                        } else if (processState == DateTimeProcessState.SECOND) {
                            val = sec;
                        }

                        if (val < 10) {
                            for (int i = 0; i < formatCharCopies - 1; i++) {
                                appender.append('0');
                            }
                        }
                        appender.append(String.valueOf(val));
                        break;
                    case MILLISECOND:
                        String strMS = String.valueOf(ms);
                        int msFieldCount = strMS.length();
                        for (int i = 0; i < 3 - msFieldCount; i++) {
                            appender.append('0');
                        }
                        if (formatCharCopies < 3) {

                            if (formatCharCopies == 1) {
                                if (ms % 100 == 0) {
                                    // the tailing two zeros can be removed
                                    ms = ms / 100;
                                } else if (ms % 10 == 0) {
                                    // the tailing one zero can be removed
                                    ms = ms / 10;
                                }
                            } else {
                                if (ms % 10 == 0) {
                                    // the tailing one zero can be removed
                                    ms = ms / 10;
                                }
                            }
                            appender.append(String.valueOf(ms));
                        } else {
                            appender.append(strMS);
                        }
                        break;
                    /* TODO: enable when we support "datetime with timezone" datatype
                    case TIMEZONE:
                        if (timezone == 0) {
                            appender.append('Z');
                            break;
                        }
                        if (timezone < 0) {
                            appender.append('-');
                            timezone *= -1;
                        }
                        int timezoneField = (int) (timezone / GregorianCalendarSystem.CHRONON_OF_HOUR);
                        if (timezoneField < 10) {
                            appender.append('0');
                        }
                        appender.append(String.valueOf(timezoneField));
                        timezoneField = (int) (timezone % GregorianCalendarSystem.CHRONON_OF_HOUR
                                / GregorianCalendarSystem.CHRONON_OF_MINUTE);
                        if (timezoneField < 10) {
                            appender.append('0');
                        }
                        appender.append(String.valueOf(timezoneField));
                        break;
                     */
                    case AMPM:
                        if (usePM) {
                            appender.append("PM");
                        } else {
                            appender.append("AM");
                        }
                        break;
                    case SEPARATOR:
                        if (separatorChar == '\0') {
                            throw new HyracksDataException(
                                    "Incorrect separator: separator char is not initialized properly!");
                        }
                        for (int i = 0; i < formatCharCopies; i++) {
                            appender.append(separatorChar);
                        }
                        break;
                    default:
                        throw new HyracksDataException("Unexpected time state when printing a date value");
                }
            } catch (IOException ex) {
                throw HyracksDataException.create(ex);
            }
        }
    }