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);
}
}
}