字符串是传输日期和时间值的好方法,因为它们是人类可读的。但是您还应该确保它们是机器可读的,没有任何歧义。例如,不要使用像 1/4/2013 这样的值,因为没有额外的文化信息,您将无法知道是 1 月 4 日还是 4 月 1 日。请改用其中一种 ISO8601 格式。
将这些与DateTime 一起使用时,您可以使用"o" 格式字符串,它可以往返类型。它为Utc 种类附加一个Z,或为Local 种类附加一个本地偏移量。
var dt = new DateTime(2013,6,4,8,56,0); // Unspecified Kind
var iso = dt.ToString("o"); // 2013-06-04T08:56:00.0000000
var dt = DateTime.UtcNow; // Utc Kind
var iso = dt.ToString("o"); // 2013-06-04T15:56:00.0000000Z
var dt = DateTime.Now; // Local Kind
var iso = dt.ToString("o"); // 2013-06-04T08:56:00.0000000-07:00
从这种格式解析时,如果你没有偏移量,那么类型将是Unspecified。但如果你有一个Z 或any 偏移量,那么默认情况下类型是Local。它还将应用您提供的任何偏移量,因此结果是等效的 local 时间。所以如果你想正确应用它,你必须明确告诉它来回那种类型。
var dt = DateTime.Parse("2013-01-04T15:56:00.0000000Z");
var kind = dt.Kind; // Local - incorrect!
var s = dt.ToString("o"); // "2013-01-04T08:56:00.0000000-07:00" (ouch!)
改为:
var dt = DateTime.Parse("2013-01-04T15:56:00.0000000Z",
CultureInfo.InvariantCulture,
DateTimeStyles.RoundtripKind);
var kind = dt.Kind; // Utc - that's better.
var s = dt.ToString("o"); // "2013-01-04T15:56:00.0000000Z" (nice!)
当然,使用DateTimeOffset 会更好。当你以 ISO8601 格式序列化它时,你总是得到一个完整的表示:
var dto = DateTimeOffset.Now;
var iso = dto.ToString("o"); // 2013-06-04T08:56:00.0000000-07:00
此格式与 RFC3339 一致,后者描述了 ISO8601 规范的此配置文件,并且正在迅速成为在不同系统之间序列化时间戳的事实标准。恕我直言 - 您应该尽可能使用这种格式。它大大优于您在网络上常见的其他格式,例如 RFC1123。 Here are some more details on various date/time formats.