7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.22 1997/05/23 05:24:47 thomas Exp $
10
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.23 1997/05/30 15:02:51 thomas Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -44,6 +44,12 @@ char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
44
44
char * days [] = {"Sunday" , "Monday" , "Tuesday" , "Wednesday" ,
45
45
"Thursday" , "Friday" , "Saturday" , NULL };
46
46
47
+ /* TMODULO()
48
+ * Macro to replace modf(), which is broken on some platforms.
49
+ */
50
+ #define TMODULO (t ,q ,u ) {q = ((t < 0)? ceil(t / u): floor(t / u)); \
51
+ if (q != 0) t -= rint(q * u);}
52
+
47
53
48
54
/*****************************************************************************
49
55
* USER I/O ROUTINES *
@@ -1556,6 +1562,9 @@ int j2day( int date)
1556
1562
* Returns:
1557
1563
* 0 on success
1558
1564
* -1 on out of range
1565
+ *
1566
+ * For dates within the system-supported time_t range, convert to the
1567
+ * local time zone. If out of this range, leave as GMT. - tgl 97/05/27
1559
1568
*/
1560
1569
int
1561
1570
datetime2tm ( DateTime dt , int * tzp , struct tm * tm , double * fsec , char * * tzn )
@@ -1568,7 +1577,9 @@ datetime2tm( DateTime dt, int *tzp, struct tm *tm, double *fsec, char **tzn)
1568
1577
1569
1578
1570
1579
date0 = date2j (2000 ,1 ,1 );
1571
- time = (modf ( dt /86400 , & date )* 86400 );
1580
+
1581
+ time = dt ;
1582
+ TMODULO (time ,date ,86400e0 );
1572
1583
1573
1584
if (time < 0 ) {
1574
1585
time += 86400 ;
@@ -1594,24 +1605,30 @@ printf( "datetime2tm- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_m
1594
1605
printf ( "datetime2tm- time is %02d:%02d:%02.0f\n" , tm -> tm_hour , tm -> tm_min , sec );
1595
1606
#endif
1596
1607
1597
- * fsec = modf ( JROUND (sec ), & sec );
1598
- tm -> tm_sec = sec ;
1608
+ * fsec = JROUND (sec );
1609
+ TMODULO ( * fsec , tm -> tm_sec , 1 ) ;
1599
1610
1600
1611
#ifdef DATEDEBUG
1601
1612
printf ( "datetime2tm- time is %02d:%02d:%02d %.7f\n" , tm -> tm_hour , tm -> tm_min , tm -> tm_sec , * fsec );
1602
1613
#endif
1603
1614
1604
1615
if (tzp != NULL ) {
1605
- /* XXX HACK to get time behavior compatible with Postgres v6.0 - tgl 97/04/07 */
1606
1616
if (IS_VALID_UTIME ( tm -> tm_year , tm -> tm_mon , tm -> tm_mday )) {
1607
1617
utime = (dt + (date0 - date2j (1970 ,1 ,1 ))* 86400 );
1608
1618
1609
1619
#ifdef USE_POSIX_TIME
1610
1620
tx = localtime (& utime );
1611
1621
#ifdef DATEDEBUG
1622
+ #ifdef HAVE_INT_TIMEZONE
1612
1623
printf ( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n" ,
1613
1624
tx -> tm_year , tx -> tm_mon , tx -> tm_mday , tx -> tm_hour , tx -> tm_min , sec ,
1614
1625
tzname [0 ], tzname [1 ], tx -> tm_isdst );
1626
+ #else
1627
+ printf ( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s dst=%d\n" ,
1628
+ tx -> tm_year , tx -> tm_mon , tx -> tm_mday , tx -> tm_hour , tx -> tm_min , sec ,
1629
+ tx -> tm_zone , tx -> tm_isdst );
1630
+ #endif
1631
+ #else
1615
1632
#endif
1616
1633
tm -> tm_year = tx -> tm_year + 1900 ;
1617
1634
tm -> tm_mon = tx -> tm_mon + 1 ;
@@ -1626,6 +1643,9 @@ printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
1626
1643
if (tzn != NULL ) * tzn = tzname [(tm -> tm_isdst > 0 )];
1627
1644
1628
1645
#else /* !HAVE_INT_TIMEZONE */
1646
+ tm -> tm_gmtoff = tx -> tm_gmtoff ;
1647
+ tm -> tm_zone = tx -> tm_zone ;
1648
+
1629
1649
* tzp = (tm -> tm_isdst ? (tm -> tm_gmtoff - 3600 ): tm -> tm_gmtoff ); /* tm_gmtoff is Sun/DEC-ism */
1630
1650
if (tzn != NULL ) * tzn = tm -> tm_zone ;
1631
1651
#endif
@@ -1634,6 +1654,7 @@ printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
1634
1654
* tzp = CTimeZone ; /* V7 conventions; don't know timezone? */
1635
1655
if (tzn != NULL ) * tzn = CTZName ;
1636
1656
#endif
1657
+
1637
1658
} else {
1638
1659
* tzp = 0 ;
1639
1660
tm -> tm_isdst = 0 ;
@@ -1653,10 +1674,12 @@ printf( "datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, t
1653
1674
#endif
1654
1675
1655
1676
#ifdef DATEDEBUG
1677
+ #ifdef USE_POSIX_TIME
1656
1678
#ifdef HAVE_INT_TIMEZONE
1657
1679
printf ( "datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n" ,
1658
1680
tzname [tm -> tm_isdst != 0 ], ((tzp != NULL )? * tzp : 0 ), CTimeZone , CDayLight );
1659
1681
#endif
1682
+ #endif
1660
1683
#endif
1661
1684
1662
1685
return 0 ;
@@ -1690,6 +1713,9 @@ printf( "tm2datetime- time is %f %02d:%02d:%02d %f\n", time, tm->tm_hour, tm->tm
1690
1713
} /* tm2datetime() */
1691
1714
1692
1715
1716
+ /* timespan2tm()
1717
+ * Convert a timespan data type to a tm structure.
1718
+ */
1693
1719
int
1694
1720
timespan2tm (TimeSpan span , struct tm * tm , float8 * fsec )
1695
1721
{
@@ -1710,19 +1736,10 @@ timespan2tm(TimeSpan span, struct tm *tm, float8 *fsec)
1710
1736
time = span .time ;
1711
1737
#endif
1712
1738
1713
- funit = modf ( (time / 86400 ), & iunit );
1714
- tm -> tm_mday = iunit ;
1715
- if (tm -> tm_mday != 0 ) time -= rint (tm -> tm_mday * 86400 );
1716
-
1717
- funit = modf ( (time / 3600 ), & iunit );
1718
- tm -> tm_hour = iunit ;
1719
- if (tm -> tm_hour != 0 ) time -= rint (tm -> tm_hour * 3600e0 );
1720
- funit = modf ( (time / 60 ), & iunit );
1721
- tm -> tm_min = iunit ;
1722
- if (tm -> tm_min != 0 ) time -= rint (tm -> tm_min * 60e0 );
1723
- funit = modf ( time , & iunit );
1724
- tm -> tm_sec = iunit ;
1725
- if (tm -> tm_sec != 0 ) time -= tm -> tm_sec ;
1739
+ TMODULO (time , tm -> tm_mday , 86400e0 );
1740
+ TMODULO (time , tm -> tm_hour , 3600e0 );
1741
+ TMODULO (time , tm -> tm_min , 60e0 );
1742
+ TMODULO (time , tm -> tm_sec , 1 );
1726
1743
* fsec = time ;
1727
1744
1728
1745
#ifdef DATEDEBUG
@@ -1901,6 +1918,11 @@ printf( "ParseDateTime- set field[%d] to %s type %d\n", (nf-1), field[nf-1], fty
1901
1918
* Also supports input in compact time:
1902
1919
* "970207 152327"
1903
1920
* "97038 152327"
1921
+ *
1922
+ * Use the system-provided functions to get the current time zone
1923
+ * if not specified in the input string.
1924
+ * If the date is outside the time_t system-supported time range,
1925
+ * then assume GMT time zone. - tgl 97/05/27
1904
1926
*/
1905
1927
int
1906
1928
DecodeDateTime ( char * field [], int ftype [], int nf ,
@@ -2090,7 +2112,6 @@ printf( " %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
2090
2112
return (((fmask & DTK_TIME_M ) == DTK_TIME_M )? 1 : -1 );
2091
2113
2092
2114
/* timezone not specified? then find local timezone if possible */
2093
- /* XXX HACK to get correct behavior relative to Postgres v6.0 - tgl 97/04/07 */
2094
2115
if ((* dtype == DTK_DATE ) && ((fmask & DTK_DATE_M ) == DTK_DATE_M )
2095
2116
&& (tzp != NULL ) && (! (fmask & DTK_M (TZ )))) {
2096
2117
@@ -2105,9 +2126,11 @@ printf( " %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
2105
2126
2106
2127
#ifdef HAVE_INT_TIMEZONE
2107
2128
* tzp = ((tm -> tm_isdst > 0 )? (timezone - 3600 ): timezone );
2129
+
2108
2130
#else /* !HAVE_INT_TIMEZONE */
2109
- * tzp = tm -> tm_gmtoff ;
2131
+ * tzp = - ( tm -> tm_gmtoff ); /* tm_gmtoff is Sun/DEC-ism */
2110
2132
#endif
2133
+
2111
2134
#else /* !USE_POSIX_TIME */
2112
2135
* tzp = CTimeZone ;
2113
2136
#endif
@@ -2803,7 +2826,7 @@ printf( "DecodeDateDelta- (%08x/%08x) field[%d] %s value is %d\n",
2803
2826
};
2804
2827
2805
2828
if (* fsec != 0 ) {
2806
- * fsec = modf ( * fsec , & sec );
2829
+ TMODULO ( * fsec ,sec , 1 );
2807
2830
tm -> tm_sec += sec ;
2808
2831
};
2809
2832
0 commit comments