int     len,                    /* keyword length               */
                (*action) (),
                id;                     /* keyword id                   */
+       bool    isdigit;                /* is expected output/input digit */    
 } KeyWord;
 
 typedef struct
  * ----------
  */
 typedef struct {
-       int     hh, am, pm, mi, ss, ssss, d, dd, ddd, mm, yyyy, bc, iw, ww, w, cc, q, j;
+       int     hh, am, pm, mi, ss, ssss, d, dd, ddd, mm, yyyy, yyy, yy, y, 
+               bc, iw, ww, w, cc, q, j;
 } TmFromChar;
 
 #define ZERO_tmfc( _X )        \
        do { \
                (_X)->hh= (_X)->am= (_X)->pm= (_X)->mi= (_X)->ss= (_X)->ssss= \
-               (_X)->d= (_X)->dd= (_X)->ddd= (_X)->mm= (_X)->yyyy= (_X)->bc= \
-               (_X)->iw= (_X)->ww= (_X)->w= (_X)->cc= (_X)->q= (_X)->j= 0; \
+               (_X)->d= (_X)->dd= (_X)->ddd= (_X)->mm= (_X)->yyyy= (_X)->yyy= \
+               (_X)->yy= (_X)->y= (_X)->bc= (_X)->iw= (_X)->ww= (_X)->w= \
+               (_X)->cc= (_X)->q= (_X)->j= 0; \
        } while(0) 
 
 #ifdef DEBUG_TO_FROM_CHAR
  * it is not good.
  *
  * (!)
- *       Position for the keyword is simular as position in the enum DCH/NUM_poz
+ *      - Position for the keyword is simular as position in the enum DCH/NUM_poz.
  * (!)
  *
  * For fast search is used the 'int index[]', index is ascii table from position
  * ----------
  */
 static KeyWord DCH_keywords[] = {
-/*     keyword,len,func.type                    is in Index */
-       {"A.D.", 4, dch_date, DCH_A_D},         /* A */
-       {"A.M.", 4, dch_time, DCH_A_M},
-       {"AD", 2, dch_date, DCH_AD},
-       {"AM", 2, dch_time, DCH_AM},
-       {"B.C.", 4, dch_date, DCH_B_C},         /* B */
-       {"BC", 2, dch_date, DCH_BC},
-       {"CC", 2, dch_date, DCH_CC},            /* C */
-       {"DAY", 3, dch_date, DCH_DAY},          /* D */
-       {"DDD", 3, dch_date, DCH_DDD},
-       {"DD", 2, dch_date, DCH_DD},
-       {"DY", 2, dch_date, DCH_DY},
-       {"Day", 3, dch_date, DCH_Day},
-       {"Dy", 2, dch_date, DCH_Dy},
-       {"D", 1, dch_date, DCH_D},
-       {"FX", 2, dch_global, DCH_FX},          /* F */
-       {"HH24", 4, dch_time, DCH_HH24},        /* H */
-       {"HH12", 4, dch_time, DCH_HH12},
-       {"HH", 2, dch_time, DCH_HH},
-       {"IW", 2, dch_date, DCH_IW},            /* I */ 
-       {"J", 1, dch_date, DCH_J},              /* J */
-       {"MI", 2, dch_time, DCH_MI},
-       {"MM", 2, dch_date, DCH_MM},
-       {"MONTH", 5, dch_date, DCH_MONTH},
-       {"MON", 3, dch_date, DCH_MON},
-       {"Month", 5, dch_date, DCH_Month},
-       {"Mon", 3, dch_date, DCH_Mon},
-       {"P.M.", 4, dch_time, DCH_P_M},         /* P */
-       {"PM", 2, dch_time, DCH_PM},
-       {"Q", 1, dch_date, DCH_Q},              /* Q */
-       {"RM", 2, dch_date, DCH_RM},            /* R */
-       {"SSSS", 4, dch_time, DCH_SSSS},        /* S */
-       {"SS", 2, dch_time, DCH_SS},
-       {"TZ", 2, dch_time, DCH_TZ},            /* T */
-       {"WW", 2, dch_date, DCH_WW},            /* W */
-       {"W", 1, dch_date, DCH_W},
-       {"Y,YYY", 5, dch_date, DCH_Y_YYY},      /* Y */
-       {"YYYY", 4, dch_date, DCH_YYYY},
-       {"YYY", 3, dch_date, DCH_YYY},
-       {"YY", 2, dch_date, DCH_YY},
-       {"Y", 1, dch_date, DCH_Y},
-       {"a.d.", 4, dch_date, DCH_a_d},         /* a */
-       {"a.m.", 4, dch_time, DCH_a_m},
-       {"ad", 2, dch_date, DCH_ad},
-       {"am", 2, dch_time, DCH_am},
-       {"b.c.", 4, dch_date, DCH_b_c},         /* b */
-       {"bc", 2, dch_date, DCH_bc},
-       {"cc", 2, dch_date, DCH_CC},            /* c */
-       {"day", 3, dch_date, DCH_day},          /* d */
-       {"ddd", 3, dch_date, DCH_DDD},
-       {"dd", 2, dch_date, DCH_DD},
-       {"dy", 2, dch_date, DCH_dy},
-       {"d", 1, dch_date, DCH_D},
-       {"fx", 2, dch_global, DCH_FX},          /* f */
-       {"hh24", 4, dch_time, DCH_HH24},        /* h */
-       {"hh12", 4, dch_time, DCH_HH12},
-       {"hh", 2, dch_time, DCH_HH},
-       {"iw", 2, dch_date, DCH_IW},            /* i */
-       {"j", 1, dch_time, DCH_J},              /* j */
-       {"mi", 2, dch_time, DCH_MI},            /* m */
-       {"mm", 2, dch_date, DCH_MM},
-       {"month", 5, dch_date, DCH_month},
-       {"mon", 3, dch_date, DCH_mon},
-       {"p.m.", 4, dch_time, DCH_p_m},         /* p */
-       {"pm", 2, dch_time, DCH_pm},
-       {"q", 1, dch_date, DCH_Q},              /* q */
-       {"rm", 2, dch_date, DCH_rm},            /* r */
-       {"ssss", 4, dch_time, DCH_SSSS},        /* s */
-       {"ss", 2, dch_time, DCH_SS},
-       {"tz", 2, dch_time, DCH_tz},            /* t */
-       {"ww", 2, dch_date, DCH_WW},            /* w */
-       {"w", 1, dch_date, DCH_W},
-       {"y,yyy", 5, dch_date, DCH_Y_YYY},      /* y */
-       {"yyyy", 4, dch_date, DCH_YYYY},
-       {"yyy", 3, dch_date, DCH_YYY},
-       {"yy", 2, dch_date, DCH_YY},
-       {"y", 1, dch_date, DCH_Y},
+/*     keyword, len, func, type, isdigit                        is in Index */
+       {"A.D.", 4, dch_date, DCH_A_D, FALSE},          /* A */
+       {"A.M.", 4, dch_time, DCH_A_M, FALSE},
+       {"AD", 2, dch_date, DCH_AD, FALSE},
+       {"AM", 2, dch_time, DCH_AM, FALSE},
+       {"B.C.", 4, dch_date, DCH_B_C, FALSE},          /* B */
+       {"BC", 2, dch_date, DCH_BC, FALSE},
+       {"CC", 2, dch_date, DCH_CC, TRUE},              /* C */
+       {"DAY", 3, dch_date, DCH_DAY, FALSE},           /* D */
+       {"DDD", 3, dch_date, DCH_DDD, TRUE},
+       {"DD", 2, dch_date, DCH_DD, TRUE},
+       {"DY", 2, dch_date, DCH_DY, FALSE},
+       {"Day", 3, dch_date, DCH_Day, FALSE},
+       {"Dy", 2, dch_date, DCH_Dy, FALSE},
+       {"D", 1, dch_date, DCH_D, TRUE},
+       {"FX", 2, dch_global, DCH_FX, FALSE},           /* F */
+       {"HH24", 4, dch_time, DCH_HH24, TRUE},          /* H */
+       {"HH12", 4, dch_time, DCH_HH12, TRUE},
+       {"HH", 2, dch_time, DCH_HH, TRUE},
+       {"IW", 2, dch_date, DCH_IW, TRUE},              /* I */ 
+       {"J", 1, dch_date, DCH_J, TRUE},                /* J */
+       {"MI", 2, dch_time, DCH_MI, TRUE},
+       {"MM", 2, dch_date, DCH_MM, TRUE},
+       {"MONTH", 5, dch_date, DCH_MONTH, FALSE},
+       {"MON", 3, dch_date, DCH_MON, FALSE},
+       {"Month", 5, dch_date, DCH_Month, FALSE},
+       {"Mon", 3, dch_date, DCH_Mon, FALSE},
+       {"P.M.", 4, dch_time, DCH_P_M, FALSE},          /* P */
+       {"PM", 2, dch_time, DCH_PM, FALSE},
+       {"Q", 1, dch_date, DCH_Q, TRUE},                /* Q */
+       {"RM", 2, dch_date, DCH_RM, FALSE},             /* R */
+       {"SSSS", 4, dch_time, DCH_SSSS, TRUE},  /* S */
+       {"SS", 2, dch_time, DCH_SS, TRUE},
+       {"TZ", 2, dch_time, DCH_TZ, FALSE},             /* T */
+       {"WW", 2, dch_date, DCH_WW, TRUE},              /* W */
+       {"W", 1, dch_date, DCH_W, TRUE},
+       {"Y,YYY", 5, dch_date, DCH_Y_YYY, TRUE},        /* Y */
+       {"YYYY", 4, dch_date, DCH_YYYY, TRUE},
+       {"YYY", 3, dch_date, DCH_YYY, TRUE},
+       {"YY", 2, dch_date, DCH_YY, TRUE},
+       {"Y", 1, dch_date, DCH_Y, TRUE},
+       {"a.d.", 4, dch_date, DCH_a_d, FALSE},          /* a */
+       {"a.m.", 4, dch_time, DCH_a_m, FALSE},
+       {"ad", 2, dch_date, DCH_ad, FALSE},
+       {"am", 2, dch_time, DCH_am, FALSE},
+       {"b.c.", 4, dch_date, DCH_b_c, FALSE},          /* b */
+       {"bc", 2, dch_date, DCH_bc, FALSE},
+       {"cc", 2, dch_date, DCH_CC, TRUE},              /* c */
+       {"day", 3, dch_date, DCH_day, FALSE},           /* d */
+       {"ddd", 3, dch_date, DCH_DDD, TRUE},
+       {"dd", 2, dch_date, DCH_DD, TRUE},
+       {"dy", 2, dch_date, DCH_dy, FALSE},
+       {"d", 1, dch_date, DCH_D, TRUE},
+       {"fx", 2, dch_global, DCH_FX, FALSE},           /* f */
+       {"hh24", 4, dch_time, DCH_HH24, TRUE},          /* h */
+       {"hh12", 4, dch_time, DCH_HH12, TRUE},
+       {"hh", 2, dch_time, DCH_HH, TRUE},
+       {"iw", 2, dch_date, DCH_IW, TRUE},              /* i */
+       {"j", 1, dch_time, DCH_J, TRUE},                /* j */
+       {"mi", 2, dch_time, DCH_MI, TRUE},              /* m */
+       {"mm", 2, dch_date, DCH_MM, TRUE},
+       {"month", 5, dch_date, DCH_month, FALSE},
+       {"mon", 3, dch_date, DCH_mon, FALSE},
+       {"p.m.", 4, dch_time, DCH_p_m, FALSE},          /* p */
+       {"pm", 2, dch_time, DCH_pm, FALSE},
+       {"q", 1, dch_date, DCH_Q, TRUE},                /* q */
+       {"rm", 2, dch_date, DCH_rm, FALSE},             /* r */
+       {"ssss", 4, dch_time, DCH_SSSS, TRUE},  /* s */
+       {"ss", 2, dch_time, DCH_SS, TRUE},
+       {"tz", 2, dch_time, DCH_tz, FALSE},             /* t */
+       {"ww", 2, dch_date, DCH_WW, TRUE},              /* w */
+       {"w", 1, dch_date, DCH_W, TRUE},
+       {"y,yyy", 5, dch_date, DCH_Y_YYY, TRUE},        /* y */
+       {"yyyy", 4, dch_date, DCH_YYYY, TRUE},
+       {"yyy", 3, dch_date, DCH_YYY, TRUE},
+       {"yy", 2, dch_date, DCH_YY, TRUE},
+       {"y", 1, dch_date, DCH_Y, TRUE},
 /* last */
 {NULL, 0, NULL, 0}};
 
 /* ----------
- * KeyWords for NUMBER version
+ * KeyWords for NUMBER version (now, isdigit info is not needful here..)
  * ----------
  */
 static KeyWord NUM_keywords[] = {
                                 * Skip blank space in FROM_CHAR's input
                                 * ----------
                                 */
-                               if (isspace(n->character) && IS_FX == 0)
+                               if (isspace(n->character) && IS_FX == 0)
                                {
                                        while (*s != '\0' && isspace((int) *(s + 1)))
                                                ++s;
        return -1;
 }
 
+/* ----------
+ * Return TRUE if next format picture is not digit value
+ * ----------
+ */
+static bool
+is_next_separator(FormatNode *n)
+{
+       if (n->type == NODE_TYPE_END)
+               return FALSE;
+       
+       if (n->type == NODE_TYPE_ACTION && S_THth(n->suffix))
+               return TRUE;
+       
+       /* 
+        * Next node 
+        */
+       n++;    
+       
+       if (n->type == NODE_TYPE_END)
+               return FALSE;
+       
+       if (n->type == NODE_TYPE_ACTION)
+       {
+               if (n->key->isdigit)
+                       return FALSE;
+       
+               return TRUE;    
+       } 
+       else if (isdigit(n->character))
+               return FALSE;
+       
+       return TRUE;            /* some non-digit input (separator) */  
+}
+
 #define AMPM_ERROR     elog(ERROR, "to_timestamp(): bad AM/PM string")
 
 /* ----------
                        }
                        else if (flag == FROM_CHAR) 
                        {
-                               sscanf(inout, "%d", &tmfc->ssss);
+                               if (is_next_separator(node))
+                                       sscanf(inout, "%d", &tmfc->ssss);
+                               else
+                                       sscanf(inout, "%05d", &tmfc->ssss);     
                                return int4len((int4) tmfc->ssss) - 1 + SKIP_THth(suf);
                        }
                        break;
                        }
                        else if (flag == FROM_CHAR)
                        {
-                               sscanf(inout, "%d", &tmfc->yyyy);
+                               if (is_next_separator(node))
+                                       sscanf(inout, "%d", &tmfc->yyyy);
+                               else
+                                       sscanf(inout, "%04d", &tmfc->yyyy);
+                                               
                                if (!S_FM(suf) && tmfc->yyyy <= 9999 && tmfc->yyyy >= -9999)
                                        len = 4;
                                else
                        }
                        else if (flag == FROM_CHAR)
                        {
-                               sscanf(inout, "%03d", &tmfc->yyyy);
+                               sscanf(inout, "%03d", &tmfc->yyy);
                                return 2 + SKIP_THth(suf);
                        }
                        break;
                        }
                        else if (flag == FROM_CHAR)
                        {
-                               sscanf(inout, "%02d", &tmfc->yyyy);
+                               sscanf(inout, "%02d", &tmfc->yy);
                                return 1 + SKIP_THth(suf);
                        }
                        break;
                        }
                        else if (flag == FROM_CHAR)
                        {
-                               sscanf(inout, "%1d", &tmfc->yyyy);
+                               sscanf(inout, "%1d", &tmfc->y);
                                return 0 + SKIP_THth(suf);
                        }
                        break;
        
        if (tmfc->yyyy) 
                tm->tm_year = tmfc->yyyy;
+
+       else if (tmfc->y)
+       {
+               /*
+                * 1-digit year:
+                *      always +2000
+                */
+               tm->tm_year = tmfc->y + 2000;   
+       }       
+       else if (tmfc->yy)
+       {
+               /*
+                * 2-digit year:
+                *      '00' ... '69'  = 2000 ... 2069
+                *      '70' ... '99'  = 1970 ... 1999
+                */     
+               tm->tm_year = tmfc->yy;
        
-       if (tmfc->j)
-               j2date(tmfc->j, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+               if (tm->tm_year < 70)
+                       tm->tm_year += 2000;
+               else 
+                       tm->tm_year += 1900;
+       }
+       else if (tmfc->yyy)
+       {
+               /*
+                * 3-digit year:
+                *      '100' ... '999' = 1100 ... 1999
+                *      '000' ... '099' = 2000 ... 2099
+                */
+               tm->tm_year = tmfc->yyy;
        
-       if (tmfc->bc && tm->tm_year > 0)
-               tm->tm_year = -(tm->tm_year);
+               if (tm->tm_year >= 100)
+                       tm->tm_year += 1000;
+               else 
+                       tm->tm_year += 2000;
+       }
+
+               
+       if (tmfc->bc)
+       {
+               if (tm->tm_year > 0)
+                       tm->tm_year = -(tm->tm_year - 1);
+               else
+                       elog(ERROR, "Inconsistant use of year %04d and 'BC'", tm->tm_year);
+       }       
        
-       if (tm->tm_year < 0)
-               tm->tm_year = tm->tm_year + 1;
+       if (tmfc->j)
+               j2date(tmfc->j, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
        
        if (tmfc->iw)
                isoweek2date(tmfc->iw, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);