For my site I just used jQuery to do an AJAX request to a timezone HTTP handler that would record the timezone in session, then I created an extension method "ToVisitorTime" that would use this value.
In your base template or page header:
<script type="text/javascript" src="/lib/js/jquery.js"></script>
<asp:Placeholder id="plcTimezoneScript" Visible="false" runat="server">
<script type="text/javascript">
function getVisitorTimezone()
{
// get visitor timezone offset
var curDt = new Date();
$.post("/ajax/TimezoneOffset.ashx", {
offset: -(curDt.getTimezoneOffset()/60)
});
}
$(getVisitorTimezone);
</script>
</asp:Placeholder>
Then to hide it if you already grabbed the session, in the codebehind:
protected void Page_Load(object sender, EventArgs e)
{
object sessOffset = Session["OFFSET"];
if (sessOffset == null)
{
plcTimezoneScript.Visible = true;
}
}
For the /ajax/TimezoneOffset.ashx handler:
using System;
using System.Web;
using System.Web.SessionState;
public class TimezoneOffset : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
object sessOffset = context.Session["OFFSET"];
if (context.Request.RequestType == "POST")
{
if (sessOffset == null)
{
string offset = context.Request.Form.Get("offset");
int Offset = 0;
if (!String.IsNullOrEmpty(offset)
&& Int32.TryParse(offset, out Offset))
{
context.Session.Add("OFFSET", Offset);
}
}
}
}
public bool IsReusable {
get {
return false;
}
}
}
Then an extension method to take care of showing the right time (returns a DateTime object for further processing if need be). Remember to store this in a static class:
public static DateTime ToVisitorTime(this DateTime UtcDate)
{
// use timezone offset, if set
object TimezoneOffset = HttpContext.Current.Session["OFFSET"];
if (TimezoneOffset != null)
{
int Offset = 0;
if (Int32.TryParse(TimezoneOffset.ToString(), out Offset))
{
UtcDate = UtcDate.AddHours(Offset);
}
else
{
UtcDate = UtcDate.ToLocalTime();
}
}
else
{
// well, at least show the local server time
UtcDate = UtcDate.ToLocalTime();
}
return UtcDate;
}
This was taken from a tutorial I've yet to publish but should do what you need. One downside is that on the first page load, nothing will be in the correct time.
You should use a JS method probably, considering this already requires JS to work. I would recommend the Datejs plugin and use some jQuery to automatically replace utc dates.