I've been storing all dates in the database as UTC time for several years now, but recently, it's becoming more of a pain to deal with date range queries in reporting services where the date range is specified in local time.
Specifically, let's take this example data set:
EmailAddress DateCreated
[email protected] 2009-09-01 00:00:00
[email protected] 2009-09-01 00:00:00
[email protected] 2009-02-28 04:00:00
[email protected] 2009-04-27 14:33:00
[email protected] 2009-08-31 17:28:00
[email protected] 2009-03-19 18:57:00
[email protected] 2009-03-01 00:49:00
[email protected] 2009-02-28 04:00:00
[email protected] 2009-09-01 00:00:00
[email protected] 2009-09-16 00:00:00
Now let's say the client wants to see how many records exist for the month of February using central standard time. I cannot simply query for records using UTC time, because the UTC timestamp must be converted to CST before the grouping takes place. In other words, record #7 (2009-03-01 00:49:00) should be counted under February using CST dates, even though the UTC date puts it squarely in the month of March.
What usually ends up happening is that I write a function to convert the date such that a query looks like so:
select
dbo.ConvertToLocalDate(DateCreated),
count(*) as [Count]
from
example_table
group by
dbo.ConvertToLocalDate(DateCreated)
but the performance of such a query is less than desirable for anything more than a few hundred thousand rows. I've tried several variations on the theme, including adding a column to pre-calculate the local date, and also a modified query such as:
select
t3.LocalDateCreated,
count(*) as [Count]
from
example_table t1
inner join (
select
t2.Email,
dbo.ConvertToLocalDate(t2.DateCreated) as LocalDateCreated
from
example_table t2) t3 on t3.Email = t1.Email
group by
t3.LocalDateCreated
This all seems really hackish to me though. Is there a better way?