From: Matthew Kerwin Date: 2012-12-11T10:51:12+09:00 Subject: Re: Time.new(2001, 12, 3).to_i returns wrong value --f46d04287a17420b9704d089e816 Content-Type: text/plain; charset=ISO-8859-1 On 11 December 2012 11:13, Robert Buck wrote: > Yes, the big problem here is that, since what I am writing is a database > driver, users can throw anything at me. So I have no control over how > the Time/Date objects are created. If you're writing the driver, you can define the API. If you specify clearly what is allowed and how it will be interpreted, there's not (much of) a problem. > But at the database interface I need > to normalize, for both inserts and queries. Since the internal database > API assumes those date/times that are passed as millis since the epoch > are UTC, I do that conversion explicitly using offsets. I'm still having trouble understanding "since the internal database API assumes those date/times that are passed as millis since the epoch are UTC ..." It's my understand that [milli]seconds-since-the-epoch is a timezone-agnostic value, because there was only one epoch, everywhere in the world, at the same instant, irrespective of what was showing on your wall-clock at that time. The time that was 1_098_293_801 seconds after the epoch may be written as "2004-10-20 17:36:41 UTC" or "2004-10-21 03:36:41 +1000" or whatever, but it's still the same time. Thus, if the user provides you with an integer, no interpretation is required on your part. Store it as an integer. And in Ruby you can use Time.at(seconds_since_epoch) , or if you really want to see it as a UTC string, Time.at(seconds_since_epoch).utc.strftime('%FT%TZ') or whatever. Conversely, if you allow the user to provide you with a string, like 'YYYY-MM-DD' you have to have some explicit rules about how that will be converted to either a timezone-aware Time object, or the equivalent timezone-agnostic seconds-since-the-epoch value. > For string > representations during inserts I provide my own quote_date function in > the AR Adapter. Exactly. > On the return route I have resorted to always providing > Date/Time in local timezone, applying the opposite adjustment described > above. When returning values from the database, assuming they're stored either as timezone-agnostic seconds-since-the-epoch (INTEGER) values, or as timezone-aware DATETIME fields, you can reconstruct a Time object precisely (using either Time::at , or Time::mktime in the long form). There's no "resorting" to anything. -- Matthew Kerwin, B.Sc (CompSci) (Hons) http://matthew.kerwin.net.au/ ABN: 59-013-727-651 "You'll never find a programming language that frees you from the burden of clarifying your ideas." - xkcd --f46d04287a17420b9704d089e816 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
On 11 December 2012 11:13, Robert Buck <lists@ruby-forum.com= > wrote:
Yes, the big problem here is that, since what I am writing is a database driver, users can throw anything at me. So I have no control over how
the Time/Date objects are created.

If you&#= 39;re writing the driver, you can define the API. =A0If you specify clearly= what is allowed and how it will be interpreted, there's not (much of) = a problem.
=A0
But at the database interface I need
to normalize, for both inserts and queries. Since the internal database
API assumes those date/times that are passed as millis since the epoch
are UTC, I do that conversion explicitly using offsets.
I'm still having trouble understanding "since the int= ernal database=A0API assumes those date/times that are passed as millis sin= ce the epoch=A0are UTC ..." =A0It's my understand that [milli]seco= nds-since-the-epoch is a timezone-agnostic value, because there was only on= e epoch, everywhere in the world, at the same instant, irrespective of what= was showing on your wall-clock at that time.

The time that was=A01_098_293_801 seconds after the epo= ch may be written as "2004-10-20 17:36:41 UTC" or "2004-10-2= 1 03:36:41 +1000" or whatever, but it's still the same time.

Thus, if the user provides you with an integer, no inte= rpretation is required on your part. =A0Store it as an integer. =A0And in R= uby you can use Time.at(seconds_since_epoch) , or if you really want to see= it as a UTC string, Time.at(seconds_since_epoch).utc.strftime('%FT%TZ&= #39;) or whatever.

Conversely, if you allow the user to provide you = with a string, like 'YYYY-MM-DD' you have to have some explicit rul= es about how that will be converted to either a timezone-aware Time object,= or the equivalent timezone-agnostic seconds-since-the-epoch value.
=A0
For string
representations during inserts I provide my own quote_date function in
the AR Adapter.

Exactly.
=A0
On the return route I have resorted to always providing
Date/Time in local timezone, applying the opposite adjustment described
above.

When returning values from the= database, assuming they're stored either as timezone-agnostic seconds-= since-the-epoch (INTEGER) values, or as timezone-aware DATETIME fields, you= can reconstruct a Time object precisely (using either Time::at , or Time::= mktime in the long form). =A0There's no "resorting" to anythi= ng.

--
=A0 Matthew Kerwin, B.Sc (CompSci) (Hons)
=A0 http://matthew.kerw= in.net.au/
=A0 ABN: 59-013-727-651

=A0 "You'll never= find a programming language that frees
=A0 you from the burden of clarifying your ideas." - xkcd
--f46d04287a17420b9704d089e816--