Re: simple calculation frustrations

2006-11-04 Thread Dave Rolsky

On Fri, 3 Nov 2006, Zefram wrote:


Dave Rolsky wrote:

Pretty much all DBMS's (ok, not SQLite) have support for datetime as a
data type.


Worms.  Can thereof.  A datetime type is not a primary feature of a DBMS,
so it's probably not had much attention paid to it.  Until recently,
MySQL's datetime type allowed dates such as 2006-04-31.  Even if it's
implemented correctly, it'll implement some arbitrarily selected date
model that's not particularly likely to match your need.  In this case,
timezone behaviour is the issue, and not very many datetime types handle
multiple timezones in the way desired.


Clearly, MySQL is not the gold standard for this sort of thing. It's more 
like a tin standard ;)


Postgre handles datetime type nicely, and supports real time zones.

I still think that using the built-in date and datetime types is a better 
choice than breaking it down into components and storing those. After all, 
MySQL wouldn't validate your week number either. On an OT-note, this is 
why a DBMS should have good support for creating your own types, though 
AFAIK none really do.



Using a DBMS's datetime type also loses you portability, of course.


There's another can of worms. My answer to that is I generally don't care. 
If I pick a tool I'm picking it because I want to make use of it. 
Programming in Perl loses portability too, because I need to have Perl 
(and probably a minimum version) installed too.


Anyway, this rather OT.


-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/


RE: simple calculation frustrations

2006-11-03 Thread Garrett, Philip \(MAN-Corporate\)
Matthew wrote:
 Ahh. And we have customers all over the world. Dang. See, all of this
 programming was done back shortly after we sprang forward so we
 didn't think about it.
 
 Any suggestions on how I should store a customers timezone in
 database? 

I think the best way is probably using the Olson time zone name.  These
are names like 'America/New_York' and 'Australia/Melbourne'.
http://www.twinsun.com/tz/tz-link.htm

Perl's DateTime module uses these time zones, as do MySQL = 4.1.3 and
Oracle = 9i.

Regards,
Philip


Re: simple calculation frustrations

2006-11-03 Thread Matthew
Thanks for the link Philip. I downloaded and updated all my 
/usr/share/zoneinfo then imported them into MySQL using their 
mysql_tzinfo_to_sql tool.


Is there a better way to store the time zone of our customers other than 
VARCHAR?  I noticed that the utility above created an INT indexed table 
of tzID - tzName but those tables are in the mysql database and I'd 
rather not give users permission to that table. Plus that would 
complicate SQL queries further by adding in either A) another JOIN 
statement or B) an extra SELECT to convert the INT to a name.


Any thoughts?

Thanks,
Matthew

Garrett, Philip (MAN-Corporate) wrote:

Matthew wrote:

Ahh. And we have customers all over the world. Dang. See, all of this
programming was done back shortly after we sprang forward so we
didn't think about it.

Any suggestions on how I should store a customers timezone in
database? 


I think the best way is probably using the Olson time zone name.  These
are names like 'America/New_York' and 'Australia/Melbourne'.
http://www.twinsun.com/tz/tz-link.htm

Perl's DateTime module uses these time zones, as do MySQL = 4.1.3 and
Oracle = 9i.

Regards,
Philip


Re: simple calculation frustrations

2006-11-03 Thread Dave Rolsky

On Fri, 3 Nov 2006, Zefram wrote:


OK, so you want the other behaviour.  I suggest that instead of storing
an actual timestamp you should store a broken-down time: week number,
day of week, local time of day, and (most important) timezone rule.
You can put those together in DateTime to find out what point in time
they refer to.  Increment the week number as required.


I don't think that's the best way to do it.

Pretty much all DBMS's (ok, not SQLite) have support for datetime as a 
data type. I strongly recommend you convert all datetimes to the UTC time 
zone, then storing that value. Then when you pull it out, convert it back 
to the user's preferred time zone, which you can store as a string 
(America/Chicago).


The advantage to this is that your datetime data is stored in a consistent 
way, so if you ever need to compare datetimes for some reason, you know 
that they'll compare sanely.


Some DBMS's will let you store a datetime with a timezone, in which case 
you can do that and store them in many different time zones, and stuff 
still just works. In that case either solution is fine. I don't think 
MySQL supports that though.



-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/


Re: simple calculation frustrations

2006-11-03 Thread Zefram
Dave Rolsky wrote:
Pretty much all DBMS's (ok, not SQLite) have support for datetime as a 
data type.

Worms.  Can thereof.  A datetime type is not a primary feature of a DBMS,
so it's probably not had much attention paid to it.  Until recently,
MySQL's datetime type allowed dates such as 2006-04-31.  Even if it's
implemented correctly, it'll implement some arbitrarily selected date
model that's not particularly likely to match your need.  In this case,
timezone behaviour is the issue, and not very many datetime types handle
multiple timezones in the way desired.

Using a DBMS's datetime type also loses you portability, of course.

The advantage to this is that your datetime data is stored in a consistent 
way, so if you ever need to compare datetimes for some reason, you know 
that they'll compare sanely.

I think what he wants to store isn't actually a date, as in a point in
time.  Looks like he wants to store a time of week, timezone-relative,
along with a timezone spec.  The incrementing loop he came in with is
just answering the question when will that time of week next occur?.

-zefram


Re: simple calculation frustrations

2006-11-03 Thread Matthew
To clarify, this is all in reference to our event system. A customer 
can create an event for March 3, 2006 as a one time event or a weekly 
recurring event.


We are storing '2006-03-03' in the database as the base date.

In order to find the date of the next event, we take the base date from 
DB and add to that the increment value until the new base date is 
greater than today's date:


$baseDate = from_db();
while($baseDate  $today)
   $baseDate += increment

-Matthew

Zefram wrote:

Dave Rolsky wrote:
Pretty much all DBMS's (ok, not SQLite) have support for datetime as a 
data type.


Worms.  Can thereof.  A datetime type is not a primary feature of a DBMS,
so it's probably not had much attention paid to it.  Until recently,
MySQL's datetime type allowed dates such as 2006-04-31.  Even if it's
implemented correctly, it'll implement some arbitrarily selected date
model that's not particularly likely to match your need.  In this case,
timezone behaviour is the issue, and not very many datetime types handle
multiple timezones in the way desired.

Using a DBMS's datetime type also loses you portability, of course.

The advantage to this is that your datetime data is stored in a consistent 
way, so if you ever need to compare datetimes for some reason, you know 
that they'll compare sanely.


I think what he wants to store isn't actually a date, as in a point in
time.  Looks like he wants to store a time of week, timezone-relative,
along with a timezone spec.  The incrementing loop he came in with is
just answering the question when will that time of week next occur?.

-zefram


Re: simple calculation frustrations

2006-11-02 Thread Rick Measham

Matthew wrote:

hey guys,
  I can't believe I'm having this much trouble doing this. I'm pulling a 
UNIX_TIMESTAMP from MySQL and all I want to do is add a certain interval 
to that date then spit out the new date. Right now we only support 
weekly intervals in our app.


Best bet: Get mysql to add the week, providing it's time zone is set 
correctly ..


SELECT UNIX_TIMESTAMP( FROM_UNIXTIME( theField ) + INTERVAL 7 DAY )

(You're supposed to be able to do 1 WEEK too, but I can't get that to 
work in 4.1)


Alternately, use DateTime:

use DateTime;
my $dt = DateTime-from_epoch(
epoch = $eventDate,
# So that DST is accounted for:
time_zone = 'Australia/Melbourne',
);
$dt-add( weeks = 1 );
$dt-epoch ==
(1 week after the $eventDate expressed as an epoch)

Cheers!
Rick Measham


Re: simple calculation frustrations

2006-11-02 Thread Dave Rolsky

On Thu, 2 Nov 2006, Matthew wrote:

 I tried to do so. The problem is that the date's are stored in the users 
local timezone and we only store the offset from GMT. (ex: -6 or 7)


Well, there's your problem right there. You realy can't do this and expect 
it to work, as you're finding out. You need to store the user's timezone, 
not their current offset. If you know all your users are in the US you 
might be able to come up with some hacks to deal with DST, but otherwise 
you really need to let DT::TimeZone do this for you (or MySQL, or 
something).


 Is there some array or table I can use to convert '-6' to something 
DateTime:: can use?


No, there's no way to go from offset to time zone. Again, if your users 
are all in the US, _and_ no one's in a weird zone (like Indiana, parts 
of Arizona, etc) then you can probably convert it back.



-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/


Re: simple calculation frustrations

2006-11-02 Thread Rick Measham

Matthew wrote:

Alternately, use DateTime:


  I tried to do so. The problem is that the date's are stored in the 
users local timezone and we only store the offset from GMT. (ex: -6 or 7)


  Is there some array or table I can use to convert '-6' to something 
DateTime:: can use?


Epochs are UTC on most systems, so you're probably storing them as UTC ..

-6 is meaningless and so useless for DST calculations.

Last week Melbourne, Sydney and Brisbane were all +1000. Now Melbourne 
and Sydney are +1100, but Brisbane is still +1000. And Hobart switched 
from +1000 to +1100 a few weeks earlier.


Unless you have more information that '-6' then you'll never be able to 
properly convert across a DST change.


You could, of course, continue to use the UTC time zone. But you still 
can't properly turn that into the user's local time zone as it's no 
longer -6, but -7 or some such.


Cheers!
Rick Measham


Re: simple calculation frustrations

2006-11-02 Thread Matthew

Ahh. And we have customers all over the world. Dang. See, all of this
programming was done back shortly after we sprang forward so we didn't
think about it.

Any suggestions on how I should store a customers timezone in database?

Thanks,
Matthew

Dave Rolsky wrote:

On Thu, 2 Nov 2006, Matthew wrote:

 I tried to do so. The problem is that the date's are stored in the 
users local timezone and we only store the offset from GMT. (ex: -6 or 7)


Well, there's your problem right there. You realy can't do this and 
expect it to work, as you're finding out. You need to store the user's 
timezone, not their current offset. If you know all your users are in 
the US you might be able to come up with some hacks to deal with DST, 
but otherwise you really need to let DT::TimeZone do this for you (or 
MySQL, or something).


 Is there some array or table I can use to convert '-6' to something 
DateTime:: can use?


No, there's no way to go from offset to time zone. Again, if your users 
are all in the US, _and_ no one's in a weird zone (like Indiana, parts 
of Arizona, etc) then you can probably convert it back.



-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/