imay commented on a change in pull request #1644: Refactor DateLiteral class in 
FE
URL: https://github.com/apache/incubator-doris/pull/1644#discussion_r317677438
 
 

 ##########
 File path: fe/src/main/java/org/apache/doris/rewrite/FEFunctions.java
 ##########
 @@ -92,415 +89,67 @@ public static DateLiteral daysAdd(LiteralExpr date, 
LiteralExpr day) throws Anal
 
     @FEFunction(name = "date_format", argTypes = { "DATETIME", "VARCHAR" }, 
returnType = "VARCHAR")
     public static StringLiteral dateFormat(LiteralExpr date, StringLiteral 
fmtLiteral) throws AnalysisException {
-        String result = dateFormat(new Date(getTime(date)), 
fmtLiteral.getStringValue());
+        String result = ((DateLiteral) 
date).dateFormat(fmtLiteral.getStringValue());
         return new StringLiteral(result);
     }
 
     @FEFunction(name = "str_to_date", argTypes = { "VARCHAR", "VARCHAR" }, 
returnType = "DATETIME")
     public static DateLiteral dateParse(StringLiteral date, StringLiteral 
fmtLiteral) throws AnalysisException {
-        boolean hasTimePart = false;
-        DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
-
-        String formatString = fmtLiteral.getStringValue();
-        boolean escaped = false;
-        for (int i = 0; i < formatString.length(); i++) {
-            char character = formatString.charAt(i);
-
-            if (escaped) {
-                switch (character) {
-                    case 'a': // %a Abbreviated weekday name (Sun..Sat)
-                        builder.appendDayOfWeekShortText();
-                        break;
-                    case 'b': // %b Abbreviated month name (Jan..Dec)
-                        builder.appendMonthOfYearShortText();
-                        break;
-                    case 'c': // %c Month, numeric (0..12)
-                        builder.appendMonthOfYear(1);
-                        break;
-                    case 'd': // %d Day of the month, numeric (00..31)
-                        builder.appendDayOfMonth(2);
-                        break;
-                    case 'e': // %e Day of the month, numeric (0..31)
-                        builder.appendDayOfMonth(1);
-                        break;
-                    case 'H': // %H Hour (00..23)
-                        builder.appendHourOfDay(2);
-                        hasTimePart = true;
-                        break;
-                    case 'h': // %h Hour (01..12)
-                    case 'I': // %I Hour (01..12)
-                        builder.appendClockhourOfHalfday(2);
-                        hasTimePart = true;
-                        break;
-                    case 'i': // %i Minutes, numeric (00..59)
-                        builder.appendMinuteOfHour(2);
-                        hasTimePart = true;
-                        break;
-                    case 'j': // %j Day of year (001..366)
-                        builder.appendDayOfYear(3);
-                        break;
-                    case 'k': // %k Hour (0..23)
-                        builder.appendHourOfDay(1);
-                        hasTimePart = true;
-                        break;
-                    case 'l': // %l Hour (1..12)
-                        builder.appendClockhourOfHalfday(1);
-                        hasTimePart = true;
-                        break;
-                    case 'M': // %M Month name (January..December)
-                        builder.appendMonthOfYearText();
-                        break;
-                    case 'm': // %m Month, numeric (00..12)
-                        builder.appendMonthOfYear(2);
-                        break;
-                    case 'p': // %p AM or PM
-                        builder.appendHalfdayOfDayText();
-                        break;
-                    case 'r': // %r Time, 12-hour (hh:mm:ss followed by AM or 
PM)
-                        builder.appendClockhourOfHalfday(2)
-                                .appendLiteral(':')
-                                .appendMinuteOfHour(2)
-                                .appendLiteral(':')
-                                .appendSecondOfMinute(2)
-                                .appendLiteral(' ')
-                                .appendHalfdayOfDayText();
-                        hasTimePart = true;
-                        break;
-                    case 'S': // %S Seconds (00..59)
-                    case 's': // %s Seconds (00..59)
-                        builder.appendSecondOfMinute(2);
-                        hasTimePart = true;
-                        break;
-                    case 'T': // %T Time, 24-hour (hh:mm:ss)
-                        builder.appendHourOfDay(2)
-                                .appendLiteral(':')
-                                .appendMinuteOfHour(2)
-                                .appendLiteral(':')
-                                .appendSecondOfMinute(2);
-                        hasTimePart = true;
-                        break;
-                    case 'v': // %v Week (01..53), where Monday is the first 
day of the week; used with %x
-                        builder.appendWeekOfWeekyear(2);
-                        break;
-                    case 'x': // %x Year for the week, where Monday is the 
first day of the week, numeric, four digits; used with %v
-                        builder.appendWeekyear(4, 4);
-                        break;
-                    case 'W': // %W Weekday name (Sunday..Saturday)
-                        builder.appendDayOfWeekText();
-                        break;
-                    case 'Y': // %Y Year, numeric, four digits
-                        builder.appendYear(4, 4);
-                        break;
-                    case 'y': // %y Year, numeric (two digits)
-                        builder.appendTwoDigitYear(2020);
-                        break;
-                    case 'f': // %f Microseconds (000000..999999)
-                    case 'w': // %w Day of the week (0=Sunday..6=Saturday)
-                    case 'U': // %U Week (00..53), where Sunday is the first 
day of the week
-                    case 'u': // %u Week (00..53), where Monday is the first 
day of the week
-                    case 'V': // %V Week (01..53), where Sunday is the first 
day of the week; used with %X
-                    case 'X': // %X Year for the week where Sunday is the 
first day of the week, numeric, four digits; used with %V
-                    case 'D': // %D Day of the month with English suffix (0th, 
1st, 2nd, 3rd, …)
-                        throw new AnalysisException(String.format("%%%s not 
supported in date format string", character));
-                    case '%': // %% A literal "%" character
-                        builder.appendLiteral('%');
-                        break;
-                    default: // %<x> The literal character represented by <x>
-                        builder.appendLiteral(character);
-                        break;
-                }
-                escaped = false;
-            } else if (character == '%') {
-                escaped = true;
-            } else {
-                builder.appendLiteral(character);
-            }
-        }
-
-        Date retDate = new 
Date(builder.toFormatter().withLocale(Locale.ENGLISH).parseMillis(date.getStringValue()));
-        if (hasTimePart) {
-            return new DateLiteral(DateFormatUtils.format(retDate, "yyyy-MM-dd 
HH:mm:ss"), Type.DATETIME);
-        } else {
-            return new DateLiteral(DateFormatUtils.format(retDate, 
"yyyy-MM-dd"), Type.DATE);
-        }
+        return DateLiteral.dateParser(date.getStringValue(), 
fmtLiteral.getStringValue());
     }
 
     @FEFunction(name = "date_sub", argTypes = { "DATETIME", "INT" }, 
returnType = "DATETIME")
     public static DateLiteral dateSub(LiteralExpr date, LiteralExpr day) 
throws AnalysisException {
-        Date d = new Date(getTime(date));
-        d = DateUtils.addDays(d, -(int) day.getLongValue());
-        return new DateLiteral(DateFormatUtils.format(d, "yyyy-MM-dd 
HH:mm:ss"), Type.DATETIME);
+        return dateAdd(date, new IntLiteral(-(int) day.getLongValue()));
     }
 
     @FEFunction(name = "year", argTypes = { "DATETIME" }, returnType = "INT")
     public static IntLiteral year(LiteralExpr arg) throws AnalysisException {
-        long timestamp = getTime(arg);
-        Calendar instance = Calendar.getInstance();
-        instance.setTimeInMillis(timestamp);
-        return new IntLiteral(instance.get(Calendar.YEAR), Type.INT);
+        return new IntLiteral(((DateLiteral) arg).getYear(), Type.INT);
     }
 
     @FEFunction(name = "month", argTypes = { "DATETIME" }, returnType = "INT")
     public static IntLiteral month(LiteralExpr arg) throws AnalysisException {
-        long timestamp = getTime(arg);
-        Calendar instance = Calendar.getInstance();
-        instance.setTimeInMillis(timestamp);
-        return new IntLiteral(instance.get(Calendar.MONTH) + 1, Type.INT);
+        return new IntLiteral(((DateLiteral) arg).getMonth(), Type.INT);
     }
 
     @FEFunction(name = "day", argTypes = { "DATETIME" }, returnType = "INT")
     public static IntLiteral day(LiteralExpr arg) throws AnalysisException {
-        long timestamp = getTime(arg);
-        Calendar instance = Calendar.getInstance();
-        instance.setTimeInMillis(timestamp);
-        return new IntLiteral(instance.get(Calendar.DAY_OF_MONTH), Type.INT);
+        return new IntLiteral(((DateLiteral) arg).getDay(), Type.INT);
     }
 
     @FEFunction(name = "unix_timestamp", argTypes = { "DATETIME" }, returnType 
= "INT")
     public static IntLiteral unix_timestamp(LiteralExpr arg) throws 
AnalysisException {
-        long timestamp = getTime(arg);
-        return new IntLiteral(timestamp / 1000, Type.INT);
+        try {
+            return new IntLiteral(((DateLiteral) 
arg).unixTime(TimeUtils.getTimeZone()) / 1000, Type.INT);
+        } catch (ParseException e) {
+            throw new AnalysisException(e.getLocalizedMessage());
+        }
     }
 
     @FEFunction(name = "from_unixtime", argTypes = { "INT" }, returnType = 
"VARCHAR")
     public static StringLiteral fromUnixTime(LiteralExpr unixTime) throws 
AnalysisException {
-        long ts = unixTime.getLongValue();
-        // if unixTime < 0 or larger than 9999-12-31 23:59:59, we should 
return null, throw a exception and let BE process
-        if (ts < 0 || ts > 253402271999L) {
+        //if unixTime < 0, we should return null, throw a exception and let BE 
process
+        if (unixTime.getLongValue() < 0) {
             throw new AnalysisException("unixtime should larger than zero");
         }
-        Date date = new Date(unixTime.getLongValue() * 1000);
-        return new StringLiteral(dateFormat(date, "%Y-%m-%d %H:%i:%S"));
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd 
HH:mm:ss");
 
 Review comment:
   I think we can create a constructor of DateLiteral with unix timestamp and 
timezone.
   Then this logic can be included in DateLiteral

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to