在全球范围内将UTC DateTime是否对用户指定的本地DateTime是否 [英] Globally convert UTC DateTimes to user specified local DateTimes

查看:255
本文介绍了在全球范围内将UTC DateTime是否对用户指定的本地DateTime是否的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我存储所有日期时间字段为UTC时间。当用户请求一个网页,我想借他的preferred本地时区(而不是服务器计算机的本地时区),并自动显示在所有的网络形式本地日期的所有日期时间字段。

I am storing all the DateTime fields as UTC time. When a user requests a web page, I would like to take his preferred local timezone (and not the local timezone of the server machine) and automatically display all the DateTime fields in all the web forms as local dates.

当然,我可以申请转换每则DateTime.ToString()调用在每一个形式或实施一些辅助工具,但它是一个耗时的任务,也有这是棘手的自定义配置一些第三方组件日期时间显示模板。

Of course, I could apply the conversion on every DateTime.ToString() call in every form or implement some helper utility but it is a time consuming task, and also there are some 3rd party components which are tricky to configure with custom DateTime display templates.

从本质上讲,我想提出DateTime类的行为如下:

Essentially, I would like to make the DateTime class to behave as follows:

from this moment on for this web request, 
whenever some code calls DateTime.ToString(), convert it to the local time 
        using the timezone offset given at the very beginning of the web request, 
but if possible, please keep .NET core library DateTime.ToString() calls intact 
       (I don't want to mess up event logging timestamps etc.)

有没有办法做到这一点?

Is there any way to do it?

顺便说一句,我使用ASP.NET MVC 4,如果它很重要。

BTW, I am using ASP.NET MVC 4, if it matters.

推荐答案

您不能直接做你问什么,但我会建议一些替代品。正如尼古拉斯指出的那样,没有什么HTTP,将直接给你的时区。

You can't do directly what you asked for, but I will suggest some alternatives. As Nicholas pointed out, there is nothing in HTTP that would give you the time zone directly.

选项1


  • 首先,决定你要使用哪种类型的时区的数据。有两种不同类型的可用,要么你可以用的TimeZoneInfo 类,或者说,世界其他地区使用IANA /奥尔森时区访问Microsoft时区。 在这里阅读更多信息。我的建议是后者,利用 NodaTime 提供的实现。

  • First, decide which type of time zone data you want to work with. There are two different types available, either the Microsoft time zones that you can access with the TimeZoneInfo class, or the IANA/Olson time zones that the rest of the world uses. Read here for more info. My recommendation would be the latter, using the implementation provided by NodaTime.

然后确定要转换到哪个时区。你应该让你的用户设置的地方来接他们的时区。

Then determine which time zone you want to convert to. You should allow your user a setting somewhere to pick their time zone.


  • 您可能会显示一个下拉列表中进行选择的几个时区之一,否则你可能会做一些更有用,比如显示一幅世界地图,他们可以点击选择自己的时区。有几个库,可以在Javascript中做到这一点,但我最喜欢的是这个

您可能要猜使用默认的时区,所以他们从列表(或地图)挑才可以尽量靠近尽可能准确。有一个伟大的图书馆为这个名为 jsTimeZoneDetect 。它会询问浏览器的时钟,使的是什么时区,这可能是一个最好的猜测假设。这是相当不错的,但它仍然只是一个猜测。不要盲目地使用它 - 但不要用它来确定一个起点。 更新:您现在还可以做到这一点与 moment.tz.guess(),在 moment.js的时刻,时区组件。

You might want to guess a default time zone to use, so you can be as close to accurate as possible before they pick from the list (or map). There is a great library for this called jsTimeZoneDetect. It will interrogate the browser's clock and make a best guess assumption of what time zone it might be. It is fairly good, but it is still just a guess. Don't use it blindly - but do use it to determine a starting point. Update You can now also do this with moment.tz.guess(), in the moment-timezone component of moment.js.

现在,你知道用户的时区,您可以使用该值将UTC 的DateTime 值转换为本地时区。不幸的是,没有什么可以线程,将做到这一点的设置。当您更改系统时区,这是对所有进程和线程。所以,你有没有选择,只能通过时间区的每一个要发送回来的地方。 (我相信这是你的主要问题。)看到这个的几乎的复制在这里。

Now that you know the time zone of the user, you can use that value to convert your UTC DateTime values to that local time zone. Unfortunately, there is nothing you can set on the thread that will do that. When you change the system time zone, it is global for all processes and threads. So you have no choice but to pass the time zone to each and every place you are sending it back. (I believe this was your main question.) See this almost duplicate here.

在将其转换为字符串,则需要也知道用户所在的区域(这可以从得到Request.UserLanguages​​ 的值)。你可以把它分配给当前线程,或者你可以把它作为参数传递给则DateTime.ToString()方法。这并不做任何时区转换 - 它只是可以确保数字是在正确的位置,使用正确的分隔符,和适当的语言平日或几个月的名字

Before you convert it to a string, you will need to also know the user's locale (which you can get from the Request.UserLanguages value). You can assign it to the current thread, or you can pass it as a parameter to the DateTime.ToString() method. This doesn't do any time zone conversion - it just makes sure that the numbers are in the correct position, using the correct separators, and the appropriate language for names of weekdays or months.

选项2

的将其转换为本地时间服务器都上。

Don't convert it to local time on the server at all.


  • 既然你说你与UTC值工作,确保他们的 .Kind 属性是 UTC 。你或许应该这样做,当你从数据库中加载,但如果你要可以手动做到这一点:

  • Since you said you are working with UTC values, make sure their .Kind property is Utc. You should probably do this when you load from your database, but if you have to you can do it manually:

myDateTime = DateTime.SpecifyKind(myDateTime, DateTimeKind.Utc);


  • 发送回浏览器作为纯UTC,像ISO8601一个不变的格式。换句话说:

  • Send it back to the browser as pure UTC, in an invariant format like ISO8601. In other words:

    myDateTime.ToString("o");  // example:  "2013-05-02T21:01:26.0828604Z"
    


  • 使用一些JavaScript的浏览器解析它为UTC。它会自动选择浏览器的本地时间设置。一种方法是使用内置的日期对象在JavaScript中,像这样的:

  • Use some JavaScript on the browser to parse it as UTC. It will automatically pick up the local time settings of the browser. One way is to use the built-in Date object in JavaScript, like this:

    var dt = new Date('2013-05-02T21:01:26.0828604Z');
    

    然而,这只会在支持ISO-8601格式新的浏览器。相反,我建议使用 moment.js 库。它是跨浏览器一致的,它具有ISO日期和本土化更好的支持。另外,你得到了很多其他有用的解析和格式化功能。

    However, this will only work in newer browsers that support the ISO-8601 format. Instead, I recommend using the moment.js library. It is consistent across browsers, and it has better support for ISO dates, and localization. Plus you get a lot of other useful parsing and formatting functions.

    // pass the value from your server
    var m = moment('2013-05-02T21:01:26.0828604Z');
    
    // use one of the formats supported by moment.js
    // this is locale-specific "long date time" format.
    var s = m.format('LLLL');
    


  • 选项1的优点是,可以在任何时区时间工作。如果你可以从下拉列表中问他们时区的用户,那么你不需要使用任何JavaScript。

    The advantage of Option 1 is that you can work with times in any time zone. If you can ask the user for their timezone from a dropdown list, then you need not use any Javascript.

    选项2的好处是,你让浏览器做一些工作适合你。这就是,如果你发送的原始数据,如使AJAX调用到的WebAPI到最好的一段路要走。然而,JavaScript是只知道UTC与浏览器的本地时区。所以这是行不通的那么好,如果你需要转换为的其他的区域。

    The advantage of Option 2 is that you get the browser to do some of the work for you. This is the best way to go if you're sending out raw data, such as making AJAX calls to a WebAPI. However, JavaScript is only aware of UTC and the browser's local time zone. So it doesn't work so well if you need to convert to other zones.

    您也应该知道,如果你选择方案2,您可以通过在ECMAScript中5.1的设计缺陷的影响。该进场,如果你是由一组不同的夏令时规则比覆盖当前有效日期的工作。你可以阅读在这个问题上更 和的 nofollow的>。

    You should also be aware that if you choose Option #2, you may be affected by a flaw in the design of ECMAScript 5.1. This comes into play if you are working with dates that are covered by a different set of daylight saving time rules than are currently in effect. You can read more in this question, and on my blog.

    这将是容易得多,如果我们在HTTP头一段时间区信息,但不幸的是我们不知道。这些都是很多箍跳通过,但它同时具有灵活性和准确性的最佳方法。

    It would be so much easier if we had some time zone information in the HTTP headers, but unfortunately we don't. These are a lot of hoops to jump through, but it's the best way to have both flexibility and accuracy.

    这篇关于在全球范围内将UTC DateTime是否对用户指定的本地DateTime是否的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆