显示编辑器的LocalTime中的DateTimeOffset [英] Display EditorFor DateTimeOffset in LocalTime

查看:64
本文介绍了显示编辑器的LocalTime中的DateTimeOffset的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建"Time Clock"网络应用程序.但是,我很难让EditorFor在LocalTime中显示时间.按照最佳做法,我已将所有内容保存为UTC(通过DateTimeOffset)到数据库.

I am creating a 'Time Clock' web app. However, I am having trouble getting the EditorFor to display the time in LocalTime. I have everything saved to the Database as UTC(via DateTimeOffset), as per best practice.

关于如何使其在本地时间显示并仍保存为UTC的任何建议?

Any suggestions on how to get this to display in local time, and still save as UTC?

ViewModel

ViewModel

    [DataType(DataType.Time)]
    [DisplayFormat(DataFormatString = "{HH:mm}")]
    public DateTimeOffset TimeIn { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{MM, DD, YY}")]
    public DateTimeOffset DateIn { get; set; }

    [DataType(DataType.Time)]
    [DisplayFormat(DataFormatString = "{HH:mm}")]
    public DateTimeOffset TimeOut { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{MM, DD, YY}")]
    public DateTimeOffset DateOut { get; set; }

查看

  <div class="form-group">
        @Html.LabelFor(model => model.TimeOut, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.TimeOut, new { htmlAttributes = new { @class = "form-control" } })
            @Html.EditorFor(model => model.DateOut, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.TimeOut, "", new { @class = "text-danger" })
        </div>
    </div>

任何帮助将不胜感激,如果您还有其他希望帮助解决该问题的信息,请告诉我.谢谢!

Any help would be appreciated, please let me know if there is anything else you would like to see to help solve the issue. Thanks!

推荐答案

日期和时间很糟糕.干净利落.一件不太明显的事情,但您需要敏锐地意识到,本地时间"之类的概念具有很大的变化性.当您执行诸如 TimeOut.LocalTime 之类的操作时,您所谈论的是本地 server 时间,该时间可能(而且可能与)完全不同.用户的本地时间.首先,您需要定义要查找的对象,最有可能的是,感兴趣的是用户的时间而不是服务器的时间.结果, LocalTime 对您没有用.

Dates and times suck. Plain and simple. One thing that's not obvious, but you need to be keenly aware of is that a concept like "local time" is highly variant. When you do something like TimeOut.LocalTime, you're talking about local server time, which could be, and likely is, vastly different from the user's local time. First and foremost, you need to define which you're looking for, and more likely than not, it's the user's time, not the server's, that is of interest. As a result LocalTime is useless to you.

如果您关心用户的本地时间,那么必须让他们为您提供时间.服务器无法识别此信息.您可以在每个日期和时间字段旁边提供时区下拉列表,或者,如果用户通过了身份验证,则可以让他们在其个人资料上进行设置,然后将其用于他们提交的所有内容.

If you care about the user's local time, then you have to get them to provide it to you. There is no way for the server to discern this information. You can either provide time zone drop downs next to each of these date and time fields or, if the user is authenticated, you could have them set it on their profile, and then use that for everything they submit.

无论哪种方式,您将遇到的另一个问题是允许用户输入日期和时间.当您在客户端和服务器之间传输数据时,就是在处理字符串.MVC中的modelbinder有助于解析这些字符串值,以将它们绑定到更合适的类型,例如 DateTimeOffset ,但是为了使其起作用,发布的值必须在非常特定格式,否则转换过程将失败.期望用户以一种非常特定的方式做某事当然是灾难的秘诀,因此,您需要以某种方式为他们提供易于使用的界面,该界面仍然可以为您提供所需的信息,而又不会给用户提供任何利用它的机会向上,因为有机会,用户 会将其搞砸.

Either way, the other issue you'll have is in allowing user input of dates and times. When you're transferring data between a client and server, you're dealing with strings. The modelbinder in MVC helpfully parses these string values to bind them to more appropriate types like DateTimeOffset, but in order for that to work, the posted value must be in a very specific format, or that conversion process will fail. Expecting a user to do something in a very specific way is of course a recipe for disaster, so you need to somehow present them with an easy to use interface that still gets you the information you need, without providing the user any opportunity to screw it up, because given an opportunity, a user will screw it up.

因此,您最好的朋友是HTML5输入类型,即特定的 date time .还有其他类似的代码,例如 datetime datetime-local 等,但是当前任何浏览器均不支持这些功能,并且实际上存在被HTML5规范弃用的危险.几乎每种现代浏览器现在(分别)都支持某种形式的日期"控件和时间"控件,即使不支持,用户输入诸如日期"值和时间"之类的离散单位仍然更加容易"的值要比一个组合的日期时间"值正确.

For that reason, your best friend is the HTML5 input types, specific date and time. There's others like datetime, datetime-local, etc., but these are not supported in any current browser and actually in danger of being deprecated by the HTML5 spec. Pretty much every modern browser supports some form of "date" control and "time" control (separately) now, and even if it's not supported, it's still easier for a user to enter discrete units like a "date" value and a "time" value correctly than one combined "datetime" value.

基于所有这些,我建议您通过以下方式更改视图模型:

Based on all of this, I'd recommend you change your view model in the following way:

[DataType(DataType.Time)]
public TimeSpan TimeIn { get; set; }

[DataType(DataType.Date)]
public DateTime DateIn { get; set; }

public string TimeZoneIn { get; set; }

[DataType(DataType.Time)]
public TimeSpan TimeOut { get; set; }

[DataType(DataType.Date)]
public DateTime DateOut { get; set; }

public string TimeZoneOut { get; set; }

然后,您可以添加一些帮助器属性,例如:

Then, you can add some helper properties like:

public DateTimeOffset InUtc =>
    TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateIn, TimeZoneIn).Add(TimeIn).ToUniversalTime();

public DateTimeOffset OutUtc =>
    TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateOut, TimeZoneOut).Add(TimeOut).ToUniversalTime();

另一件事.尽管您使用UTC存储(也许特别是因为您使用UTC存储),但是您仍然至少需要保留时区部分,以便以后可以转换回该时区.还应注意,如果您使用SQL Server作为持久性存储,则 DateTimeOffset 将转换为 DATETIMEOFFSET 列类型,该列类型可以对时区部分进行编码.在这种情况下,无需转换为UTC,因为无论将其存储为用户的本地时间,UTC还是完全存储为其他时间,您始终可以到达所需的任何时区.但是,任何其他数据库都只需要UTC日期时间,因此确实有些麻烦.

One other thing. Although you're storing in UTC (and perhaps especially because you're storing in UTC), you still need to persist at least the time zone portion, so you can convert back into that time zone later. It should also be noted that if you're using SQL Server as your persistence store, DateTimeOffset will translate to a DATETIMEOFFSET column type, which can encode the time zone portion. In that scenario, there's no need to convert to UTC as you can always get to whatever time zone you need whether it's stored as the user's local time, UTC, or something else entirely. However, any other database will need UTC datetimes only, so it does somewhat pigeon hole you in.

这篇关于显示编辑器的LocalTime中的DateTimeOffset的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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