std.datetime impenetrable

Jonathan M Davis jmdavisProg at gmx.com
Thu Sep 15 12:03:56 PDT 2011


On Thursday, September 15, 2011 10:48 Steve Teale wrote:
> Looking at the documentation makes my head hurt, especially if I have
> consumed some beer, when I am not pure and immutable.

For an overview, check out http://d-programming-language.org/intro-to-
datetime.html

I'd _love_ to fix the links on the top of the page, but ddoc needs some 
improvements with regards to how it generates anchor names for that to be 
possible (anchors are based solely on function or type names with no concept 
of scaping, so every function with the same name ends up with the same anchor 
regardless of whether it's a free function or what it's a member function of).

> Can anyone help me to understand how to determine what timezone the user
> has selected to be his/hers.
> 
> Alternatively, let me explain my desire. When my program first runs, I want
> to hazard a guess as to what size of paper the user is likely to use - US
> Letter Size, or A4/inches or metric. GTK does not seem to want to tell me
> about the default printer settings - could be the beer of course.
> 
> The timezone might allow me to bracket the USA, Canada, and Mexico though
> of course then the poor sods in South America and the Philippines and so
> on would be SOL.
> 
> Anyway, how would you do it?

Determining the exact time zone that the computer is in is really hard. It's 
actually pretty easy to do in Windows, but on Posix... not so much. So, 
there's no function in std.datetime to do it. If I can ever figure out how to 
sanely do it on Posix, then I'll add it, but until then, it's not there.

If all you want to do is bracket it, then you can just use the UTC offset for 
the time zone. Because the UTC offset varies depending on the time of year (or 
even from year to year), you can't just ask a TimeZone for its UTC offset, but 
I do have a pull request which makes it possible to ask what the UTC offset is 
at a particular std time or to ask a SysTime what its UTC offset is - but that 
hasn't been released yet. So, if you wanted to find out what the offset was 
right now in the current time zone, you would do

auto sysTime = Clock.currTime();
auto utcOffset = dur!"hnsecs"(sysTime.timezone.utcToTZ(sysTime.stdTime) - 
sysTime.stdTime);

So, for instance, America/Los_Angeles would give you an offset of -7 hours 
right now and -8 during the Winter. If you then wanted to narrow the 
hemisphere, you can do it in _some_ cases by checking whether DST is in effect 
in July:

auto north = SysTime(Date(2011, 7, 1)).dstInEffect;

but that will only work if the timezone has DST (and a large chunk of the 
Southern Hemisphere does not). If you were just trying to bracket USA, Canada, 
and Mexico though (all of which mostly have DST), it would mostly work to do 
something like

auto jan = SysTime(Date(2011, 1, 11));
auto jul = SysTime(Date(2011, 7, 11));
auto utcOffset = dur!"hnsecs"(jan.timezone.utcToTZ(jan.stdTime) - 
jan.stdTime);
auto inBracket = jul.dstInEffect && utcOffset >= dur!"hours"(-10) && utcOffset 
<= dur!"hours"(-3) + dur!"minutes"(-30);

But that will fail for Hawaii or any other northern time zone with no DST, and 
it'll probably take in more time zones than you want it to above the equator, 
but it would _mostly_ work. But honestly, even if std.datetime _could_ tell 
you what the exact time zone was, that would still be a bit of a pain. You'd 
have to get the exact list of time zones that you cared about and compare that 
against the current time zone. It _would_ be mork accurate though. Maybe I'll 
figure out a reliable way to get the current time zone on Posix at some point, 
but unfortunately, it's not something that Posix is set up to do very easily 
(it's time zone handling is _much_ more accurate than Windows though, so 
neither OS really does it entirely right).

Of course, what you really want to do if you can't just ask what the default 
printer settings are is to do it based on locale, but I don't know how 
straightforward that is. It might just be easier to use the hack that you're 
trying to do. And the code that I gave above should do that for you.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list