*
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.179 2007/07/06 04:15:59 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.180 2007/07/18 03:13:13 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
    if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
        timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
    {
-       fsec = (fsec1 - fsec2);
+       /* form the symbolic difference */
+       fsec = fsec1 - fsec2;
        tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
        tm->tm_min = tm1->tm_min - tm2->tm_min;
        tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
            tm->tm_year = -tm->tm_year;
        }
 
+       /* propagate any negative fields into the next higher field */
+       while (fsec < 0)
+       {
+#ifdef HAVE_INT64_TIMESTAMP
+           fsec += USECS_PER_SEC;
+#else
+           fsec += 1.0;
+#endif
+           tm->tm_sec--;
+       }
+
        while (tm->tm_sec < 0)
        {
            tm->tm_sec += SECS_PER_MINUTE;
    if (timestamp2tm(dt1, &tz1, tm1, &fsec1, &tzn, NULL) == 0 &&
        timestamp2tm(dt2, &tz2, tm2, &fsec2, &tzn, NULL) == 0)
    {
+       /* form the symbolic difference */
        fsec = fsec1 - fsec2;
        tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
        tm->tm_min = tm1->tm_min - tm2->tm_min;
            tm->tm_year = -tm->tm_year;
        }
 
+       /* propagate any negative fields into the next higher field */
+       while (fsec < 0)
+       {
+#ifdef HAVE_INT64_TIMESTAMP
+           fsec += USECS_PER_SEC;
+#else
+           fsec += 1.0;
+#endif
+           tm->tm_sec--;
+       }
+
        while (tm->tm_sec < 0)
        {
            tm->tm_sec += SECS_PER_MINUTE;