123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
|
/*******************************************************************************
copyright: Copyright (c) 2007 Kris Bell. All rights reserved
license: BSD style: $(LICENSE)
version: Apr 2007: split away from utc
author: Kris
*******************************************************************************/
module tango.time.WallClock;
public import tango.time.Time;
private import tango.time.Clock;
private import tango.sys.Common;
/******************************************************************************
Exposes wall-time relative to Jan 1st, 1 AD. These values are
based upon a clock-tick of 100ns, giving them a span of greater
than 10,000 years. These Units of time are the foundation of most
time and date functionality in Tango.
Please note that conversion between UTC and Wall time is performed
in accordance with the OS facilities. In particular, Win32 systems
behave differently to Posix when calculating daylight-savings time
(Win32 calculates with respect to the time of the call, whereas a
Posix system calculates based on a provided point in time). Posix
systems should typically have the TZ environment variable set to
a valid descriptor.
*******************************************************************************/
struct WallClock
{
version (Win32)
{
/***************************************************************
Return the current local time
***************************************************************/
@property static Time now ()
{
return Clock.now - localBias();
}
/***************************************************************
Return the timezone relative to GMT. The value is
negative when west of GMT
***************************************************************/
@property static TimeSpan zone ()
{
TIME_ZONE_INFORMATION tz = void;
auto tmp = GetTimeZoneInformation (&tz);
return TimeSpan.fromMinutes(-tz.Bias);
}
/***************************************************************
Set fields to represent a local version of the
current UTC time. All values must fall within
the domain supported by the OS
***************************************************************/
static DateTime toDate ()
{
return toDate (Clock.now);
}
/***************************************************************
Set fields to represent a local version of the
provided UTC time. All values must fall within
the domain supported by the OS
***************************************************************/
static DateTime toDate (const(Time) utc)
{
return Clock.toDate (utc - localBias());
}
/***************************************************************
Convert Date fields to local time
***************************************************************/
static Time fromDate (ref const(DateTime) date)
{
return (Clock.fromDate(date) + localBias());
}
/***************************************************************
Retrieve the local bias, including DST adjustment.
Note that Win32 calculates DST at the time of call
rather than based upon a point in time represented
by an argument.
***************************************************************/
private static TimeSpan localBias ()
{
int bias;
TIME_ZONE_INFORMATION tz = void;
switch (GetTimeZoneInformation (&tz))
{
default:
bias = tz.Bias;
break;
case 1:
bias = tz.Bias + tz.StandardBias;
break;
case 2:
bias = tz.Bias + tz.DaylightBias;
break;
}
return TimeSpan.fromMinutes(bias);
}
}
version (Posix)
{
/***************************************************************
Return the current local time
***************************************************************/
@property static Time now ()
{
tm t = void;
timeval tv = void;
gettimeofday (&tv, null);
localtime_r (&tv.tv_sec, &t);
tv.tv_sec = timegm (&t);
return Clock.convert (tv);
}
/***************************************************************
Return the timezone relative to GMT. The value is
negative when west of GMT
***************************************************************/
@property static TimeSpan zone ()
{
version (darwin)
{
timezone_t tz = void;
gettimeofday (null, &tz);
return TimeSpan.fromMinutes(-tz.tz_minuteswest);
}
else
return TimeSpan.fromSeconds(-timezone);
}
/***************************************************************
Set fields to represent a local version of the
current UTC time. All values must fall within
the domain supported by the OS
***************************************************************/
static DateTime toDate ()
{
return toDate (Clock.now);
}
/***************************************************************
Set fields to represent a local version of the
provided UTC time. All values must fall within
the domain supported by the OS
***************************************************************/
static DateTime toDate (const(Time) utc)
{
DateTime dt = void;
auto timeval = Clock.convert (utc);
dt.time.millis = cast(uint)timeval.tv_usec / 1000;
tm t = void;
localtime_r (&timeval.tv_sec, &t);
dt.date.year = t.tm_year + 1900;
dt.date.month = t.tm_mon + 1;
dt.date.day = t.tm_mday;
dt.date.dow = t.tm_wday;
dt.date.era = 0;
dt.time.hours = t.tm_hour;
dt.time.minutes = t.tm_min;
dt.time.seconds = t.tm_sec;
Clock.setDoy(dt);
return dt;
}
/***************************************************************
Convert Date fields to local time
***************************************************************/
static Time fromDate (ref const(DateTime) dt)
{
tm t = void;
t.tm_year = dt.date.year - 1900;
t.tm_mon = dt.date.month - 1;
t.tm_mday = dt.date.day;
t.tm_hour = dt.time.hours;
t.tm_min = dt.time.minutes;
t.tm_sec = dt.time.seconds;
auto seconds = mktime (&t);
return Time.epoch1970 + TimeSpan.fromSeconds(seconds)
+ TimeSpan.fromMillis(dt.time.millis);
}
}
/***********************************************************************
***********************************************************************/
static Time toLocal (const(Time) utc)
{
auto mod = utc.ticks % TimeSpan.TicksPerMillisecond;
auto date=toDate(utc);
return Clock.fromDate(date) + TimeSpan(mod);
}
/***********************************************************************
***********************************************************************/
static Time toUtc (const(Time) wall)
{
auto mod = wall.ticks % TimeSpan.TicksPerMillisecond;
auto date=Clock.toDate(wall);
return fromDate(date) + TimeSpan(mod);
}
}
version (Posix)
{
version (darwin) {}
else
{
shared static this()
{
tzset();
}
}
}
|