Отображение DateTime в GridView, используя время пользователя - PullRequest
2 голосов
/ 28 апреля 2010

У меня есть DateTime, сохраненное в UTC, которое я хотел бы показать пользователю по его местному времени из элемента управления GridView. Как я могу преобразовать свой DateTime во время пользователя (не по местному времени моего сервера)? Вот мое текущее поле, отображаемое в коллекции столбцов GridView:

<asp:BoundField DataField="RunTime" HeaderText="Run Time"
  SortExpression="RunTime" DataFormatString="{0:f}" />

Ответы [ 4 ]

3 голосов
/ 29 апреля 2010

Для моего сайта я просто использовал jQuery для выполнения AJAX-запроса к обработчику HTTP часового пояса, который будет записывать часовой пояс в сеансе, затем я создал метод расширения "ToVisitorTime", который будет использовать это значение.

В вашем базовом шаблоне или заголовке страницы:

<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>

Затем, чтобы скрыть это, если вы уже захватили сеанс, в коде:

protected void Page_Load(object sender, EventArgs e)
{
    object sessOffset = Session["OFFSET"];

    if (sessOffset == null)
    {
        plcTimezoneScript.Visible = true;
    }
}

Для обработчика /ajax/TimezoneOffset.ashx:

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;
        }
    }

}

Затем метод расширения, обеспечивающий отображение нужного времени (возвращает объект DateTime для дальнейшей обработки, если это необходимо). Не забудьте сохранить это в статическом классе:

    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;
}

Это было взято из учебника, который я еще не опубликовал, но должен делать то, что вам нужно. Недостатком является то, что при первой загрузке страницы ничего не будет происходить в нужное время.

Вероятно, вам следует использовать метод JS, учитывая, что для этого уже требуется JS. Я бы порекомендовал плагин Datejs и использовать некоторые jQuery для автоматической замены дат utc.

3 голосов
/ 28 апреля 2010

Вы можете использовать JavaScript, чтобы найти часовой пояс пользователя:

var userTime =(new Date().getTimezoneOffset()/60)*(-1);

Затем сохраните это в скрытом поле или передайте в качестве параметра. На вашей странице вам придется переопределить событие RowDataBound GridView, найти время и преобразовать его, используя методы преобразования DateTime.

редактирование: Вероятно, самый безопасный способ сделать это - сохранить свой часовой пояс в профиле. Таким образом, отключение JavaScript не повлияет на ваше приложение.

редактирование: Код на стороне сервера

    static void Main()
    {            
        const string timeFmt = "{0,-30}{1:yyyy-MM-dd HH:mm}";
        DateTime dt = DateTime.Now.ToUniversalTime();
        for (int i = -12; i <= 12; i++)
        {
            DateTime converted = ConvertToLocalDateTime(dt, i);
            Console.WriteLine(timeFmt, "Offset: " + i , converted);
        }
        Console.ReadLine();
    }

    static DateTime ConvertToLocalDateTime(DateTime dateTime, int offset)
    {
         TimeZoneInfo destinationTimeZone = TimeZoneInfo.GetSystemTimeZones()
            .Where(x => x.BaseUtcOffset.Hours.Equals(offset)).FirstOrDefault();

        var rule = destinationTimeZone.GetAdjustmentRules().Where(x =>
            x.DateStart <= dateTime && dateTime <= x.DateEnd)
            .FirstOrDefault();

        TimeSpan baseOffset = TimeSpan.Zero;
        if(rule != null)
        {
            baseOffset -= destinationTimeZone.IsDaylightSavingTime(dateTime) ? 
                rule.DaylightDelta : TimeSpan.Zero;
        }

        DateTimeOffset dto = DateTimeOffset.Parse(dateTime.ToString());
        return new DateTime(TimeZoneInfo.ConvertTimeFromUtc(dateTime, destinationTimeZone).Ticks + baseOffset.Ticks);
    }

См .: http://msdn.microsoft.com/en-us/library/system.timezone(VS.90).aspx

3 голосов
/ 28 апреля 2010

Вам необходимо знать часовой пояс пользователя - например, из профиля или пользовательских данных, которые хранит ваш сайт. В качестве альтернативы вы можете попытаться угадать на основе данных GeoIP, хотя это может быть подозрительно, поскольку пользователь может не использовать этот конкретный часовой пояс на своем компьютере.

.NET не знает автоматически, сколько времени пользователь использует на удаленном конце.

2 голосов
/ 28 апреля 2010

Лучше всего было бы сохранить предпочтения пользователя часового пояса. Вы не можете правильно угадать часовой пояс из информации браузера.

Вот краткое руководство по сохранению выбранного часового пояса в сеансе и созданию быстрого элемента управления на каждой странице для обновления напечатанных дат.

http://www.dotnet -friends.com / статьи / осина / artinasp381efae4-87c8-41ae-9427-2ae75edd9594.aspx

...