为什么 LocalDateTime 实际上不是本地日期和时间?
Why isn't LocalDateTime actually a local date and time?
作为一名软件架构师,我真的很想使用 NodaTime,但是 'Local' 的概念让我们的代码非常难以使用(这让我和我的团队抓狂)! documentation,当提到 "local" 和 "global" 次时,说明如下:
The key difference is that people all around the world will agree on
a global value simultaneously, whereas they may all see different
local values for the same global value, due to time zones.
这句话是通过本地时间的定义来定义全球时间的意思。因此,在了解全球时间之前,我们必须先了解本地时间的含义。
Google(以及许多其他类似的词典)将“Local Time”定义为:
Time as reckoned in a particular region or time zone.
- time at a particular place as measured from the sun's transit over the meridian at that place, defined as noon.
因此,当地时间是由 时区 定义(或绑定)的特定时间 - 知道了。现在我们完全理解了全球时间的含义;好的,下一句:
A local value has no associated time zone in Noda Time;
等等!什么...?! 文档刚刚通过使用普遍接受的本地时间定义定义了全球时间( 是 与时区相关联)现在他们决定完全否定它的意义,如果那是真的,那么全球时间现在意味着什么?恕我直言,绝对没有。
文档继续说明...
in particular it is not just "a date and time fixed to the local time of the computer running the code"
我对这个陈述有两个问题:
- 文档无法使用'local time'的通用定义来尝试来描述它不是什么。这就像在说:
X is equal to (NOT X) is true
.
- 既然使用电脑的日期和时间正是"Local Time"的定义,那我怎么称呼本地时间呢?
我认为我们使用的定义比 'Local' 更好,'Raw' 这个词怎么样?这意味着:
Being in or nearly in the natural state: not processed or purified.
嗯嗯....
A [raw] value has no associated time zone in Noda Time;
in particular it is not just "a date and time fixed to the local time of the computer running the code"
现在这听起来更像是文档试图传达的定义。
或者,也许其他人可以想出比 'Raw' 更好的词;但关键是,请把'Local'的真正含义还给我们,因为'Local'在软件和生活中都有非常真实和非常有用的含义。
因此,我们能否将 Local[Date][Time]
类 重命名为 Raw[Date][Time]
并(可选)添加名为 Local[Date][Time]
的新 类 即 绑定到计算机的本地时区吗?
@Michal 和@J...-
我们遇到的问题是无法理解 'our' 本地的 LocalDateTime
(因为它是无区域的)。我们在使用 LocalDateTime 时遇到的问题是它 是 zoneless。从本质上讲,LocalDateTime
应该是,顾名思义,是ZonedDateTime
的一种特殊类型。 (就像 UTC 在概念上(具体而言)是 ZonedDateTime
的一种特殊类型。因此,UTC 可以拥有自己的一组类型,例如:Utc[Date][Time]
;在给定正确的问题域的情况下,它可能非常很有用。因为 UtcDateTime
还没有 'taken',我们可以在不干扰 NodaTime 的情况下创建这样一个概念。)
回到我们的问题,例如:如果我有两个 ZonedDateTimes,一个来自纽约,另一个来自西雅图,我想从我当前的位置(比方说:达拉斯)研究这两个 ZonedDateTimes。我想写...
LocalDateTime fromNy = newYork.LocalDateTime;
LocalDateTime fromWa = seattle.LocalDateTime;
但是,我得到了两个不相关的本地日期时间,它们彼此之间完全没有关系。事实上,如果不是因为 var 名称,我不知道哪个是哪个。
我想要的是两个已转换为 my 本地时区的 ZonedDateTimes,正如 属性 名称所暗示的那样。现在,这两个 LocalDateTime 值(其中 LocalDateTime 是 ZonedDateTime 的一种特殊类型)具有相关含义。我知道我可以通过执行以下操作获得接近我想要的东西;但它很乱,没有传达相同的语义并且丢失了时区信息。
DateTimeZone ct = BclDateTimeZone.ForSystemDefault();
LocalDateTime tx1 = newYork.WithZone(ct);
LocalDateTime tx2 = seattle.WithZone(ct);
我也希望能够像这样再次转换值:
ZonedDateTime wa = tx2.WithZone(seattleTimeZone);
ZonedDateTime nw = tx2.WithZone(nyTimeZone);
这还允许:
instant.InUtc();
instant.InZone(zone);
instant.InLocal();
因此能够将即时时间映射到 3 个最常见的时区; UTC、本地和其他。但我不能,因为 LocalDateTime 不是 ZonedDateTime 的特殊类型。
恕我直言,NodaTime 1.x 不错,但不够灵活(或流畅),无法在黄金时段使用。但好消息是,它离它并不远。希望在 2.0(或更早版本)中可以解决这些问题。
@Michal - 我喜欢你关于 Noda[Date][Time]
的想法,而不是 Raw[Date][Time]
。
您可能感到困惑的是:
LocalDateTime
= 特定日历(例如公历)中的通用时间,但由于没有附加 TimeZone
,您无法区分这发生在全球时间线上的确切时间点。想象这只是一个通用值。例如。 14:00
。您不知道 14:00
的确切时间,因为您不知道这是什么时区。
ZonedDateTime
= LocalDateTime
在特定时区(您可能想象的是 LocalDateTime
)。
我可能同意你的看法,这有点误导。我更希望它被称为 NodaDateTime
和 ZonedDateTime
被称为 LocalDateTime
因为这样看起来更合乎逻辑。
编辑 - 以下评论
就个人而言,我很少使用 LocalDateTime
,如果您坚持使用 Instant
和 ZonedDateTime
之间,您可能会摆脱很多头痛。有一个非常好的类型之间转换的概览图:
取自:nodatime.org - User Guide - Converting Between Types
所以在你的情况下你想做的是从特定的ZoneDateTime
转换成Instant
,然后再回到你想要的ZonedDateTime
(你的系统tz)
例如
var myTz = BclDateTimeZone.ForSystemDefault();
var fromNy = SystemClock.Instance.Now.InZone(DateTimeZoneProviders.Tzdb["America/New_York"]);
// fromNy = 2015-03-22T08:28:56 America/New_York (-04)
var fromLa = SystemClock.Instance.Now.InZone(DateTimeZoneProviders.Tzdb["America/Los_Angeles"]);
// fromLa = 2015-03-22T05:28:56 America/Los_Angeles (-07)
var fromNyInMyTz = fromNy.ToInstant().InZone(myTz);
// localFromNy = 2015-03-22T12:28:56 GMT Standard Time (+00)
var fromLaInMyTz = fromLa.ToInstant().InZone(myTz);
// localFromLa = 2015-03-22T12:28:56 GMT Standard Time (+00)
您还可以创建一个扩展方法:
public static class NodaExtensions
{
public static ZonedDateTime InUtc(this ZonedDateTime dt)
{
return dt.ToInstant().InUtc();
}
public static ZonedDateTime InZone(this ZonedDateTime dt, DateTimeZone tz)
{
return dt.ToInstant().InZone(tz);
}
public static ZonedDateTime InLocal(this ZonedDateTime dt)
{
return dt.ToInstant().InZone(BclDateTimeZone.ForSystemDefault());
}
}
允许:
var fromNyInUtc = fromNy.InUtc();
var fromLaInUtc = fromLa.InUtc();
var fromNyInZone = fromNy.InZone(myTz);
var fromLaInZone = fromLa.InZone(myTz);
var fromNyInLocal = fromNy.InLocal();
var fromLaInLocal = fromLa.InLocal();
这是您想要的吗?
作为一名软件架构师,我真的很想使用 NodaTime,但是 'Local' 的概念让我们的代码非常难以使用(这让我和我的团队抓狂)! documentation,当提到 "local" 和 "global" 次时,说明如下:
The key difference is that people all around the world will agree on a global value simultaneously, whereas they may all see different local values for the same global value, due to time zones.
这句话是通过本地时间的定义来定义全球时间的意思。因此,在了解全球时间之前,我们必须先了解本地时间的含义。
Google(以及许多其他类似的词典)将“Local Time”定义为:
Time as reckoned in a particular region or time zone.
- time at a particular place as measured from the sun's transit over the meridian at that place, defined as noon.
因此,当地时间是由 时区 定义(或绑定)的特定时间 - 知道了。现在我们完全理解了全球时间的含义;好的,下一句:
A local value has no associated time zone in Noda Time;
等等!什么...?! 文档刚刚通过使用普遍接受的本地时间定义定义了全球时间( 是 与时区相关联)现在他们决定完全否定它的意义,如果那是真的,那么全球时间现在意味着什么?恕我直言,绝对没有。
文档继续说明...
in particular it is not just "a date and time fixed to the local time of the computer running the code"
我对这个陈述有两个问题:
- 文档无法使用'local time'的通用定义来尝试来描述它不是什么。这就像在说:
X is equal to (NOT X) is true
. - 既然使用电脑的日期和时间正是"Local Time"的定义,那我怎么称呼本地时间呢?
我认为我们使用的定义比 'Local' 更好,'Raw' 这个词怎么样?这意味着:
Being in or nearly in the natural state: not processed or purified.
嗯嗯....
A [raw] value has no associated time zone in Noda Time; in particular it is not just "a date and time fixed to the local time of the computer running the code"
现在这听起来更像是文档试图传达的定义。
或者,也许其他人可以想出比 'Raw' 更好的词;但关键是,请把'Local'的真正含义还给我们,因为'Local'在软件和生活中都有非常真实和非常有用的含义。
因此,我们能否将 Local[Date][Time]
类 重命名为 Raw[Date][Time]
并(可选)添加名为 Local[Date][Time]
的新 类 即 绑定到计算机的本地时区吗?
@Michal 和@J...-
我们遇到的问题是无法理解 'our' 本地的 LocalDateTime
(因为它是无区域的)。我们在使用 LocalDateTime 时遇到的问题是它 是 zoneless。从本质上讲,LocalDateTime
应该是,顾名思义,是ZonedDateTime
的一种特殊类型。 (就像 UTC 在概念上(具体而言)是 ZonedDateTime
的一种特殊类型。因此,UTC 可以拥有自己的一组类型,例如:Utc[Date][Time]
;在给定正确的问题域的情况下,它可能非常很有用。因为 UtcDateTime
还没有 'taken',我们可以在不干扰 NodaTime 的情况下创建这样一个概念。)
回到我们的问题,例如:如果我有两个 ZonedDateTimes,一个来自纽约,另一个来自西雅图,我想从我当前的位置(比方说:达拉斯)研究这两个 ZonedDateTimes。我想写...
LocalDateTime fromNy = newYork.LocalDateTime;
LocalDateTime fromWa = seattle.LocalDateTime;
但是,我得到了两个不相关的本地日期时间,它们彼此之间完全没有关系。事实上,如果不是因为 var 名称,我不知道哪个是哪个。
我想要的是两个已转换为 my 本地时区的 ZonedDateTimes,正如 属性 名称所暗示的那样。现在,这两个 LocalDateTime 值(其中 LocalDateTime 是 ZonedDateTime 的一种特殊类型)具有相关含义。我知道我可以通过执行以下操作获得接近我想要的东西;但它很乱,没有传达相同的语义并且丢失了时区信息。
DateTimeZone ct = BclDateTimeZone.ForSystemDefault();
LocalDateTime tx1 = newYork.WithZone(ct);
LocalDateTime tx2 = seattle.WithZone(ct);
我也希望能够像这样再次转换值:
ZonedDateTime wa = tx2.WithZone(seattleTimeZone);
ZonedDateTime nw = tx2.WithZone(nyTimeZone);
这还允许:
instant.InUtc();
instant.InZone(zone);
instant.InLocal();
因此能够将即时时间映射到 3 个最常见的时区; UTC、本地和其他。但我不能,因为 LocalDateTime 不是 ZonedDateTime 的特殊类型。
恕我直言,NodaTime 1.x 不错,但不够灵活(或流畅),无法在黄金时段使用。但好消息是,它离它并不远。希望在 2.0(或更早版本)中可以解决这些问题。
@Michal - 我喜欢你关于 Noda[Date][Time]
的想法,而不是 Raw[Date][Time]
。
您可能感到困惑的是:
LocalDateTime
= 特定日历(例如公历)中的通用时间,但由于没有附加 TimeZone
,您无法区分这发生在全球时间线上的确切时间点。想象这只是一个通用值。例如。 14:00
。您不知道 14:00
的确切时间,因为您不知道这是什么时区。
ZonedDateTime
= LocalDateTime
在特定时区(您可能想象的是 LocalDateTime
)。
我可能同意你的看法,这有点误导。我更希望它被称为 NodaDateTime
和 ZonedDateTime
被称为 LocalDateTime
因为这样看起来更合乎逻辑。
编辑 - 以下评论
就个人而言,我很少使用 LocalDateTime
,如果您坚持使用 Instant
和 ZonedDateTime
之间,您可能会摆脱很多头痛。有一个非常好的类型之间转换的概览图:
取自:nodatime.org - User Guide - Converting Between Types
所以在你的情况下你想做的是从特定的ZoneDateTime
转换成Instant
,然后再回到你想要的ZonedDateTime
(你的系统tz)
例如
var myTz = BclDateTimeZone.ForSystemDefault();
var fromNy = SystemClock.Instance.Now.InZone(DateTimeZoneProviders.Tzdb["America/New_York"]);
// fromNy = 2015-03-22T08:28:56 America/New_York (-04)
var fromLa = SystemClock.Instance.Now.InZone(DateTimeZoneProviders.Tzdb["America/Los_Angeles"]);
// fromLa = 2015-03-22T05:28:56 America/Los_Angeles (-07)
var fromNyInMyTz = fromNy.ToInstant().InZone(myTz);
// localFromNy = 2015-03-22T12:28:56 GMT Standard Time (+00)
var fromLaInMyTz = fromLa.ToInstant().InZone(myTz);
// localFromLa = 2015-03-22T12:28:56 GMT Standard Time (+00)
您还可以创建一个扩展方法:
public static class NodaExtensions
{
public static ZonedDateTime InUtc(this ZonedDateTime dt)
{
return dt.ToInstant().InUtc();
}
public static ZonedDateTime InZone(this ZonedDateTime dt, DateTimeZone tz)
{
return dt.ToInstant().InZone(tz);
}
public static ZonedDateTime InLocal(this ZonedDateTime dt)
{
return dt.ToInstant().InZone(BclDateTimeZone.ForSystemDefault());
}
}
允许:
var fromNyInUtc = fromNy.InUtc();
var fromLaInUtc = fromLa.InUtc();
var fromNyInZone = fromNy.InZone(myTz);
var fromLaInZone = fromLa.InZone(myTz);
var fromNyInLocal = fromNy.InLocal();
var fromLaInLocal = fromLa.InLocal();
这是您想要的吗?