1 /*******************************************************************************
2 
3         Copyright:
4             Copyright (c) 2007 Kris Bell.
5             Some parts copyright (c) 2009-2016 dunnhumby Germany GmbH.
6             All rights reserved.
7 
8         License:
9             Tango Dual License: 3-Clause BSD License / Academic Free License v3.0.
10             See LICENSE_TANGO.txt for details.
11 
12         Version: Apr 2007: split away from utc
13 
14         Authors: Kris
15 
16 *******************************************************************************/
17 
18 module ocean.time.WallClock;
19 
20 import core.sys.posix.sys.time;
21 import core.sys.posix.time;
22 import ocean.time.Clock;
23 public import ocean.time.Time;
24 
25 
26 /******************************************************************************
27 
28         Exposes wall-time relative to Jan 1st, 1 AD. These values are
29         based upon a clock-tick of 100ns, giving them a span of greater
30         than 10,000 years. These Units of time are the foundation of most
31         time and date functionality in Tango contributors.
32 
33         Please note that conversion between UTC and Wall time is performed
34         in accordance with the OS facilities.
35         Posix system calculates based on a provided point in time).
36         They should typically have the TZ environment variable set to
37         a valid descriptor.
38 
39 *******************************************************************************/
40 
41 struct WallClock
42 {
43     /***************************************************************************
44 
45         Returns
46             the current local time
47 
48     ***************************************************************************/
49 
50     static Time now ()
51     {
52         tm t = void;
53         timeval tv = void;
54         gettimeofday (&tv, null);
55         localtime_r (&tv.tv_sec, &t);
56         tv.tv_sec = timegm (&t);
57         return Clock.convert (tv);
58     }
59 
60     /***************************************************************************
61 
62         Returns
63             the timezone relative to GMT. The value is negative when west of GMT
64 
65     ***************************************************************************/
66 
67     static TimeSpan zone ()
68     {
69         return TimeSpan.fromSeconds(-timezone);
70     }
71 
72     /***************************************************************************
73 
74         Set fields to represent a local version of the current UTC time
75 
76         All values must fall within the domain supported by the OS
77 
78     ***************************************************************************/
79 
80     static DateTime toDate ()
81     {
82         return toDate (Clock.now);
83     }
84 
85     /***************************************************************************
86 
87         Set fields to represent a local version of the provided UTC time
88 
89         All values must fall within the domain supported by the OS
90 
91     ***************************************************************************/
92 
93     static DateTime toDate (Time utc)
94     {
95         DateTime dt = void;
96         auto timeval = Clock.convert (utc);
97         dt.time.millis = cast(uint) (timeval.tv_usec / 1000);
98 
99         tm t = void;
100         localtime_r (&timeval.tv_sec, &t);
101 
102         dt.date.year    = t.tm_year + 1900;
103         dt.date.month   = t.tm_mon + 1;
104         dt.date.day     = t.tm_mday;
105         dt.date.dow     = t.tm_wday;
106         dt.date.era     = 0;
107         dt.time.hours   = t.tm_hour;
108         dt.time.minutes = t.tm_min;
109         dt.time.seconds = t.tm_sec;
110 
111         Clock.setDoy(dt);
112         return dt;
113     }
114 
115     /***************************************************************************
116 
117         Convert Date fields to local time
118 
119     ***************************************************************************/
120 
121     static Time fromDate (ref DateTime dt)
122     {
123         tm t = void;
124 
125         t.tm_year = dt.date.year - 1900;
126         t.tm_mon  = dt.date.month - 1;
127         t.tm_mday = dt.date.day;
128         t.tm_hour = dt.time.hours;
129         t.tm_min  = dt.time.minutes;
130         t.tm_sec  = dt.time.seconds;
131 
132         auto seconds = mktime (&t);
133         return Time.epoch1970 + TimeSpan.fromSeconds(seconds)
134             + TimeSpan.fromMillis(dt.time.millis);
135     }
136 
137         /***********************************************************************
138 
139         ***********************************************************************/
140 
141         static Time toLocal (Time utc)
142         {
143                 auto mod = utc.ticks % TimeSpan.TicksPerMillisecond;
144                 auto date=toDate(utc);
145                 return Clock.fromDate(date) + TimeSpan(mod);
146         }
147 
148         /***********************************************************************
149 
150         ***********************************************************************/
151 
152         static Time toUtc (Time wall)
153         {
154                 auto mod = wall.ticks % TimeSpan.TicksPerMillisecond;
155                 auto date=Clock.toDate(wall);
156                 return fromDate(date) + TimeSpan(mod);
157         }
158 }
159 
160 
161 static this()
162 {
163     tzset();
164 }