开始使用Noda Time

18

我希望使用Noda time来开发一个相当简单的应用程序,但是我无法找到处理非常基本用例的文档:

我有一个已登录的用户,并将在设置中存储他们首选的时区。客户端传来的任何日期/时间都以已知的文本格式(例如“dd/MM/yyyy HH:mm”)和已知的时区标识符(例如“Europe/London”)形式出现。我计划将这些时间转换为UTC / Noda Instants,以避免在数据库中每个日期上都存储时区信息。

首先,这听起来像一个明智的做法吗?我可以自由更改几乎所有内容,因此很乐意采取更好/更明智的方法。数据库是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:

我知道会有人问“你尝试过什么”,但我所做的只是一些失败的转换。很乐意被指向一个“开始使用Noda时间”的页面!


你看到了 http://noda-time.googlecode.com/hg-history/1.0.x/docs/userguide/index.html 吗? - Matthew Watson
是的,我已经浏览了几乎每一页。我理解核心原则,只是试图弄清楚如何在实践中使用它。我看到的唯一代码示例是单元测试... - Paul Grimshaw
最相关的页面可能是文本处理和核心概念中的时区部分。当然还有API文档。但如果您能建议添加更多内容的特定位置,那就太好了。更多的示例代码肯定会很有用 - 但问题在于选择什么。嗯。 - Jon Skeet
也很好知道你尝试过哪些失败的方法,这样我就可以尝试使正确的方法更易于发现 :) - Jon Skeet
1个回答

21

我打算将这些时间转换为UTC / Noda实例,以避免在数据库中每个日期都需要存储所有时区信息。

如果您不需要后来知道原始时区,那就没问题了(例如,如果用户更改时区但仍希望在原始时区重复某些操作)。

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

  • 解析为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();

1
嗨Jon,这正是我在寻找的代码。我已经创建了一个模式,但没有意识到该模式包含Parse方法。我正在寻找ZonedDateTime对象上的此功能。我会尝试一下,非常感谢您的帮助。 - Paul Grimshaw
1
@PaulGrimshaw:没错 - 我们从LocalDateTime等中删除了Parse(和TryParse)方法,因为只在Pattern类型上拥有它们要好得多。不要犹豫问任何其他问题 - Noda Time用户越多越好 :) - Jon Skeet
6
我想补充一点,我更喜欢非常严格、迫使你深思熟虑的库,而不是似乎会在不可预测的时刻使用系统时间的日期时间库。据我看来,Noda Time所需的仅是一个“入门指南”,介绍类似上文中提到的基本内容。 - Paul Grimshaw
我在共享服务器上托管Web应用程序时遇到了一些DateTime.Now问题,在这篇SO帖子中有详细解释。 - Billa
1
@DonnyV.:我看了看,发现有很多机会可以把它用糟糕的. 如果你想要一些东西,可以轻松使用并失败,而不需要思考, 那么你可以继续使用DateTime. 是的,使用Noda Time时需要思考 - 这不是巧合,在我看来这是一种特性。时间是一个复杂的领域,你需要学习一点并思考一点才能正确地处理它。 Noda Time旨在鼓励您思考以前没有考虑过的事情,然后使您能够非常容易地表达您的结论。 - Jon Skeet
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接