1 /* Copyright (c) 1993 by Sanjay Ghemawat */
2
3 #include <stddef.h>
4 #include <sys/types.h>
5 #include <math.h>
6 #include <string.h>
7 #include <stdlib.h>
8
9 #include "config.h"
10
11 #include "Month.h"
12 #include "WeekDay.h"
13 #include "Time_.h"
14
15 /*
16 * Want to get high resolution for region of time that will be most
17 * heavily used. This region will probably be around now. Therefore,
18 * rep will be number of seconds elapsed since we construct the first
19 * Time value for this run of the program.
20 */
21
22 int Time::initialized = 0; /* Initialized yet? */
23 double Time::offset = 0.0; /* Offset for time values */
24 int Time::junkInt = 0;
25
Initialize()26 void Time::Initialize() {
27 struct timeval buf;
28 gettimeofday(&buf, 0);
29
30 offset = buf.tv_sec;
31 initialized = 1;
32 }
33
Now()34 Time Time::Now() {
35 struct timeval buf;
36 gettimeofday(&buf, 0);
37 return Time(buf);
38 }
39
BreakDownDate(int & mday,WeekDay & wday,Month & month,int & year)40 void Time::BreakDownDate(int& mday,WeekDay& wday,Month& month, int& year) const
41 {
42 this->BreakDown(mday, wday, month, year);
43 }
44
BreakDownClock(int & hour,int & min,int & sec,int & milli)45 void Time::BreakDownClock(int& hour, int& min, int& sec, int& milli) const {
46 WeekDay junkWDay;
47 Month junkMonth;
48
49 BreakDown(junkInt,junkWDay,junkMonth,junkInt, hour, min, sec, milli);
50 }
51
BreakDown(int & mday,WeekDay & wday,Month & month,int & year,int & hour,int & min,int & sec,int & milli,const char * tz)52 void Time::BreakDown(int& mday, WeekDay& wday, Month& month, int& year,
53 int& hour, int& min, int& sec, int& milli,
54 const char *tz) const
55 {
56 char *old;
57 if (! initialized) Initialize();
58
59 time_t clock = (time_t) round(rep + offset);
60
61 if (tz) {
62 if ((old=getenv("TZ"))) old=strdup(old);
63 setenv("TZ", tz, 1);
64 tzset();
65 }
66
67 struct tm* t = localtime(&clock);
68
69 if (tz) {
70 if (old) setenv("TZ", old, 1); else unsetenv("TZ");
71 tzset();
72 free(old);
73 }
74
75 mday = t->tm_mday; /* tm_mday in 1..31 */
76 wday = WeekDay::Sunday() + t->tm_wday; /* tm_wday in 0..6. Sun = 0 */
77 month = Month::January() + t->tm_mon; /* tm_mon in 0..11. Jan = 0 */
78 year = t->tm_year + 1900;
79 hour = t->tm_hour;
80 min = t->tm_min;
81 sec = t->tm_sec;
82 milli = (int)round((rep - floor(rep)) * 1000);
83 }
84
Time(const struct timeval & tv)85 Time::Time(const struct timeval& tv) {
86 if (! initialized) Initialize();
87 rep = (tv.tv_sec - offset) + ((double) tv.tv_usec) / 1000000.0;
88 }
89
Convert(struct timeval & tv)90 void Time::Convert(struct timeval& tv) const {
91 if (! initialized) Initialize();
92
93 tv.tv_sec = (long) floor(rep + offset);
94 tv.tv_usec = (long) round((rep + offset - tv.tv_sec) * 1000000.0);
95 }
96
97 #if 0
98 time_t timezone_to_local(time_t clock, const char *tz) {
99 const char *old=getenv("TZ");
100 if (old) old=strdupa(old);
101
102 struct tm* t = localtime(&clock);
103 setenv("TZ", tz, 1);
104 tzset();
105
106 clock = mktime(t);
107 if (old) setenv("TZ", old, 1); else unsetenv("TZ");
108 tzset();
109
110 return clock;
111 }
112
113 time_t local_to_timezone(time_t clock, const char *tz) {
114 const char *old=getenv("TZ");
115 if (old) old=strdupa(old);
116
117 setenv("TZ", tz, 1);
118 tzset();
119 struct tm* t = localtime(&clock);
120
121 if (old) setenv("TZ", old, 1); else unsetenv("TZ");
122 tzset();
123 clock = mktime(t);
124
125 return clock;
126 }
127 #endif
128
Duration(const struct timeval & tv)129 Duration::Duration(const struct timeval& tv) {
130 rep = tv.tv_sec + ((double) tv.tv_usec) / 1000000.0;
131 }
132
Convert(struct timeval & tv)133 void Duration::Convert(struct timeval& tv) const {
134 tv.tv_sec = (long) floor(rep);
135 tv.tv_usec = (long) round((rep - tv.tv_sec) / 1000000.0);
136 }
137