我建议始终在服务器端使用 UTC (GMT) 时间(在代码隐藏、数据库等中),并将时间从 UTC 转换为本地时间,仅用于显示目的。这意味着所有时间操作——包括在数据库中节省时间、执行计算等——都应该使用 UTC 完成。
问题是:您的代码隐藏如何知道客户端浏览器的时区?假设用户在表单中输入一些日期/时间值(例如12/30/2009 14:30)并将其提交给服务器。假设用户提交的是本地时间,那么服务器如何知道如何将此值转换为 UTC?
应用程序可以要求用户指定时区(并将其保存在持久性 cookie 或数据库中),但这需要用户付出额外的努力,并且您的应用程序需要为此实现逻辑和屏幕。如果应用程序可以自动确定客户端的时区,那就更好了。
我已经在 JavaScript 的getTimezoneOffset函数的帮助下解决了这个问题,它是唯一可以告诉服务器客户端本地时间和 GMT 时间差的 API。由于这是一个客户端 API,我做了以下操作:在服务器端检查保存时间偏移值的自定义会话 cookie,如果它不可用,则重新加载页面(仅在 GET 期间,而不是 POST 调用期间)添加了一些 JavaScript 逻辑来生成时间偏移并将其保存在 cookie 中。从客户端来看,这几乎是透明的(在会话期间我在 GET 上重新加载页面)。一旦我在 cookie 中获得了偏移量,我就会根据时间转换的方向(UTC 到本地时间,或本地时间到 UTC)将它应用于时间管理功能。
这听起来可能有点复杂,但确实如此,但在我编写了辅助函数之后,在站点中集成此功能只需在 Page_Load (需要时间转换的页面)中进行一次调用,并在发送时使用时间转换例程并从浏览器中检索时间值。这是如何使用它的示例:
using My.Utilities.Web;
...
// Derive the form class from BaseForm instead of Page.
public class WebForm1: BaseForm
{
...
private void Page_Load(object sender, System.EventArgs e)
{
// If we only want to load the page to generate the time
// zone offset cookie, we do not need to do anything else.
if (InitializeLocalTime())
return;
// Assume that txtStartDate is a TextBox control.
if (!IsPostback)
{
// To display a date-time value, convert it from GMT (UTC)
// to local time.
DateTime startDate = GetStartDateFromDB(...);
txtStartDate.Text = FormatLocalDate(startDate);
...
}
else
{
// To save a date-time value, convert it from local
// time to GMT (UTC).
DateTime tempDate = DateTime.Parse(txtStartDate.Text);
DateTime startDate = ConvertLocalTimeToUtc(tempDate);
SaveStartDateInDB(startDate, ...);
...
}
}
...
}
如果您需要更多详细信息,请查看It's About Time: Localizing Time in ASP.NET Applications文章(抱歉,我没有发布者网站上文章的直接链接,因为 asp.netPRO 仅限制付费订阅者的访问权限; 不过有指向 PDF 副本的链接)。我希望我可以发布文章中的示例,但我不想侵犯版权;然而,这里有一个项目来构建一个具有所有必要功能和文档的辅助库(忽略你不需要的东西)。
更新:文章已由新发布者在线发布,其中包含示例项目。