我希望将Noda time用于一个相当简单的应用程序,但是我正在努力寻找任何文档来处理一个非常基本的用例:

我有一个登录用户,将在设置中存储他们的首选时区。来自客户的任何日期/时间都采用已知的文本格式(例如“dd/MM/yyyy HH:mm”)和已知的时区ID(例如“欧洲/伦敦”)。我计划将这些时间转换为UTC/Noda Instants,以防止需要将时区信息与每个日期一起存储在数据库中。

首先,这听起来像是明智的做法吗?我几乎可以自由地进行任何更改,因此很高兴被设置为更好/更明智的类(class)。该数据库是MongoDb,使用C#驱动程序。

我已经尝试过遵循这些原则,但是却难以克服第一步!

var userSubmittedDateTimeString = "2013/05/09 10:45";
var userFormat = "yyyy/MM/dd HH:mm";
var userTimeZone = "Europe/London";

//noda code here to convert to UTC


//Then back again:

我知道有人会问“您尝试了什么”,我所遇到的就是各种失败的转换。很高兴指向“野田时间入门”页面!

最佳答案



如果您以后不需要知道原始时区,那很好。 (例如,如果用户更改了时区,但仍希望在原始时区重现一些内容)。

无论如何,我会将其分为三个步骤:

  • 解析为LocalDateTime
  • 将其转换为ZonedDateTime
  • 将其转换为Instant

  • 就像是:
    // TODO: Are you sure it *will* be in the invariant culture? No funky date
    // separators?
    // Note that if all users have the same pattern, you can make this a private
    // static readonly field somewhere
    var pattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy/MM/dd HH:mm");
    
    var parseResult = pattern.Parse(userSubmittedDateTimeString);
    if (!parseResult.Success)
    {
        // throw an exception or whatever you want to do
    }
    
    var localDateTime = parseResult.Value;
    
    var timeZone = DateTimeZoneProviders.Tzdb[userTimeZone];
    
    // TODO: Consider how you want to handle ambiguous or "skipped" local date/time
    // values. For example, you might want InZoneStrictly, or provide your own custom
    // handler to InZone.
    var zonedDateTime = localDateTime.InZoneLeniently(timeZone);
    
    var instant = zonedDateTime.ToInstant();
    

    09-25 18:30