summaryrefslogtreecommitdiff
path: root/usr/src/lib/libast/common/tm/tmxmake.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libast/common/tm/tmxmake.c')
-rw-r--r--usr/src/lib/libast/common/tm/tmxmake.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/tm/tmxmake.c b/usr/src/lib/libast/common/tm/tmxmake.c
new file mode 100644
index 0000000000..5c49499b96
--- /dev/null
+++ b/usr/src/lib/libast/common/tm/tmxmake.c
@@ -0,0 +1,134 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2007 AT&T Knowledge Ventures *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Knowledge Ventures *
+* *
+* A copy of the License is available at *
+* http://www.opensource.org/licenses/cpl1.0.txt *
+* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+
+#include "FEATURE/tmlib"
+
+/*
+ * return Tm_t for t
+ * time zone and leap seconds accounted for in return value
+ */
+
+Tm_t*
+tmxmake(Time_t t)
+{
+ register struct tm* tp;
+ register Tm_leap_t* lp;
+ Time_t x;
+ time_t now;
+ int leapsec;
+ int y;
+ uint32_t n;
+ int32_t o;
+#if TMX_FLOAT
+ Time_t z;
+ uint32_t i;
+#endif
+ Tm_t tm;
+
+ static Tm_t ts;
+
+ tmset(tm_info.zone);
+ leapsec = 0;
+ if ((tm_info.flags & (TM_ADJUST|TM_LEAP)) == (TM_ADJUST|TM_LEAP) && (n = tmxsec(t)))
+ {
+ for (lp = &tm_data.leap[0]; n < lp->time; lp++);
+ if (lp->total)
+ {
+ if (n == lp->time && (leapsec = (lp->total - (lp+1)->total)) < 0)
+ leapsec = 0;
+ t = tmxsns(n - lp->total, tmxnsec(t));
+ }
+ }
+ x = tmxsec(t);
+ if (tm_info.flags & TM_UTC)
+ {
+ tm.tm_zone = &tm_data.zone[2];
+ o = 0;
+ }
+ else
+ {
+ tm.tm_zone = tm_info.zone;
+ o = 60 * tm.tm_zone->west;
+ if (x > o)
+ {
+ x -= o;
+ o = 0;
+ }
+ }
+#if TMX_FLOAT
+ i = x / (24 * 60 * 60);
+ z = i;
+ n = x - z * (24 * 60 * 60);
+ tm.tm_sec = n % 60 + leapsec;
+ n /= 60;
+ tm.tm_min = n % 60;
+ n /= 60;
+ tm.tm_hour = n % 24;
+#define x i
+#else
+ tm.tm_sec = x % 60 + leapsec;
+ x /= 60;
+ tm.tm_min = x % 60;
+ x /= 60;
+ tm.tm_hour = x % 24;
+ x /= 24;
+#endif
+ tm.tm_wday = (x + 4) % 7;
+ tm.tm_year = (400 * (x + 25202)) / 146097 + 1;
+ n = tm.tm_year - 1;
+ x -= n * 365 + n / 4 - n / 100 + (n + (1900 - 1600)) / 400 - (1970 - 1901) * 365 - (1970 - 1901) / 4;
+ tm.tm_mon = 0;
+ tm.tm_mday = x + 1;
+ tmfix(&tm);
+ n += 1900;
+ tm.tm_isdst = 0;
+ if (tm.tm_zone->daylight)
+ {
+ if ((y = tmequiv(&tm) - 1900) == tm.tm_year)
+ now = tmxsec(t);
+ else
+ {
+ Tm_t te;
+
+ te = tm;
+ te.tm_year = y;
+ now = tmxsec(tmxtime(&te, tm.tm_zone->west));
+ }
+ if ((tp = tmlocaltime(&now)) && ((tm.tm_isdst = tp->tm_isdst) || o))
+ {
+ tm.tm_min -= o / 60 + (tm.tm_isdst ? tm.tm_zone->dst : 0);
+ tmfix(&tm);
+ }
+ }
+ tm.tm_nsec = tmxnsec(t);
+ ts = tm;
+ return &ts;
+}