/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.tajo.util.datetime;

import com.google.common.annotations.VisibleForTesting;
import org.apache.tajo.conf.TajoConf;
import org.apache.tajo.datum.Int8Datum;
import org.apache.tajo.exception.ValueOutOfRangeException;
import org.apache.tajo.util.datetime.DateTimeConstants.DateStyle;
import org.apache.tajo.util.datetime.DateTimeConstants.DateToken;
import org.apache.tajo.util.datetime.DateTimeConstants.TokenField;

import javax.annotation.Nullable;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * This Class is originated from j2date in datetime.c of PostgreSQL.
 */
public class DateTimeUtil {
  private static int MAX_FRACTION_LENGTH = 6;

  /** maximum possible number of fields in a date * string */
  private static int MAXDATEFIELDS = 25;

  public static boolean isJulianCalendar(int year, int month, int day) {
    return year <= 1752 && month <= 9 && day < 14;
  }

  public static int getCenturyOfEra(int year) {
    if (year > 0) {
      return (year - 1) / 100 + 1;
    } else if (year < 0) {
      //600BC to 501BC -> -6
      int pYear = -year;
      return -((pYear - 1) / 100 + 1);
    } else {
      return 0;
    }
  }

  public static boolean isLeapYear(int year) {
    return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
  }

  public static int getDaysInYearMonth(int year, int month) {
    if (isLeapYear(year)) {
      return DateTimeConstants.DAY_OF_MONTH[1][month - 1];
    } else {
      return DateTimeConstants.DAY_OF_MONTH[0][month - 1];
    }
  }

  /**
   * Julian date support.
   *
   * isValidJulianDate checks the minimum date exactly, but is a bit sloppy
   * about the maximum, since it's far enough out to not be especially
   * interesting.
   * @param years
   * @param months
   * @param days
   * @return
   */
  public static boolean isValidJulianDate(int years, int months, int days) {
    return years > DateTimeConstants.JULIAN_MINYEAR || years == DateTimeConstants.JULIAN_MINYEAR &&
        months > DateTimeConstants.JULIAN_MINMONTH || months == DateTimeConstants.JULIAN_MINMONTH &&
        days >= DateTimeConstants.JULIAN_MINDAY && years < DateTimeConstants.JULIAN_MAXYEAR;
  }

  /**
   * Calendar time to Julian date conversions.
   * Julian date is commonly used in astronomical applications,
   *	since it is numerically accurate and computationally simple.
   * The algorithms here will accurately convert between Julian day
   *	and calendar date for all non-negative Julian days_full
   *	(i.e. from Nov 24, -4713 on).
   *
   * These routines will be used by other date/time packages
   * - thomas 97/02/25
   *
   * Rewritten to eliminate overflow problems. This now allows the
   * routines to work correctly for all Julian day counts from
   * 0 to 2147483647	(Nov 24, -4713 to Jun 3, 5874898) assuming
   * a 32-bit integer. Longer types should also work to the limits
   * of their precision.
   * @param year
   * @param month
   * @param day
   * @return
   */
  public static int date2j(int year, int month, int day) {
    int julian;
    int century;

    if (month > 2) {
      month += 1;
      year += 4800;
    } else {
      month += 13;
      year += 4799;
    }

    century = year / 100;
    julian = (year * 365) - 32167;
    julian += (((year / 4) - century) + (century / 4));
    julian += ((7834 * month) / 256) + day;

    return julian;
  }

  public static TimeMeta j2date(int julianDate) {
    TimeMeta tm = new TimeMeta();
    j2date(julianDate, tm);
    return tm;
  }

  /**
   * Set TimeMeta's date fields.
   * @param julianDate
   * @param tm
   */
  public static void j2date(int julianDate, TimeMeta tm) {
    long julian;
    long quad;
    long extra;
    long y;

    julian = julianDate;
    julian += 32044;
    quad = julian / 146097;
    extra = (julian - quad * 146097) * 4 + 3;
    julian += 60 + quad * 3 + extra / 146097;
    quad = julian / 1461;
    julian -= quad * 1461;
    y = julian * 4 / 1461;
    julian = ((y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366))
        + 123;
    y += quad * 4;


    tm.years = (int)(y - 4800);
    quad = julian * 2141 / 65536;
    tm.dayOfMonth = (int)(julian - 7834 * quad / 256);
    tm.monthOfYear = (int) ((quad + 10) % DateTimeConstants.MONTHS_PER_YEAR + 1);
  }

  /**
   * This method is originated from j2date in datetime.c of PostgreSQL.
   *
   * julianToDay - convert Julian date to day-of-week (0..6 == Sun..Sat)
   *
   * Note: various places use the locution julianToDay(date - 1) to produce a
   * result according to the convention 0..6 = Mon..Sun.	This is a bit of
   * a crock, but will work as long as the computation here is just a modulo.
   * @param julianDate
   * @return
   */
  public static int j2day(int julianDate) {
    long day;

    day = julianDate;

    day += 1;
    day %= 7;

    return (int) day;
  }

  /**
   * This method is originated from date2isoweek in timestamp.c of PostgreSQL.
   * Returns ISO week number of year.
   * @param year
   * @param mon
   * @param mday
   * @return
   */
  public static int date2isoweek(int year, int mon, int mday) {
    double result;
    int day0;
    int day4;
    int dayn;

    /* current day */
    dayn = date2j(year, mon, mday);

    /* fourth day of current year */
    day4 = date2j(year, 1, 4);

    /* day0 == offset to first day of week (Monday) */
    day0 = j2day(day4 - 1);

    /*
     * We need the first week containing a Thursday, otherwise this day falls
     * into the previous year for purposes of counting weeks
     */
    if (dayn < day4 - day0) {
      day4 = date2j(year - 1, 1, 4);

      /* day0 == offset to first day of week (Monday) */
      day0 = j2day(day4 - 1);
    }

    result = (dayn - (day4 - day0)) / 7 + 1;

      /*
       * Sometimes the last few days_full in a year will fall into the first week of
       * the next year, so check for this.
       */
    if (result >= 52) {
      day4 = date2j(year + 1, 1, 4);

      /* day0 == offset to first day of week (Monday) */
      day0 = j2day(day4 - 1);

      if (dayn >= day4 - day0) {
        result = (dayn - (day4 - day0)) / 7 + 1;
      }
    }

    return (int) result;
  }

  /**
   * date2isoyear()
   *
   * Returns ISO 8601 year number.
   * @param year
   * @param mon
   * @param mday
   * @return
   */
  public static int date2isoyear(int year, int mon, int mday) {
    /* current day */
    int dayn = date2j(year, mon, mday);

	  /* fourth day of current year */
    int day4 = date2j(year, 1, 4);

	  /* day0 == offset to first day of week (Monday) */
    int day0 = j2day(day4 - 1);

    /*
     * We need the first week containing a Thursday, otherwise this day falls
     * into the previous year for purposes of counting weeks
     */
    if (dayn < day4 - day0) {
      day4 = date2j(year - 1, 1, 4);

		/* day0 == offset to first day of week (Monday) */
      day0 = j2day(day4 - 1);

      year--;
    }

    double result = (dayn - (day4 - day0)) / 7 + 1;

    /*
     * Sometimes the last few days in a year will fall into the first week of
     * the next year, so check for this.
     */
    if (result >= 52) {
      day4 = date2j(year + 1, 1, 4);

		/* day0 == offset to first day of week (Monday) */
      day0 = j2day(day4 - 1);

      if (dayn >= day4 - day0) {
        year++;
      }
    }

    return year;
  }

  /**
   * Converts julian timestamp to epoch.
   * @param timestamp
   * @return
   */
  public static int julianTimeToEpoch(long timestamp) {
    long totalSecs = timestamp / DateTimeConstants.USECS_PER_SEC;
    return (int)(totalSecs + DateTimeConstants.SECS_DIFFERENCE_BETWEEN_JULIAN_AND_UNIXTIME);
  }

  /**
   * Converts julian timestamp to java timestamp.
   * @param timestamp julian time in millisecond
   * @return java time in millisecond
   */
  public static long julianTimeToJavaTime(long timestamp) {
    double totalSecs = (double)timestamp / (double)DateTimeConstants.MSECS_PER_SEC;
    return Math.round(totalSecs + DateTimeConstants.SECS_DIFFERENCE_BETWEEN_JULIAN_AND_UNIXTIME * 1000.0);
  }

  /**
   * Converts java timestamp to julian timestamp.
   * @param javaTimestamp
   * @return
   */
  public static long javaTimeToJulianTime(long javaTimestamp) {
    double totalSecs = javaTimestamp / 1000.0;
    return (long)((totalSecs -
        DateTimeConstants.SECS_DIFFERENCE_BETWEEN_JULIAN_AND_UNIXTIME) * DateTimeConstants.USECS_PER_SEC);
  }

  /**
   * Calculate the time value(hour, minute, sec, fsec)
   * If tm.TomeZone is set, the result value is adjusted.
   * @param tm
   * @return
   */
  public static long toTime(TimeMeta tm) {
    if (tm.timeZone != 0 && tm.timeZone != Integer.MAX_VALUE) {
      int timeZoneSecs = tm.timeZone;
      tm.timeZone = Integer.MAX_VALUE;
      tm.plusMillis(0 - timeZoneSecs * 1000);
    }
    return toTime(tm.hours, tm.minutes, tm.secs, tm.fsecs);
  }

  /**
   * Calculate the time value(hour, minute, sec, fsec)
   * @param hour
   * @param min
   * @param sec
   * @param fsec
   * @return
   */
  public static long toTime(int hour, int min, int sec, int fsec) {
    return (((((hour * DateTimeConstants.MINS_PER_HOUR) + min) *
        DateTimeConstants.SECS_PER_MINUTE) + sec) *
        DateTimeConstants.USECS_PER_SEC) + fsec;
  }

  public static long toJavaTime(int hour, int min, int sec, int fsec) {
    return toTime(hour, min, sec, fsec)/DateTimeConstants.MSECS_PER_SEC;
  }

  public static Timestamp toJavaTimestamp(TimeMeta tm, @Nullable TimeZone tz) {
    long javaTime = DateTimeUtil.julianTimeToJavaTime(DateTimeUtil.toJulianTimestamp(tm));

    if (tz != null) {
      int offset = tz.getOffset(javaTime) - TimeZone.getDefault().getOffset(javaTime);
      return new Timestamp(javaTime + offset);
    } else {
      return new Timestamp(javaTime);
    }
  }

  public static Time toJavaTime(TimeMeta tm, @Nullable TimeZone tz) {
    if (tz != null) {
      DateTimeUtil.toUserTimezone(tm, tz);
    }
    return new Time(tm.hours, tm.minutes, tm.secs);
  }

  public static Date toJavaDate(TimeMeta tm, @Nullable TimeZone tz) {
    if (tz != null) {
      DateTimeUtil.toUserTimezone(tm, tz);
    }
    return new Date(tm.years - 1900, tm.monthOfYear - 1 , tm.dayOfMonth);
  }

  /**
   * Calculate julian timestamp.
   * @param years
   * @param months
   * @param days
   * @param hours
   * @param minutes
   * @param seconds
   * @param fsec
   * @return
   */
  public static long toJulianTimestamp(
      int years, int months, int days, int hours, int minutes, int seconds, int fsec) {
    /* Julian day routines are not correct for negative Julian days_full */
    if (!isValidJulianDate(years, months, days)) {
      throw new ValueOutOfRangeException("Out of Range Julian days_full");
    }

    long numJulianDays = date2j(years, months, days) - DateTimeConstants.POSTGRES_EPOCH_JDATE;

    return toJulianTimestamp(numJulianDays, hours, minutes, seconds, fsec);
  }

  /**
   * Calculate julian timestamp.
   * @param numJulianDays
   * @param hours
   * @param minutes
   * @param seconds
   * @param fsec
   * @return
   */
  private static long toJulianTimestamp(long numJulianDays, int hours, int minutes, int seconds, int fsec) {
    long time = toTime(hours, minutes, seconds, fsec);

    long timestamp = numJulianDays * DateTimeConstants.USECS_PER_DAY + time;
      /* check for major overflow */
    if ((timestamp - time) / DateTimeConstants.USECS_PER_DAY != numJulianDays) {
      throw new RuntimeException("Out of Range of Time");
    }
      /* check for just-barely overflow (okay except time-of-day wraps) */
      /* caution: we want to allow 1999-12-31 24:00:00 */
    if ((timestamp < 0 && numJulianDays > 0) || (timestamp > 0 && numJulianDays < -1)) {
      throw new RuntimeException("Out of Range of Date");
    }

    return timestamp;
  }

  /**
   * Calculate julian timestamp.
   * If tm.TomeZone is set, the result value is adjusted.
   * @param tm
   * @return
   */
  public static long toJulianTimestamp(TimeMeta tm) {
    if (tm.timeZone != 0 && tm.timeZone != Integer.MAX_VALUE) {
      int timeZoneSecs = tm.timeZone;
      tm.timeZone = Integer.MAX_VALUE;
      tm.plusMillis(0 - timeZoneSecs * 1000);
    }
    if (tm.dayOfYear > 0) {
      return toJulianTimestamp(date2j(tm.years, 1, 1) + tm.dayOfYear - 1, tm.hours, tm.minutes, tm.secs, tm.fsecs);
    } else {
      return toJulianTimestamp(tm.years, tm.monthOfYear, tm.dayOfMonth, tm.hours, tm.minutes, tm.secs, tm.fsecs);
    }
  }

  /**
   * Set TimeMeta's field value using given julian timestamp.
   * Note that year is _not_ 1900-based, but is an explicit full value.
   * Also, month is one-based, _not_ zero-based.
   * Returns:
   *	 0 on success
   *	-1 on out of range
   *
   * If attimezone is NULL, the global timezone (including possibly brute forced
   * timezone) will be used.
   */
  public static void toJulianTimeMeta(long julianTimestamp, TimeMeta tm) {
    long date;
    long time;

    // TODO - If timezone is set, timestamp value should be adjusted here.
    time = julianTimestamp;

    // TMODULO
    date = time / DateTimeConstants.USECS_PER_DAY;
    if (date != 0) {
      time -= date * DateTimeConstants.USECS_PER_DAY;
    }
    if (time < 0) {
      time += DateTimeConstants.USECS_PER_DAY;
      date -= 1;
    }

    /* add offset to go from J2000 back to standard Julian date */
    date += DateTimeConstants.POSTGRES_EPOCH_JDATE;

    /* Julian day routine does not work for negative Julian days_full */
    if (date < 0 || date > Integer.MAX_VALUE) {
      throw new RuntimeException("Timestamp Out Of Scope");
    }

    j2date((int) date, tm);
    date2j(time, tm);
  }

  /**
   * This method is originated from dt2time in timestamp.c of PostgreSQL.
   *
   * @param julianDate
   * @return hour, min, sec, fsec
   */
  public static void date2j(long julianDate, TimeMeta tm) {
    long time = julianDate;

    tm.hours = (int) (time / DateTimeConstants.USECS_PER_HOUR);
    time -= tm.hours * DateTimeConstants.USECS_PER_HOUR;
    tm.minutes = (int) (time / DateTimeConstants.USECS_PER_MINUTE);
    time -= tm.minutes * DateTimeConstants.USECS_PER_MINUTE;
    tm.secs = (int) (time / DateTimeConstants.USECS_PER_SEC);
    tm.fsecs = (int) (time - (tm.secs * DateTimeConstants.USECS_PER_SEC));
  }

  /**
   * Decode date string which includes delimiters.
   *
   * This method is originated from DecodeDate() in datetime.c of PostgreSQL.
   * @param str The date string like '2013-12-25'.
   * @param fmask
   * @param tmaskValue
   * @param is2digits
   * @param tm
   */
  private static void decodeDate(String str, int fmask, AtomicInteger tmaskValue,  AtomicBoolean is2digits, TimeMeta tm) {

    int idx = 0;
    int nf = 0;
    TokenField type = null;
    int val = 0;

    AtomicInteger dmask = new AtomicInteger(0);
    int tmask = tmaskValue.get();
    boolean haveTextMonth = false;

    int length = str.length();
    char[] dateStr = str.toCharArray();
    String[] fields = new String[MAXDATEFIELDS];

    while(idx < length && nf < MAXDATEFIELDS) {

      /* skip field separators */
      while (idx < length && !Character.isLetterOrDigit(dateStr[idx])) {
        idx++;
      }

      if (idx == length) {
        throw new IllegalArgumentException("BAD Format: " + str);
      }

      int fieldStartIdx = idx;
      int fieldLength = idx;
      if (Character.isDigit(dateStr[idx])) {
        while (idx < length && Character.isDigit(dateStr[idx])) {
          idx++;
        }
        fieldLength = idx;
      } else if (Character.isLetterOrDigit(dateStr[idx])) {
        while (idx < length && Character.isLetterOrDigit(dateStr[idx])) {
          idx++;
        }
        fieldLength = idx;
      }

      fields[nf] = str.substring(fieldStartIdx, fieldLength);
      nf++;
    }

    /* look first for text fields, since that will be unambiguous month */
    for (int i = 0; i < nf; i++) {
      if (Character.isLetter(fields[i].charAt(0))) {
        DateToken dateToken =  DateTimeConstants.dateTokenMap.get(fields[i].toLowerCase());
        type = dateToken.getType();

        if (type == TokenField.IGNORE_DTF) {
          continue;
        }

        dmask.set(DateTimeConstants.DTK_M(type));
        switch (type) {
          case MONTH:
            tm.monthOfYear = type.getValue();
            haveTextMonth = true;
            break;

          default:
            throw new IllegalArgumentException("BAD Format: " + str);
        }
        if ((fmask & dmask.get()) != 0) {
          throw new IllegalArgumentException("BAD Format: " + str);
        }

        fmask |= dmask.get();
        tmask |= dmask.get();

			/* mark this field as being completed */
        fields[i] = null;
      }
    }

    /* now pick up remaining numeric fields */
    for (int i = 0; i < nf; i++) {
      if (fields[i] == null) {
        continue;
      }

      length = fields[i].length();
      if (length  <= 0) {
        throw new IllegalArgumentException("BAD Format: " + str);
      }

      decodeNumber(length, fields[i], haveTextMonth, fmask, dmask, tm, new AtomicLong(0), is2digits);

      if ( (fmask & dmask.get()) != 0 ) {
        throw new IllegalArgumentException("BAD Format: " + str);
      }
      fmask |= dmask.get();
      tmask |= dmask.get();
    }

    tmaskValue.set(tmask);

    if ((fmask & ~(DateTimeConstants.DTK_M(TokenField.DOY) | DateTimeConstants.DTK_M(TokenField.TZ))) != DateTimeConstants.DTK_DATE_M) {
      throw new IllegalArgumentException("BAD Format: " + str);
    }
  }

  /**
   * Decode time string which includes delimiters.
   * Return 0 if okay, a DTERR code if not.
   *
   * Only check the lower limit on hours, since this same code can be
   * used to represent time spans.
   * @param str
   * @param fmask
   * @param range
   * @param tmask
   * @param tm
   * @param fsec
   */
  private static void decodeTime(String str, int fmask, int range,
             AtomicInteger tmask, TimeMeta tm, AtomicLong fsec) {
    StringBuilder cp = new StringBuilder();

    tmask.set(DateTimeConstants.DTK_TIME_M);

    tm.hours = strtoi(str, 0, cp);
    if (cp.charAt(0) != ':') {
      throw new IllegalArgumentException("BAD Format: " + str);
    }

    tm.minutes = strtoi(cp.toString(), 1, cp);

    if (cp.length() == 0) {
      tm.secs = 0;
      fsec.set(0);
		  /* If it's a MINUTE TO SECOND interval, take 2 fields as being mm:ss */
      if (range == (DateTimeConstants.INTERVAL_MASK(TokenField.MINUTE) | DateTimeConstants.INTERVAL_MASK(TokenField.SECOND))) {
        tm.secs = tm.minutes;
        tm.minutes = tm.hours;
        tm.hours = 0;
      }
    } else if (cp.charAt(0) == '.') {
		  /* always assume mm:ss.sss is MINUTE TO SECOND */
      parseFractionalSecond(cp, fsec);
      tm.secs = tm.minutes;
      tm.minutes = tm.hours;
      tm.hours = 0;
    }
    else if (cp.charAt(0) == ':') {
      tm.secs = strtoi(cp.toString(), 1, cp);
      if (cp.length() == 0){
        fsec.set(0);
      } else if (cp.charAt(0) == '.') {
        parseFractionalSecond(cp, fsec);
      } else{
        throw new IllegalArgumentException("BAD Format: " + str);
      }
    } else {
      throw new IllegalArgumentException("BAD Format: " + str);
    }

	/* do a sanity check */
    if (tm.hours < 0 || tm.minutes < 0 || tm.minutes > DateTimeConstants.MINS_PER_HOUR - 1 ||
        tm.secs < 0 || tm.secs > DateTimeConstants.SECS_PER_MINUTE ||
            fsec.get() < 0 ||
            fsec.get() > DateTimeConstants.USECS_PER_SEC) {
      throw new IllegalArgumentException("BAD Format: FIELD_OVERFLOW: " + str);
    }
  }

  /**
   * Parse datetime string to julian time.
   * The result is the UTC time basis.
   * @param str
   * @return
   */
  public static long toJulianTimestamp(String str) {
    TimeMeta tm = decodeDateTime(str, MAXDATEFIELDS);
    return toJulianTimestamp(tm);
  }


  /**
   * Parse datetime string to UTC-based julian time.
   * The result julian time is adjusted by local timezone.
   *
   * @param timestampStr
   * @param tz Local timezone. If it is NULL, UTC will be used by default.
   * @return UTC-based julian time
   */
  public static long toJulianTimestampWithTZ(String timestampStr, @Nullable TimeZone tz) {
    long timestamp = DateTimeUtil.toJulianTimestamp(timestampStr);
    TimeMeta tm = new TimeMeta();
    DateTimeUtil.toJulianTimeMeta(timestamp, tm);
    if (tz != null) {
      DateTimeUtil.toUTCTimezone(tm, tz);
    }
    return DateTimeUtil.toJulianTimestamp(tm);
  }

  /**
   * Parse datetime string to julian date.
   * @param dateStr
   * @return
   */
  public static int toJulianDate(String dateStr) {
    TimeMeta tm = DateTimeUtil.decodeDateTime(dateStr);
    return DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth);
  }

  /**
   * Parse datetime string to julian time.
   * @param timeStr
   * @return
   */
  public static long toJulianTime(String timeStr) {
    TimeMeta tm = DateTimeUtil.decodeDateTime(timeStr);
    return DateTimeUtil.toTime(tm);
  }

  public static TimeMeta decodeDateTime(String str) {
    return decodeDateTime(str, MAXDATEFIELDS);
  }

  /**
   * Break string into tokens based on a date/time context.
   *
   * This method is originated form ParseDateTime() in datetime.c of PostgreSQL.
   *
   * @param str The input string
   * @param maxFields
   */
  public static TimeMeta decodeDateTime(String str, int maxFields) {
    int idx = 0;
    int nf = 0;
    int length = str.length();
    char [] timeStr = str.toCharArray();
    String [] fields = new String[maxFields];
    TokenField[] fieldTypes = new TokenField[maxFields];

    while (idx < length) {

      /* Ignore spaces between fields */
      if (Character.isSpaceChar(timeStr[idx])) {
        idx++;
        continue;
      }

      /* Record start of current field */
      if (nf >= maxFields) {
        throw new IllegalArgumentException("Too many fields");
      }

      int startIdx = idx;

      //January 8, 1999
      /* leading digit? then date or time */
      if (Character.isDigit(timeStr[idx])) {
        idx++;
        while (idx < length && Character.isDigit(timeStr[idx])) {
          idx++;
        }

        if (idx < length && timeStr[idx] == ':') {
          fieldTypes[nf] = TokenField.DTK_TIME;

          while (idx <length && (Character.isDigit(timeStr[idx]) || timeStr[idx] == ':' || timeStr[idx] == '.')) {
            idx++;
          }
        }

        /* date field? allow embedded text month */
        else if (idx < length && (timeStr[idx] == '-' || timeStr[idx] == '/' || timeStr[idx] == '.')) {

          /* save delimiting character to use later */
          char delim = timeStr[idx];
          idx++;

          /* second field is all digits? then no embedded text month */
          if (Character.isDigit(timeStr[idx])) {
            fieldTypes[nf] = delim == '.' ? TokenField.DTK_NUMBER : TokenField.DTK_DATE;

            while (idx < length && Character.isDigit(timeStr[idx])) {
              idx++;
            }

            /*
					   * insist that the delimiters match to get a three-field
					   * date.
					   */
            if (idx < length && timeStr[idx] == delim) {
              fieldTypes[nf] = TokenField.DTK_DATE;
              idx++;
              while (idx < length && (Character.isDigit(timeStr[idx]) || timeStr[idx] == delim)) {
                idx++;
              }
            }
          } else {
            fieldTypes[nf] = TokenField.DTK_DATE;
            while (idx < length && Character.isLetterOrDigit(timeStr[idx]) || timeStr[idx] == delim) {
              idx++;
            }
          }
        } else {
          /*
			     * otherwise, number only and will determine year, month, day, or
			     * concatenated fields later...
			    */
          fieldTypes[nf] = TokenField.DTK_NUMBER;
        }
      }

      /* Leading decimal point? Then fractional seconds... */
      else if (timeStr[idx] == '.') {
        idx++;
        while (idx < length && Character.isDigit(timeStr[idx])) {
          idx++;
          continue;
        }
        fieldTypes[nf] = TokenField.DTK_NUMBER;
      }

      // text? then date string, month, day of week, special, or timezone
      else if (Character.isLetter(timeStr[idx])) {
        boolean isDate;
        idx++;
        while (idx < length && Character.isLetter(timeStr[idx])) {
          idx++;
        }

        // Dates can have embedded '-', '/', or '.' separators.  It could
        // also be a timezone name containing embedded '/', '+', '-', '_',
        // or ':' (but '_' or ':' can't be the first punctuation). If the
        // next character is a digit or '+', we need to check whether what
        // we have so far is a recognized non-timezone keyword --- if so,
        // don't believe that this is the start of a timezone.

        isDate = false;
        if (idx < length && (timeStr[idx] == '-' || timeStr[idx] == '/' || timeStr[idx] == '.')) {
          isDate = true;
        } else if (idx < length && (timeStr[idx] == '+' || Character.isDigit(timeStr[idx]))) {
          // The original ParseDateTime handles this case. But, we currently omit this case.
          throw new IllegalArgumentException("Cannot parse this datetime field " + str.substring(startIdx, idx));
        }

        if (isDate) {
          fieldTypes[nf] = TokenField.DTK_DATE;

          do {
            idx++;
          } while (idx <length && (timeStr[idx] == '+' || timeStr[idx] == '-' || timeStr[idx] == '/' ||
              timeStr[idx] == '_' || timeStr[idx] == '.' || timeStr[idx] == ':' ||
              Character.isLetterOrDigit(timeStr[idx])));
        } else {
          fieldTypes[nf] = TokenField.DTK_STRING;
        }
      }

      // sign? then special or numeric timezone
      else if (timeStr[idx] == '+' || timeStr[idx] == '-') {
        idx++;

        // soak up leading whitespace
        while (idx < length && Character.isSpaceChar(timeStr[idx])) {
          idx++;
        }

        // numeric timezone?
        // note that "DTK_TZ" could also be a signed float or yyyy-mm */
        if (idx < length && Character.isDigit(timeStr[idx])) {
          fieldTypes[nf] = TokenField.DTK_TZ;
          idx++;

          while (idx < length && (Character.isDigit(timeStr[idx]) || timeStr[idx] == ':' || timeStr[idx] == '.' ||
              timeStr[idx] == '-')) {
            idx++;
          }
        }
        /* special? */
        else if (idx < length && Character.isLetter(timeStr[idx])) {
          fieldTypes[nf] = TokenField.DTK_SPECIAL;
          idx++;

          while (idx < length && Character.isLetter(timeStr[idx])) {
            idx++;
          }
        } else {
          throw new IllegalArgumentException("BAD Format: " + str.substring(startIdx, idx));
        }
      }
      /* ignore other punctuation but use as delimiter */
      else if (isPunctuation(timeStr[idx])) {
        idx++;
        continue;
      } else {  // otherwise, something is not right...
        throw new IllegalArgumentException("BAD datetime format: " + str.substring(startIdx, idx));
      }

      fields[nf] = str.substring(startIdx, idx);
      nf++;
    }
    return decodeDateTime(fields, fieldTypes, nf);
  }

  /**
   * Fetch a fractional-second value with suitable error checking
   * @param cp
   * @param fsec
   */
  public static void parseFractionalSecond(StringBuilder cp, AtomicLong fsec) {
	  /* Caller should always pass the start of the fraction part */
    double frac = strtod(cp.toString(), 1, cp);
    fsec.set(Math.round(frac * 1000000));
  }

  /**
   * Interpret string as a numeric timezone.
   *
   * Return 0 if okay (and set *tzp), a DTERR code if not okay.
   *
   * NB: this must *not* ereport on failure; see commands/variable.c.
   * @param str
   * @param tz
   */
  public static void decodeTimezone(String str, AtomicInteger tz) {
    int min = 0;
    int sec = 0;
    StringBuilder sb = new StringBuilder();

    int strIndex = 0;
	  /* leading character must be "+" or "-" */
    if (str.charAt(strIndex) != '+' && str.charAt(strIndex) != '-') {
      throw new IllegalArgumentException("BAD Format: " + str);
    }
    int hr = strtoi(str, 1, sb);

	  /* explicit delimiter? */
    if (sb.length() > 0 && sb.charAt(0) == ':') {
      min = strtoi(sb.toString(), 1, sb);
      if (sb.charAt(0) == ':') {
        sec = strtoi(sb.toString(), 1, sb);
      }
    }
	  /* otherwise, might have run things together... */
    else if (sb.length() == 0 && str.length() > 3) {
      min = hr % 100;
      hr = hr / 100;
		/* we could, but don't, support a run-together hhmmss format */
    } else {
      min = 0;
    }
	  /* Range-check the values; see notes in datatype/timestamp.h */
    if (hr < 0 || hr > DateTimeConstants.MAX_TZDISP_HOUR) {
      throw new IllegalArgumentException("BAD Format: TZDISP_OVERFLOW: " + str);
    }
    if (min < 0 || min >= DateTimeConstants.MINS_PER_HOUR) {
      throw new IllegalArgumentException("BAD Format: TZDISP_OVERFLOW: " + str);
    }
    if (sec < 0 || sec >= DateTimeConstants.SECS_PER_MINUTE) {
      throw new IllegalArgumentException("BAD Format: TZDISP_OVERFLOW: " + str);
    }

    int tzValue = (hr * DateTimeConstants.MINS_PER_HOUR + min) * DateTimeConstants.SECS_PER_MINUTE + sec;
    if (str.charAt(strIndex) == '-') {
      tzValue = -tzValue;
    }
    tz.set(tzValue);
  }

  /**
   * Interpret plain numeric field as a date value in context.
   * @param flen
   * @param str
   * @param haveTextMonth
   * @param fmask
   * @param tmaskValue
   * @param tm
   * @param fsec
   * @param is2digits
   */
  private static void decodeNumber(int flen, String str, boolean haveTextMonth, int fmask,
               AtomicInteger tmaskValue, TimeMeta tm, AtomicLong fsec, AtomicBoolean is2digits) {
    int	val;
    StringBuilder cp = new StringBuilder();

    int tmask = 0;
    tmaskValue.set(tmask);

    val = strtoi(str, 0, cp);
    if (cp.toString().equals(str)) {
      throw new IllegalArgumentException("BAD Format: " + str);
    }

    if (cp.length() > 0 && cp.charAt(0) == '.') {
		/*
		 * More than two digits before decimal point? Then could be a date or
		 * a run-together time: 2001.360 20011225 040506.789
		 */
      if (cp.length() - str.length() > 2) {
        decodeNumberField(flen, str,
            (fmask | DateTimeConstants.DTK_DATE_M),
            tmaskValue, tm,
            fsec, is2digits);
        return;
      }
      parseFractionalSecond(cp, fsec);
    }

  	// Special case for day of year
    if (flen == 3 && (fmask & DateTimeConstants.DTK_DATE_M) == DateTimeConstants.DTK_M(TokenField.YEAR) &&
        val >= 1 && val <= 366) {
      tmaskValue.set((DateTimeConstants.DTK_M(TokenField.DOY) |
          DateTimeConstants.DTK_M(TokenField.MONTH) |
          DateTimeConstants.DTK_M(TokenField.DAY)));
      tm.dayOfYear = val;
		  // tm_mon and tm_mday can't actually be set yet ...
      return;
    }

	  /* Switch based on what we have so far */
    int checkValue = fmask & DateTimeConstants.DTK_DATE_M;
    if (checkValue == 0) {
			/*
			 * Nothing so far; make a decision about what we think the input
			 * is.	There used to be lots of heuristics here, but the
			 * consensus now is to be paranoid.  It *must* be either
			 * YYYY-MM-DD (with a more-than-two-digit year field), or the
			 * field order defined by DateOrder.
			 */
      if (flen >= 3 || TajoConf.getDateOrder() == DateTimeConstants.DATEORDER_YMD) {
        tmaskValue.set(DateTimeConstants.DTK_M(TokenField.YEAR));
        tm.years = val;
      } else if (TajoConf.getDateOrder() == DateTimeConstants.DATEORDER_DMY) {
        tmaskValue.set(DateTimeConstants.DTK_M(TokenField.DAY));
        tm.dayOfMonth = val;
      } else {
        tmaskValue.set(DateTimeConstants.DTK_M(TokenField.MONTH));
        tm.monthOfYear = val;
      }
    } else if (checkValue == (DateTimeConstants.DTK_M(TokenField.YEAR))) {
			/* Must be at second field of YY-MM-DD */
      tmaskValue.set(DateTimeConstants.DTK_M(TokenField.MONTH));
      tm.monthOfYear = val;
    } else if (checkValue == (DateTimeConstants.DTK_M(TokenField.MONTH))) {
      if (haveTextMonth) {
				/*
				 * We are at the first numeric field of a date that included a
				 * textual month name.	We want to support the variants
				 * MON-DD-YYYY, DD-MON-YYYY, and YYYY-MON-DD as unambiguous
				 * inputs.	We will also accept MON-DD-YY or DD-MON-YY in
				 * either DMY or MDY modes, as well as YY-MON-DD in YMD mode.
				 */
        if (flen >= 3 || TajoConf.getDateOrder() == DateTimeConstants.DATEORDER_YMD) {
          tmaskValue.set(DateTimeConstants.DTK_M(TokenField.YEAR));
          tm.years = val;
        } else {
          tmaskValue.set(DateTimeConstants.DTK_M(TokenField.DAY));
          tm.dayOfMonth = val;
        }
      } else {
				/* Must be at second field of MM-DD-YY */
        tmaskValue.set(DateTimeConstants.DTK_M(TokenField.DAY));
        tm.dayOfMonth = val;
      }
    } else if (checkValue == (DateTimeConstants.DTK_M(TokenField.YEAR) | DateTimeConstants.DTK_M(TokenField.MONTH))) {
      if (haveTextMonth) {
				/* Need to accept DD-MON-YYYY even in YMD mode */
        if (flen >= 3 && is2digits.get()) {
					/* Guess that first numeric field is day was wrong */
          tmaskValue.set(DateTimeConstants.DTK_M(TokenField.DAY));		/* YEAR is already set */
          tm.dayOfMonth = tm.years;
          tm.years = val;
          is2digits.set(false);
        } else {
          tmaskValue.set(DateTimeConstants.DTK_M(TokenField.DAY));
          tm.dayOfMonth = val;
        }
      } else {
				/* Must be at third field of YY-MM-DD */
        tmaskValue.set(DateTimeConstants.DTK_M(TokenField.DAY));
        tm.dayOfMonth = val;
      }
    } else if (checkValue == DateTimeConstants.DTK_M(TokenField.DAY)) {
			/* Must be at second field of DD-MM-YY */
      tmaskValue.set(DateTimeConstants.DTK_M(TokenField.MONTH));
      tm.monthOfYear = val;
    } else if (checkValue == (DateTimeConstants.DTK_M(TokenField.MONTH) | DateTimeConstants.DTK_M(TokenField.DAY))) {
			/* Must be at third field of DD-MM-YY or MM-DD-YY */
      tmaskValue.set(DateTimeConstants.DTK_M(TokenField.YEAR));
      tm.years = val;
    } else if (checkValue == (DateTimeConstants.DTK_M(TokenField.YEAR) | DateTimeConstants.DTK_M(TokenField.MONTH) | DateTimeConstants.DTK_M(TokenField.DAY))) {
			/* we have all the date, so it must be a time field */
      decodeNumberField(flen, str, fmask,
          tmaskValue, tm,
          fsec, is2digits);
      return;

    } else {
      throw new IllegalArgumentException("BAD Format: " + str);
    }

	/*
	 * When processing a year field, mark it for adjustment if it's only one
	 * or two digits.
	 */
    if (tmaskValue.get() == DateTimeConstants.DTK_M(TokenField.YEAR)) {
      is2digits.set(flen <= 2);
    }
  }

  /**
   * Interpret numeric string as a concatenated date or time field.
   *
   * Use the context of previously decoded fields to help with
   * the interpretation.
   * @param len
   * @param str
   * @param fmask
   * @param tmaskValue
   * @param tm
   * @param fsec
   * @param is2digits
   * @return
   */
  static TokenField decodeNumberField(int len, String str, int fmask,
                    AtomicInteger tmaskValue, TimeMeta tm, AtomicLong fsec, AtomicBoolean is2digits) {
    /*
     * Have a decimal point? Then this is a date or something with a seconds
     * field...
     */
    int index = str.indexOf('.');

    if (index >= 0) {
      String cp = str.substring(index + 1);
		/*
		 * Can we use ParseFractionalSecond here?  Not clear whether trailing
		 * junk should be rejected ...
		 */
      double frac = strtod(cp, 0, null);
      fsec.set(Math.round(frac * 1000000));
		  /* Now truncate off the fraction for further processing */
      len = str.length();
    }
	  /* No decimal point and no complete date yet? */
    else if ((fmask & DateTimeConstants.DTK_DATE_M) != DateTimeConstants.DTK_DATE_M) {
		  /* yyyymmdd? */
      if (len == 8) {
        tmaskValue.set(DateTimeConstants.DTK_DATE_M);

        tm.dayOfMonth = Integer.parseInt(str.substring(6));
        tm.monthOfYear = Integer.parseInt(str.substring(4, 6));
        tm.years = Integer.parseInt(str.substring(0, 4));

        return TokenField.DTK_DATE;
      }
		  /* yymmdd? */
      else if (len == 6) {
        tmaskValue.set(DateTimeConstants.DTK_DATE_M);
        tm.dayOfMonth = Integer.parseInt(str.substring(4));
        tm.monthOfYear = Integer.parseInt(str.substring(2, 4));
        tm.years = Integer.parseInt(str.substring(0, 2));
        is2digits.set(true);

        return TokenField.DTK_DATE;
      }
    }

	  /* not all time fields are specified? */
    if ((fmask & DateTimeConstants.DTK_TIME_M) != DateTimeConstants.DTK_TIME_M) {
		  /* hhmmss */
      if (len == 6) {
        tmaskValue.set(DateTimeConstants.DTK_TIME_M);
        tm.secs = Integer.parseInt(str.substring(4));
        tm.minutes = Integer.parseInt(str.substring(2, 4));
        tm.hours = Integer.parseInt(str.substring(0, 2));

        return TokenField.DTK_TIME;
      }
		  /* hhmm? */
      else if (len == 4) {
        tmaskValue.set(DateTimeConstants.DTK_TIME_M);
        tm.secs = 0;
        tm.minutes = Integer.parseInt(str.substring(2, 4));
        tm.hours = Integer.parseInt(str.substring(0, 2));

        return TokenField.DTK_TIME;
      }
    }

    throw new IllegalArgumentException("BAD Format: " + str);
  }

  private static TimeMeta decodeDateTime(String[] fields, TokenField[] fieldTypes, int nf) {
    int	fmask = 0;
    AtomicInteger tmask = new AtomicInteger(0);
    int type;

    /* "prefix type" for ISO y2001m02d04 format */
    TokenField ptype = null;

    boolean		haveTextMonth = false;
    boolean		isjulian = false;
    AtomicBoolean is2digits = new AtomicBoolean(false);
    boolean		bc = false;

    int tzp = Integer.MAX_VALUE;
    String namedTimeZone = null;

    StringBuilder sb = new StringBuilder();
    // We'll insist on at least all of the date fields, but initialize the
    // remaining fields in case they are not set later...
    TokenField dtype = TokenField.DTK_DATE;
    TokenField mer = null;

    TimeMeta tm = new TimeMeta();
    TimeMeta cur_tm = new TimeMeta();

    AtomicLong fsec = new AtomicLong();
    AtomicInteger tz = new AtomicInteger(Integer.MAX_VALUE);

    // don't know daylight savings time status apriori */
    tm.isDST = false;

    for (int i = 0; i < nf; i++) {
      if (fieldTypes[i] == null) {
        continue;
      }
      switch (fieldTypes[i]) {
        case DTK_DATE:
          /***
           * Integral julian day with attached time zone?
           * All other forms with JD will be separated into
           * distinct fields, so we handle just this case here.
           ***/
          if (ptype == TokenField.DTK_JULIAN) {
            int			val;

            if (tzp == Integer.MAX_VALUE) {
              throw new IllegalArgumentException("BAD Format: " + fields[i]);
            }

            val = strtoi(fields[i], 0, sb);

            date2j(val, tm);
            isjulian = true;

					  /* Get the time zone from the end of the string */
            decodeTimezone(sb.toString(), tz);

            tmask.set(DateTimeConstants.DTK_DATE_M | DateTimeConstants.DTK_TIME_M | DateTimeConstants.DTK_M(TokenField.TZ));
            ptype = null;
            break;
          }
          /***
           * Already have a date? Then this might be a time zone name
           * with embedded punctuation (e.g. "America/New_York") or a
           * run-together time with trailing time zone (e.g. hhmmss-zz).
           * - thomas 2001-12-25
           *
           * We consider it a time zone if we already have month & day.
           * This is to allow the form "mmm dd hhmmss tz year", which
           * we've historically accepted.
           ***/
          else if (ptype != null ||
              ((fmask & (DateTimeConstants.DTK_M(TokenField.MONTH) | DateTimeConstants.DTK_M(TokenField.DAY))) ==
                  (DateTimeConstants.DTK_M(TokenField.MONTH) | DateTimeConstants.DTK_M(TokenField.DAY))))
          {
					/* No time zone accepted? Then quit... */
            if (tzp == Integer.MAX_VALUE) {
              throw new IllegalArgumentException("BAD Format: " + fields[i]);
            }

            if (Character.isDigit(fields[i].charAt(0)) || ptype != null) {
              if (ptype != null) {
							  /* Sanity check; should not fail this test */
                if (ptype != TokenField.DTK_TIME) {
                  throw new IllegalArgumentException("BAD Format: " + fields[i]);
                }
                ptype = null;
              }

						/*
						 * Starts with a digit but we already have a time
						 * field? Then we are in trouble with a date and time
						 * already...
						 */
              if ((fmask & DateTimeConstants.DTK_TIME_M) == DateTimeConstants.DTK_TIME_M) {
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }

              int index = fields[i].indexOf("-");
              if (index < 0) {
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }

						  /* Get the time zone from the end of the string */
              decodeTimezone(fields[i].substring(index + 1), tz);

              /*
               * Then read the rest of the field as a concatenated
               * time
               */
              decodeNumberField(fields[i].length(), fields[i],
                  fmask,
                  tmask, tm,
                  fsec, is2digits);

              /*
               * modify tmask after returning from
               * DecodeNumberField()
               */
              tmask.set(tmask.get() | DateTimeConstants.DTK_M(TokenField.TZ));
            }
            else {
              namedTimeZone = pg_tzset(fields[i]);
              if (namedTimeZone == null) {
							/*
							 * We should return an error code instead of
							 * ereport'ing directly, but then there is no way
							 * to report the bad time zone name.
							 */
                throw new IllegalArgumentException("BAD Format: time zone \"%s\" not recognized: " + fields[i]);
              }
						  /* we'll apply the zone setting below */
              tmask.set(DateTimeConstants.DTK_M(TokenField.TZ));
            }
          } else {
            decodeDate(fields[i], fmask, tmask, is2digits, tm);
          }
          break;

        case DTK_TIME:
          decodeTime(fields[i], (fmask | DateTimeConstants.DTK_DATE_M),
              DateTimeConstants.INTERVAL_FULL_RANGE,
              tmask, tm, fsec);
          break;

        case DTK_TZ: {
          decodeTimezone(fields[i], tz);
          tmask.set(DateTimeConstants.DTK_M(TokenField.TZ));
          break;
        }

        case DTK_NUMBER:

          /*
           * Was this an "ISO date" with embedded field labels? An
           * example is "y2001m02d04" - thomas 2001-02-04
           */
          if (ptype != null) {
            int val = strtoi(fields[i], 0, sb);

            /*
             * only a few kinds are allowed to have an embedded
             * decimal
             */
            if (sb.length() == 0) {
              continue;
            }
            if (sb.charAt(0) == '.') {
              switch (ptype) {
                case DTK_JULIAN:
                case DTK_TIME:
                case DTK_SECOND:
                  break;
                default:
                  throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }
            } else {
              throw new IllegalArgumentException("BAD Format: " + fields[i]);
            }
            switch (ptype) {
              case DTK_YEAR:
                tm.years = val;
                tmask.set(DateTimeConstants.DTK_M(TokenField.YEAR));
                break;

              case DTK_MONTH:

                /*
                 * already have a month and hour? then assume
                 * minutes
                 */
                if ((fmask & DateTimeConstants.DTK_M(TokenField.MONTH)) != 0 &&
                    (fmask & DateTimeConstants.DTK_M(TokenField.HOUR)) != 0) {
                  tm.minutes = val;
                  tmask.set(DateTimeConstants.DTK_M(TokenField.MINUTE));
                }
                else {
                  tm.monthOfYear = val;
                  tmask.set(DateTimeConstants.DTK_M(TokenField.MONTH));
                }
                break;

              case DTK_DAY:
                tm.dayOfMonth = val;
                tmask.set(DateTimeConstants.DTK_M(TokenField.DAY));
                break;

              case DTK_HOUR:
                tm.hours = val;
                tmask.set(DateTimeConstants.DTK_M(TokenField.HOUR));
                break;

              case DTK_MINUTE:
                tm.minutes = val;
                tmask.set(DateTimeConstants.DTK_M(TokenField.MINUTE));
                break;

              case DTK_SECOND:
                tm.secs = val;
                tmask.set(DateTimeConstants.DTK_M(TokenField.SECOND));
                if (sb.charAt(0) == '.') {
                  parseFractionalSecond(sb, fsec);
                  tmask.set(DateTimeConstants.DTK_ALL_SECS_M);
                }
                break;
              case DTK_TZ:
                tmask.set(DateTimeConstants.DTK_M(TokenField.TZ));
                decodeTimezone(fields[i], tz);
                break;

              case DTK_JULIAN:
							  /* previous field was a label for "julian date" */
                if (val < 0) {
                  throw new IllegalArgumentException("BAD Format: FIELD_OVERFLOW: " + fields[i]);
                }
                tmask.set(DateTimeConstants.DTK_DATE_M);
                date2j(val, tm);
                isjulian = true;

							  /* fractional Julian Day? */
                if (sb.charAt(0) == '.') {
                  double time = strtod(sb.toString(), 0, sb);

                  time *= DateTimeConstants.USECS_PER_DAY;
                  date2j((long)time, tm);
                  tmask.set(tmask.get() | DateTimeConstants.DTK_TIME_M);
                }
                break;

              case DTK_TIME:
							/* previous field was "t" for ISO time */
                decodeNumberField(fields[i].length(), fields[i],
                    (fmask | DateTimeConstants.DTK_DATE_M),
                    tmask, tm,
                    fsec, is2digits);
                if (tmask.get() != DateTimeConstants.DTK_TIME_M) {
                  throw new IllegalArgumentException("BAD Format: FIELD_OVERFLOW: " + fields[i]);
                }
                break;

              default:
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
            }

            ptype = null;
            dtype = TokenField.DTK_DATE;
          } else {
            int flen = fields[i].length();
            int index = fields[i].indexOf(".");
            String cp = null;
            if (index > 0) {
              cp = fields[i].substring(index + 1);
            }

					  /* Embedded decimal and no date yet? */
            if (cp != null && ((fmask & DateTimeConstants.DTK_DATE_M) == 0 )) {
              decodeDate(fields[i], fmask,
                  tmask, is2digits, tm);
            }
					  /* embedded decimal and several digits before? */
            else if (cp != null && flen - cp.length() > 2) {
						/*
						 * Interpret as a concatenated date or time Set the
						 * type field to allow decoding other fields later.
						 * Example: 20011223 or 040506
						 */
              decodeNumberField(flen, fields[i], fmask,
                  tmask, tm,
                  fsec, is2digits);
            }
            else if (flen > 4) {
              decodeNumberField(flen, fields[i], fmask,
                  tmask, tm,
                  fsec, is2digits);
            }
					  /* otherwise it is a single date/time field... */
            else {
              decodeNumber(flen, fields[i],
                  haveTextMonth, fmask,
                  tmask, tm,
                  fsec, is2digits);
            }
          }
          break;
        case DTK_STRING:
        case DTK_SPECIAL:
          DateToken dateToken =  DateTimeConstants.dateTokenMap.get(fields[i].toLowerCase());
          if (dateToken == null) {
            throw new IllegalArgumentException("BAD Format: " + fields[i]);
          }
          tmask.set(DateTimeConstants.DTK_M(dateToken.getType()));
          switch (dateToken.getType()) {
            case RESERV:
              switch(dateToken.getValueType()) {
                case DTK_CURRENT:
                  throw new IllegalArgumentException("BAD Format: date/time value \"current\" is no longer supported" + fields[i]);

                case DTK_NOW:
                  tmask.set(DateTimeConstants.DTK_DATE_M | DateTimeConstants.DTK_TIME_M | DateTimeConstants.DTK_M(TokenField.TZ));
                  dtype = TokenField.DTK_DATE;
                  date2j(javaTimeToJulianTime(System.currentTimeMillis()), tm);
                  break;

                case DTK_YESTERDAY:
                  tmask.set(DateTimeConstants.DTK_DATE_M);
                  dtype = TokenField.DTK_DATE;
                  date2j(javaTimeToJulianTime(System.currentTimeMillis()), tm);
                  tm.plusDays(-1);
                  break;

                case DTK_TODAY:
                  tmask.set(DateTimeConstants.DTK_DATE_M);
                  dtype = TokenField.DTK_DATE;
                  date2j(javaTimeToJulianTime(System.currentTimeMillis()), cur_tm);
                  tm.years = cur_tm.years;
                  tm.monthOfYear = cur_tm.monthOfYear;
                  tm.dayOfMonth = cur_tm.dayOfMonth;
                  break;

                case DTK_TOMORROW:
                  tmask.set(DateTimeConstants.DTK_DATE_M);
                  dtype = TokenField.DTK_DATE;
                  date2j(javaTimeToJulianTime(System.currentTimeMillis()), tm);
                  tm.plusDays(1);
                  break;

                case DTK_ZULU:
                  tmask.set(DateTimeConstants.DTK_TIME_M | DateTimeConstants.DTK_M(TokenField.TZ));
                  dtype = TokenField.DTK_DATE;
                  tm.hours = 0;
                  tm.minutes = 0;
                  tm.secs = 0;
                  break;

                default:
                  dtype = dateToken.getValueType();
              }
              break;

            case MONTH:
              /*
               * already have a (numeric) month? then see if we can
               * substitute...
               */
              if ((fmask & DateTimeConstants.DTK_M(TokenField.MONTH)) != 0 && !haveTextMonth &&
                  (fmask & DateTimeConstants.DTK_M(TokenField.DAY)) == 0 &&
                  tm.monthOfYear >= 1 && tm.monthOfYear <= 31) {
                tm.dayOfMonth = tm.monthOfYear;
                tmask.set(DateTimeConstants.DTK_M(TokenField.DAY));
              }
              haveTextMonth = true;
              tm.monthOfYear = dateToken.getValue();
              break;

            case DTZMOD:

						/*
						 * daylight savings time modifier (solves "MET DST"
						 * syntax)
						 */
              tmask.set(tmask.get() | DateTimeConstants.DTK_M(TokenField.DTZ));
              tm.isDST = true;
              if (tzp == Integer.MAX_VALUE) {
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }
              tzp += dateToken.getValue() * DateTimeConstants.MINS_PER_HOUR;
              break;

            case DTZ:

						/*
						 * set mask for TZ here _or_ check for DTZ later when
						 * getting default timezone
						 */
              tmask.set(tmask.get() | DateTimeConstants.DTK_M(TokenField.TZ));
              tm.isDST = true;
              if (tzp == Integer.MAX_VALUE) {
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }
              tzp = dateToken.getValue() * DateTimeConstants.MINS_PER_HOUR;
              break;

            case TZ:
              tm.isDST = false;
              if (tzp == Integer.MAX_VALUE) {
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }
              tzp = dateToken.getValue() * DateTimeConstants.MINS_PER_HOUR;
              break;

            case IGNORE_DTF:
              break;

            case AMPM:
              mer = dateToken.getValueType();
              break;

            case ADBC:
              bc = (dateToken.getValueType() == TokenField.BC);
              break;

            case DOW:
              tm.dayOfWeek = dateToken.getValue();
              break;

            case UNITS:
              tmask.set(0);
              ptype = dateToken.getValueType();
              break;

            case ISOTIME:

						/*
						 * This is a filler field "t" indicating that the next
						 * field is time. Try to verify that this is sensible.
						 */
              tmask.set(0);

						/* No preceding date? Then quit... */
              if ((fmask & DateTimeConstants.DTK_DATE_M) != DateTimeConstants.DTK_DATE_M) {
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }

              /***
               * We will need one of the following fields:
               *	DTK_NUMBER should be hhmmss.fff
               *	DTK_TIME should be hh:mm:ss.fff
               *	DTK_DATE should be hhmmss-zz
               ***/
              if (i >= nf - 1 ||
                  (fieldTypes[i + 1] != TokenField.DTK_NUMBER &&
                      fieldTypes[i + 1] != TokenField.DTK_TIME &&
                      fieldTypes[i + 1] != TokenField.DTK_DATE)) {
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }

              ptype = dateToken.getValueType();
              break;

            case UNKNOWN_FIELD:

						/*
						 * Before giving up and declaring error, check to see
						 * if it is an all-alpha timezone name.
						 */
              namedTimeZone = pg_tzset(fields[i]);
              if (namedTimeZone == null) {
                throw new IllegalArgumentException("BAD Format: " + fields[i]);
              }
						/* we'll apply the zone setting below */
              tmask.set(DateTimeConstants.DTK_M(TokenField.TZ));
              break;

            default:
              throw new IllegalArgumentException("BAD Format: " + fields[i]);
          }
          break;
      }
      if ((tmask.get() & fmask) != 0) {
        throw new IllegalArgumentException("BAD Format: " + fields[i]);
      }
      fmask |= tmask.get();
    }   /* end loop over fields */

    tm.fsecs = fsec.intValue();
    tm.timeZone = tz.get();
    /* do final checking/adjustment of Y/M/D fields */
    validateDate(fmask, isjulian, is2digits.get(), bc, tm);

	  /* handle AM/PM */
    if (mer != null && mer != TokenField.HR24 && tm.hours > DateTimeConstants.HOURS_PER_DAY / 2) {
      throw new IllegalArgumentException("BAD Format: overflow hour: " + tm.hours);
    }
    if (mer != null && mer == TokenField.AM && tm.hours == DateTimeConstants.HOURS_PER_DAY / 2) {
      tm.hours = 0;
    } else if (mer != null && mer == TokenField.PM && tm.hours != DateTimeConstants.HOURS_PER_DAY / 2) {
      tm.hours += DateTimeConstants.HOURS_PER_DAY / 2;
    }
	  /* do additional checking for full date specs... */
    if (dtype == TokenField.DTK_DATE) {
      if ((fmask & DateTimeConstants.DTK_DATE_M) != DateTimeConstants.DTK_DATE_M) {
        if ((fmask & DateTimeConstants.DTK_TIME_M) == DateTimeConstants.DTK_TIME_M) {
          return tm;
        }
        throw new IllegalArgumentException("BAD Format: " + tm);
      }

		/*
		 * If we had a full timezone spec, compute the offset (we could not do
		 * it before, because we need the date to resolve DST status).
		 */
      if (namedTimeZone != null) {
			/* daylight savings time modifier disallowed with full TZ */
        if ( (fmask & DateTimeConstants.DTK_M(TokenField.DTZMOD)) != 0 ) {
          throw new IllegalArgumentException("BAD Format: " + tm);
        }
      }
    }

    return tm;
  }

  private static String pg_tzset(String str) {
    //TODO implements logic
    return null;
  }

  /**
   * Check valid year/month/day values, handle BC and DOY cases
   * Return 0 if okay, a DTERR code if not.
   * @param fmask
   * @param isjulian
   * @param is2digits
   * @param bc
   * @param tm
   * @return
   */
  private static int validateDate(int fmask, boolean isjulian, boolean is2digits, boolean bc, TimeMeta tm) {
    if ( (fmask & DateTimeConstants.DTK_M(TokenField.YEAR)) != 0 ) {
      if (isjulian) {
			/* tm_year is correct and should not be touched */
      } else if (bc) {
			  /* there is no year zero in AD/BC notation */
        if (tm.years <= 0) {
          throw new IllegalArgumentException("BAD Format: year overflow:" + tm.years);
        }
			  /* internally, we represent 1 BC as year zero, 2 BC as -1, etc */
        tm.years = -(tm.years - 1);
      }
      else if (is2digits) {
			  /* process 1 or 2-digit input as 1970-2069 AD, allow '0' and '00' */
        if (tm.years < 0) { /* just paranoia */
          throw new IllegalArgumentException("BAD Format: year overflow:" + tm.years);
        }
        if (tm.years < 70) {
          tm.years += 2000;
        } else if (tm.years < 100) {
          tm.years += 1900;
        }
      }
      else {
			  /* there is no year zero in AD/BC notation */
        if (tm.years <= 0) {
          throw new IllegalArgumentException("BAD Format: year overflow:" + tm.years);
        }
      }
    }

	  /* now that we have correct year, decode DOY */
    if ( (fmask & DateTimeConstants.DTK_M(TokenField.DOY)) != 0 ) {
      j2date(date2j(tm.years, 1, 1) + tm.dayOfYear - 1, tm);
    }

	  /* check for valid month */
    if ( (fmask & DateTimeConstants.DTK_M(TokenField.MONTH)) != 0 ) {
      if (tm.monthOfYear < 1 || tm.monthOfYear > DateTimeConstants.MONTHS_PER_YEAR) {
        throw new IllegalArgumentException("BAD Format: month overflow:" + tm.monthOfYear);
      }
    }

	  /* minimal check for valid day */
    if ( (fmask & DateTimeConstants.DTK_M(TokenField.DAY)) != 0 ) {
      if (tm.dayOfMonth < 1 || tm.dayOfMonth > 31) {
        throw new IllegalArgumentException("BAD Format: day overflow:" + tm.dayOfMonth);
      }
    }

    if ((fmask & DateTimeConstants.DTK_DATE_M) == DateTimeConstants.DTK_DATE_M) {
		/*
		 * Check for valid day of month, now that we know for sure the month
		 * and year.  Note we don't use MD_FIELD_OVERFLOW here, since it seems
		 * unlikely that "Feb 29" is a YMD-order error.
		 */
      boolean leapYear = isLeapYear(tm.years);
      if (tm.dayOfMonth > DateTimeConstants.DAY_OF_MONTH[leapYear ? 1: 0][tm.monthOfYear - 1])
        throw new IllegalArgumentException("BAD Format: day overflow:" + tm.dayOfMonth);
    }

    return 0;
  }

  public static int strtoi(String str, int startIndex, StringBuilder sb) {
    sb.setLength(0);
    char[] chars = str.toCharArray();

    int index = startIndex;
    for (; index < chars.length; index++) {
      if (!Character.isDigit(chars[index])) {
        break;
      }
    }

    int val = index == startIndex ? 0 : Integer.parseInt(str.substring(startIndex, index));
    sb.append(chars, index, chars.length - index);

    return val;
  }

  public static long strtol(String str, int startIndex, StringBuilder sb) {
    sb.setLength(0);
    char[] chars = str.toCharArray();

    int index = startIndex;
    for (; index < chars.length; index++) {
      if (!Character.isDigit(chars[index])) {
        break;
      }
    }

    long val = index == startIndex ? 0 : Long.parseLong(str.substring(startIndex, index));
    sb.append(chars, index, chars.length - index);

    return val;
  }

  public static double strtod(String str, int strIndex, StringBuilder sb) {
    if (sb != null) {
      sb.setLength(0);
    }
    char[] chars = str.toCharArray();

    int index = strIndex;
    for (; index < chars.length; index++) {
      if (!Character.isDigit(chars[index])) {
        break;
      }
    }

    double val = Double.parseDouble(str.substring(0, index));
    if (sb != null) {
      sb.append(chars, index, chars.length - index);
    }
    return val;
  }

  /**
   * Check whether it is a punctuation character or not.
   * @param c The character to be checked
   * @return True if it is a punctuation character. Otherwise, false.
   */
  public static boolean isPunctuation(char c) {
    return ((c >= '!' && c <= '/') ||
        (c >= ':' && c <= '@') ||
        (c >= '[' && c <= '`') ||
        (c >= '{' && c <= '~'));
  }

  public static String toString(TimeMeta tm) {
    return encodeDateTime(tm, DateStyle.ISO_DATES);
  }

  /**
   * Encode date and time interpreted as local time.
   *
   * tm and fsec are the value to encode, print_tz determines whether to include
   * a time zone (the difference between timestamp and timestamptz types), tz is
   * the numeric time zone offset, tzn is the textual time zone, which if
   * specified will be used instead of tz by some styles, style is the date
   * style, str is where to write the output.
   *
   * Supported date styles:
   *	Postgres - day mon hh:mm:ss yyyy tz
   *	SQL - mm/dd/yyyy hh:mm:ss.ss tz
   *	ISO - yyyy-mm-dd hh:mm:ss+/-tz
   *	German - dd.mm.yyyy hh:mm:ss tz
   *	XSD - yyyy-mm-ddThh:mm:ss.ss+/-tz
   *
   * This method is originated from EncodeDateTime of datetime.c of PostgreSQL.
   * @param tm
   * @param style
   * @return
   */
  public static String encodeDateTime(TimeMeta tm, DateStyle style) {

    StringBuilder sb = new StringBuilder();
    switch (style) {

      case ISO_DATES:
      case XSO_DATES:
        if (style == DateTimeConstants.DateStyle.ISO_DATES) {
          sb.append(String.format("%04d-%02d-%02d %02d:%02d:",
              (tm.years > 0) ? tm.years : -(tm.years - 1),
              tm.monthOfYear, tm.dayOfMonth, tm.hours, tm.minutes));
        } else {
          sb.append(String.format("%04d-%02d-%02dT%02d:%02d:",
              (tm.years > 0) ? tm.years : -(tm.years - 1),
              tm.monthOfYear, tm.dayOfMonth, tm.hours, tm.minutes));
        }

        appendSecondsToEncodeOutput(sb, tm.secs, tm.fsecs, 6, true);
        if (tm.timeZone != 0 && tm.timeZone != Integer.MAX_VALUE) {
          sb.append(getDisplayTimeZoneOffset(tm.timeZone));
        }
        if (tm.years <= 0) {
          sb.append(" BC");
        }
        break;

      case SQL_DATES:
        // Compatible with Oracle/Ingres date formats

    }

    return sb.toString();
  }

  public static String encodeDate(TimeMeta tm, DateStyle style) {
    return encodeDate(tm.years, tm.monthOfYear, tm.dayOfMonth, style);
  }

  public static String encodeDate(int years, int monthOfYear, int dayOfMonth, DateStyle style) {
    StringBuilder sb = new StringBuilder();
    switch (style) {
      case ISO_DATES:
      case XSO_DATES:
      case SQL_DATES:
        // Compatible with Oracle/Ingres date formats
      default:
        sb.append(String.format("%04d-%02d-%02d",
            (years > 0) ? years : -(years - 1),
            monthOfYear, dayOfMonth));
    }

    return sb.toString();
  }

  public static String encodeTime(TimeMeta tm, DateStyle style) {
    StringBuilder sb = new StringBuilder();
    switch (style) {

      case ISO_DATES:
      case XSO_DATES:
      case SQL_DATES:
        // Compatible with Oracle/Ingres date formats
      default :
        sb.append(String.format("%02d:%02d:", tm.hours, tm.minutes));
        appendSecondsToEncodeOutput(sb, tm.secs, tm.fsecs, 6, true);
        if (tm.timeZone != 0 && tm.timeZone != Integer.MAX_VALUE) {
          sb.append(getDisplayTimeZoneOffset(tm.timeZone));
        }
        break;
    }

    return sb.toString();
  }

  /**
   * Append sections and fractional seconds (if any) at *cp.
   * precision is the max number of fraction digits, fillzeros says to
   * pad to two integral-seconds digits.
   * Note that any sign is stripped from the input seconds values.
   *
   * This method is originated form AppendSeconds in datetime.c of PostgreSQL.
   */
  public static void appendSecondsToEncodeOutput(
      StringBuilder sb, int sec, int fsec, int precision, boolean fillzeros) {
    if (fsec == 0) {
      if (fillzeros)
        sb.append(String.format("%02d", Math.abs(sec)));
      else
        sb.append(String.format("%d", Math.abs(sec)));
    } else {
      if (fillzeros) {
        sb.append(String.format("%02d", Math.abs(sec)));
      } else {
        sb.append(String.format("%d", Math.abs(sec)));
      }

      if (precision > MAX_FRACTION_LENGTH) {
        precision = MAX_FRACTION_LENGTH;
      }

      if (precision > 0) {
        char[] fracChars = String.valueOf(fsec).toCharArray();
        char[] resultChars = new char[MAX_FRACTION_LENGTH];

        int numFillZero = MAX_FRACTION_LENGTH - fracChars.length;
        for (int i = 0, fracIdx = 0; i < MAX_FRACTION_LENGTH; i++) {
          if (i < numFillZero) {
            resultChars[i] = '0';
          } else {
            resultChars[i] = fracChars[fracIdx];
            fracIdx++;
          }
        }
        sb.append(".").append(resultChars, 0, precision);
      }
      trimTrailingZeros(sb);
    }
  }

  /**
   * ... resulting from printing numbers with full precision.
   *
   * Before Postgres 8.4, this always left at least 2 fractional digits,
   * but conversations on the lists suggest this isn't desired
   * since showing '0.10' is misleading with values of precision(1).
   *
   * This method is originated form AppendSeconds in datetime.c of PostgreSQL.
   * @param sb
   */
  public static void trimTrailingZeros(StringBuilder sb) {
    int len = sb.length();
    while (len > 1 && sb.charAt(len - 1) == '0' && sb.charAt(len - 2) != '.') {
      len--;
      sb.setLength(len);
    }
  }

  /**
   * Return the Julian day which corresponds to the first day (Monday) of the given ISO 8601 year and week.
   * Julian days_full are used to convert between ISO week dates and Gregorian dates.
   *
   * This method is originated form AppendSeconds in timestamp.c of PostgreSQL.
   * @param year
   * @param week
   * @return
   */
  public static int isoweek2j(int year, int week) {
	  /* fourth day of current year */
    int day4 = date2j(year, 1, 4);

	  /* day0 == offset to first day of week (Monday) */
    int day0 = j2day(day4 - 1);

    return ((week - 1) * 7) + (day4 - day0);
  }

  /**
   * Convert ISO week of year number to date.
   * The year field must be specified with the ISO year!
   * karel 2000/08/07
   *
   * This method is originated form AppendSeconds in timestamp.c of PostgreSQL.
   * @param woy
   * @param tm
   */
  public static void isoweek2date(int woy, TimeMeta tm) {
    j2date(isoweek2j(tm.years, woy), tm);
  }

  /**
   * Convert an ISO 8601 week date (ISO year, ISO week) into a Gregorian date.
   * Gregorian day of week sent so weekday strings can be supplied.
   * Populates year, mon, and mday with the correct Gregorian values.
   * year must be passed in as the ISO year.
   *
   * This method is originated form AppendSeconds in timestamp.c of PostgreSQL.
   * @param isoweek
   * @param wday
   * @param tm
   */
  public static void isoweekdate2date(int isoweek, int wday, TimeMeta tm) {
    int jday;
    jday = isoweek2j(tm.years, isoweek);
	  /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
    if (wday > 1) {
      jday += wday - 2;
    } else {
      jday += 6;
    }
    j2date(jday, tm);
  }

  /**
   * Returns the ISO 8601 day-of-year, given a Gregorian year, month and day.
   * Possible return values are 1 through 371 (364 in non-leap years).
   * @param year
   * @param mon
   * @param mday
   * @return
   */
  public static int date2isoyearday(int year, int mon, int mday) {
    return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
  }

  public static void toUserTimezone(TimeMeta tm, TimeZone timeZone) {
    tm.convertToLocalTime(timeZone);
  }

  public static void toUTCTimezone(TimeMeta tm, TimeZone timeZone) {
    tm.convertToUTC(timeZone);
  }

  @VisibleForTesting
  public static String getDisplayTimeZoneOffset(TimeZone timeZone, boolean dst) {
    return getDisplayTimeZoneOffset((timeZone.getRawOffset() + (dst ? timeZone.getDSTSavings() : 0)) / 1000);
  }

  public static String getDisplayTimeZoneOffset(int totalSecs) {
    if (totalSecs == 0) {
      return "";
    }
    int minutes = Math.abs(totalSecs) / DateTimeConstants.SECS_PER_MINUTE;
    int hours = minutes / DateTimeConstants.MINS_PER_HOUR;
    minutes = minutes - hours * DateTimeConstants.MINS_PER_HOUR;

    StringBuilder sb = new StringBuilder();
    sb.append(totalSecs > 0 ? "+" : "-").append(String.format("%02d", hours));

    if (minutes > 0) {
      sb.append(":").append(String.format("%02d", minutes));
    }

    return sb.toString();
  }

  public static long getDay(TimeMeta dateTime) {
    return julianTimeToJavaTime(toJulianTimestamp(dateTime.years, dateTime.monthOfYear, dateTime.dayOfMonth,
        0, 0, 0, 0)) * DateTimeConstants.USECS_PER_MSEC;
  }

  public static long getHour(TimeMeta dateTime) {
    return julianTimeToJavaTime(toJulianTimestamp(dateTime.years, dateTime.monthOfYear, dateTime.dayOfMonth,
        dateTime.hours, 0, 0, 0)) * DateTimeConstants.USECS_PER_MSEC;
  }

  public static long getMinute(TimeMeta dateTime) {
    return julianTimeToJavaTime(toJulianTimestamp(dateTime.years, dateTime.monthOfYear, dateTime.dayOfMonth,
        dateTime.hours, dateTime.minutes, 0, 0)) * DateTimeConstants.USECS_PER_MSEC;
  }

  public static long getSecond(TimeMeta dateTime) {
    return julianTimeToJavaTime(toJulianTimestamp(dateTime.years, dateTime.monthOfYear, dateTime.dayOfMonth,
        dateTime.hours, dateTime.minutes, dateTime.secs, 0)) * DateTimeConstants.USECS_PER_MSEC;
  }

  public static long getMonth(TimeMeta dateTime) {
    return julianTimeToJavaTime(toJulianTimestamp(dateTime.years, dateTime.monthOfYear, 1, 0, 0, 0, 0)) *
        DateTimeConstants.USECS_PER_MSEC;
  }

  public static long getDayOfWeek(TimeMeta dateTime, int weekday) {    
    if (weekday < 1 || weekday > 7) {
      throw new RuntimeException("Weekday is out of range. Actual : " + weekday);
    }
    
    int week = date2isoweek(dateTime.years, dateTime.monthOfYear, dateTime.dayOfMonth);
    int jday = isoweek2j(dateTime.years, week);

    jday += (weekday - 1);
    
    jday -=  DateTimeConstants.POSTGRES_EPOCH_JDATE;

    return julianTimeToJavaTime(toJulianTimestamp(jday, 0, 0, 0, 0)) * DateTimeConstants.USECS_PER_MSEC;
  }

  public static long getYear(TimeMeta dateTime) {
    return julianTimeToJavaTime(toJulianTimestamp(dateTime.years, 1, 1, 0, 0, 0, 0)) *
        DateTimeConstants.USECS_PER_MSEC;
  }

  public static TimeMeta getUTCDateTime(Int8Datum int8Datum){
    return getUTCDateTime(int8Datum.asInt8());
  }

  public static TimeMeta getUTCDateTime(long time) {
    long usecs = time % DateTimeConstants.USECS_PER_MSEC;
    long julianTimestamp = javaTimeToJulianTime(time / DateTimeConstants.USECS_PER_MSEC);
    TimeMeta tm = new TimeMeta();

    julianTimestamp += usecs;
    toJulianTimeMeta(julianTimestamp, tm);
    return tm;
  }

}
