DateTime.Now和文化/时区的具体 [英] DateTime.Now and Culture/Timezone specific

查看:221
本文介绍了DateTime.Now和文化/时区的具体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的应用程序被设计来处理来自不同地理位置的用户。

Our application was designed to handle user from different Geographic location.

我们是无法检测到什么是当前终端用户本地时间和
  时区对其进行操作。他们选择不同的文化像SV-SE,
  EN-US,TA-即使他们来自欧洲/伦敦时区访问。

We are unable to detect what is the current end user local time and time zone operate on it. They select different culture like sv-se, en-us, ta-In even they access from Europe/London timezone..

我们举办它在美国的主机服务器,应用程序用户从挪威/丹麦/瑞典/英国/美国/印度

We hosted it in a hosting server in US, application users are from Norway/Denmark/Sweden/UK/USA/India

问题是,我们使用 DateTime.Now 来存储记录创建/更新日期等。

The problem is we used DateTime.Now to store the record created/updated date, etc.

由于 服务器在美国运行的所有用户数据将被保存为美国时间:(

Since the Server runs in USA all user data are saved as US time :(

在SO经过研究,我们决定存储在数据库所有的历史日期为 DateTime.UtcNow

After researching in SO, we decided to stored all history dates in DB as DateTime.UtcNow

问题:

有是 2013年12月29日,3:15 P.M瑞典时间创造了一个纪录。

There is a record created on 29 Dec 2013, 3:15 P.M Swedish time.

 public ActionResult Save(BookingViewModel model)
    {
        Booking booking = new Booking();
        booking.BookingDateTime = model.BookingDateTime; //10 Jan 2014 2:00 P.M
        booking.Name = model.Name;
        booking.CurrentUserId = (User)Session["currentUser"].UserId;
        //USA Server runs in Pacific Time Zone, UTC-08:00
        booking.CreatedDateTime = DateTime.UtcNow; //29 Dec 2013, 6:15 A.M
        BookingRepository.Save(booking);
        return View("Index");
    }

我们要表现出同样的历史时间,谁在印度/瑞典/美国登录的用户。

We want to show the same history time to the user who logged in in India/Sweden/USA.

截至目前,我们正在使用记录在当前区域性的用户,然后从一个配置文件的时区,并使用转化率随的TimeZoneInfo类

As of now we are using current culture user logged in and choose the timezone from a config file and using for conversion with TimeZoneInfo class

<appSettings>
    <add key="sv-se" value="W. Europe Standard Time" />
    <add key="ta-IN" value="India Standard Time" />
</appSettings>

    private DateTime ConvertUTCBasedOnCuture(DateTime utcTime)
    {
        //utcTime is 29 Dec 2013, 6:15 A.M
        string TimezoneId =                  
                System.Configuration.ConfigurationManager.AppSettings
                [System.Threading.Thread.CurrentThread.CurrentCulture.Name];
        // if the user changes culture from sv-se to ta-IN, different date is shown
        TimeZoneInfo tZone = TimeZoneInfo.FindSystemTimeZoneById(TimezoneId);

        return TimeZoneInfo.ConvertTimeFromUtc(utcTime, tZone);
    }
    public ActionResult ViewHistory()
    {
        List<Booking> bookings = new List<Booking>();
        bookings=BookingRepository.GetBookingHistory();
        List<BookingViewModel> viewModel = new List<BookingViewModel>();
        foreach (Booking b in bookings)
        {
            BookingViewModel model = new BookingViewModel();
            model.CreatedTime = ConvertUTCBasedOnCuture(b.CreatedDateTime);
            viewModel.Add(model);
        }
        return View(viewModel);
    }

查看code

   @Model.CreatedTime.ToString("dd-MMM-yyyy - HH':'mm")

注:用户可以改变文化/语言,他们之前登录。它是一种基于本地化的应用,在美国的服务器上运行。

NOTE: The user can change the culture/language before they login. Its a localization based application, running in US server.

我见过 NODATIME ,但我不明白它如何能够多帮助文化Web应用程序服务器是在不同的位置。

I have seen NODATIME, but I could not understand how it can help with multi culture web application hosted in different location.

我如何能表现出相同的记录创建日期 2013年12月29日,3:15 P.M 为用户登录印度/美国/ Anywhere`?

How can I show a same record creation date 29 Dec 2013, 3:15 P.M for the users logged in INDIA/USA/Anywhere`?

就像现在我在 ConvertUTCBasedOnCuture 逻辑是基于用户登录的文化。这应该是不分文化,因为用户可以登录使用任何文化从印度/美国

As of now my logic in ConvertUTCBasedOnCuture is based user logged in culture. This should be irrespective of culture, since user can login using any culture from India/USA

数据库列

CreatedTime: SMALLDATETIME

CreatedTime: SMALLDATETIME

更新:尝试性解决方案:

UPDATE: ATTEMPTED SOLUTION:

数据库列类型:DATETIMEOFFSET

UI

最后,我在每个请求使用下面的Momento.js code发送当前用户的本地时间

Finally I am sending the current user's local time using the below Momento.js code in each request

$.ajaxSetup({
    beforeSend: function (jqXHR, settings) {
        try {
      //moment.format gives current user date like 2014-01-04T18:27:59+01:00
            jqXHR.setRequestHeader('BrowserLocalTime', moment().format());
        }
        catch (e) {
        }
    }
});

应用

public static DateTimeOffset GetCurrentUserLocalTime()
{
    try
    {
      return 
      DateTimeOffset.Parse(HttpContext.Current.Request.Headers["BrowserLocalTime"]);
    }
    catch
    {
        return DateTimeOffset.Now;
    }
}

然后叫

 model.AddedDateTime = WebAppHelper.GetCurrentUserLocalTime();

在View

@Model.AddedDateTime.Value.LocalDateTime.ToString("dd-MMM-yyyy - HH':'mm")

在视图它显示本​​地时间的​​用户,但是我希望看到像 DD-MMM-YYYY CET / PST (2小时前)。

In view it shows the local time to user, however I want to see like dd-MMM-yyyy CET/PST (2 hours ago).

这3小时前应当从最终用户的本地时间计算。究竟同栈溢出问题创建/编辑的时间与时区显示和本地用户的计算。

This 2 hours ago should calculate from end user's local time. Exactly same as stack overflow question created/edited time with Timezone display and local user calculation.

示例: 回答1月25日在'13 CST 17时49分(6小时/天/月前)那么其他来自美国观看/印度用户能真正理解这个纪录是由印度/美国当前的时间正好创造6小时

Example: answered Jan 25 '13 at 17:49 CST (6 hours/days/month ago) So the other viewing from USA/INDIA user can really understand this record was created exactly 6 hours from INDIA/USA current time

我几乎觉得我取得的一切,除了显示格式和放大器;计算。我怎样才能做到这一点?

Almost I think I achieved everything, except the display format & calculation. How can i do this?

推荐答案

这听起来像你需要存储的的DateTimeOffset 代替日期时间。您的可能的只是存储在本地的DateTime 给用户创造价值,但是这意味着你不能执行任何操作排序等,您可以' ŧ只需使用 DateTime.UtcNow ,因为这不会存储任何指示何时记录的创建用户的本地日期/时间。

It sounds like you need to store a DateTimeOffset instead of a DateTime. You could just store the local DateTime to the user creating the value, but that means you can't perform any ordering operations etc. You can't just use DateTime.UtcNow, as that won't store anything to indicate the local date/time of the user when the record was created.

另外,你可以在时间瞬间存储与用户的时区沿 - 这是很难实现的,但会给你更多的信息,那么你能说这样的话什么是用户的本地一小时的时间以后呢?

Alternatively, you could store an instant in time along with the user's time zone - that's harder to achieve, but would give you more information as then you'd be able to say things like "What is the user's local time one hour later?"

托管的服务器应该是不相干的 - 你永远不应该使用服务器的时区。但是,您将需要知道用户适当的UTC偏移(或时区)。这的不能的基础上仅仅是文化的完成 - 你需要使用JavaScript的用户的计算机上,以确定UTC在你感兴趣的(不一定是现在)的时间偏移

The hosting of the server should be irrelevant - you should never use the server's time zone. However, you will need to know the appropriate UTC offset (or time zone) for the user. This cannot be done based on just the culture - you'll want to use Javascript on the user's machine to determine the UTC offset at the time you're interested in (not necessarily "now").

一旦你已经制定了如何存储的价值,它检索很简单 - 如果你已经存储在UTC瞬间偏移,你刚才申请的偏移,你会回到原始用户的本地时间。你还没说你怎么转换值文本,但它应该只是辍学简单 - 只需格式化值,你应该得到原来的本地时间

Once you've worked out how to store the value, retrieving it is simple - if you've already stored the UTC instant and an offset, you just apply that offset and you'll get back to the original user's local time. You haven't said how you're converting values to text, but it should just drop out simply - just format the value, and you should get the original local time.

如果您决定使用野田时间,你只需要使用 OffsetDateTime 而不是的DateTimeOffset

If you decide to use Noda Time, you'd just use OffsetDateTime instead of DateTimeOffset.

这篇关于DateTime.Now和文化/时区的具体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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