DateTime.TryParse和Z字母的大小写

最近,我受命以从后端到前端的特定格式提供日期,我注意到我发现自己的行为有些奇怪。

private static void OutputDateInfo(string value){
    Console.WriteLine($"Input: {value}");    if (DateTime.TryParse(value, out DateTime dateTimeValue))
    {
        Console.WriteLine($"Setialized to universal format
                {dateTimeValue.ToString("yyyy-MM-dd'T'HH:mm:ssZ")}");
    }
    Console.WriteLine();
}//somewhere in mainOutputDateInfo("2021-04-15T21:01:00.0000000Z");
OutputDateInfo("2021-04-15T21:01:00.0000000");1234567891011121314复制代码类型:[cpp]

产生输出:

Input: 2021-04-15T21:01:00.0000000Z
Setialized to universal format 2021-04-16T00:01:00Z

Input: 2021-04-15T21:01:00.0000000Setialized to universal format 2021-04-15T21:01:00Z12345复制代码类型:[cpp]

因此,就像我在UTC+3时区的Kyiv一样,它看起来像Z字母强制ToString方法,将日期转换为本地时间。

正如文档所述:

引用:

如果s不包含任何时区信息,则result包含一个DateTime值,该方法的返回值时其Kind属性为DateTimeKind.Unspecified。如果要解析的字符串包含时区信息,则方法返回时,结果包含DateTime值,其Kind属性为DateTimeKind.Local。

这DateTimeKind使得ToString投日期为本地时区?让我们记录更多属性以查看是否存在这种情况:

private static void OutputDateInfo(string value){
    Console.WriteLine($"Input: {value}");    if (DateTime.TryParse(value, out DateTime dateTimeValue))
    {
        Console.WriteLine($"Setialized to universal format
                         {dateTimeValue.ToString("yyyy-MM-dd'T'HHssZ")}");
        Console.WriteLine($"Setialized to default format {dateTimeValue}");
        Console.WriteLine($"Setialized with conversion to universal time
                         {dateTimeValue.ToUniversalTime()}");
        Console.WriteLine($"Kind: {dateTimeValue.Kind}");
    }
    Console.WriteLine();
}1234567891011121314复制代码类型:[csharp]

现在我们在控制台中看到:

Input: 2021-04-15T21:01:00.0000000Z
Setialized to universal format 2021-04-16T00:01:00Z
Setialized to default format 16.04.2021 0:01:00Setialized with conversion to universal time 15.04.2021 21:01:00Kind: Local

Input: 2021-04-15T21:01:00.0000000Setialized to universal format 2021-04-15T21:01:00Z
Setialized to default format 15.04.2021 21:01:00Setialized with conversion to universal time 15.04.2021 18:01:00Kind: Unspecified1234567891011复制代码类型:[cpp]

因此,我们确实当我们调用ToString一个DateTimeKind.Local实例,它会根据服务器时区调整。

但是,为什么将字母Z视为时区信息?上面提到的文档没有带Z字母的示例。答案是有问题的格式是ISO-8601格式,Z代表“零UTC偏移量”。是否将此格式的字符串与指定时区的任何其他字符串一样对待,还是这种特殊处理?通过比较它们,我们将得到答案。

OutputDateInfo("2021-04-15T2100.0000000Z");
OutputDateInfo("2021-04-15T2100.0000000");
OutputDateInfo("2021-04-15T1400.0000000 -7:00");123复制代码类型:[cpp]

产量:

Input: 2021-04-15T21:01:00.0000000Z
Setialized to universal format 2021-04-16T00:01:00Z
Setialized to default format 16.04.2021 0:01:00Setialized with conversion to universal time 15.04.2021 21:01:00Kind: Local

Input: 2021-04-15T21:01:00.0000000Setialized to universal format 2021-04-15T21:01:00Z
Setialized to default format 15.04.2021 21:01:00Setialized with conversion to universal time 15.04.2021 18:01:00Kind: Unspecified

Input: 2021-04-15T14:01:00.0000000 -7:00Setialized to universal format 2021-04-16T00:01:00Z
Setialized to default format 16.04.2021 0:01:00Setialized with conversion to universal time 15.04.2021 21:01:00Kind: Local1234567891011121314151617复制代码类型:[cpp]

如您所见,ISO-8601格式的字符串与指定了时区的任何其他日期字符串一样对待。

我的意图不是将其视为本地时间,而是将其视为UTC时间。我的目标是为前端提供通用时间,以便将其调整为最终用户的本地时间。我们如何欺骗.NET认为这是没有任何时区的通用时间?答案是接受的过载DateTimeStyles:

private static void OutputDateInfo(string value){
    Console.WriteLine($"Input: {value}");    if (DateTime.TryParse(value, null, DateTimeStyles.AdjustToUniversal,
                          out DateTime universalTime))
    {
        Console.WriteLine($"Adjusted to universal {universalTime}");
    }

    Console.WriteLine();
}1234567891011复制代码类型:[cpp]

输出:

Input: 2021-04-15T21:01:00.0000000Z
Adjusted to universal 15.04.2021 21:01:00Input: 2021-04-15T21:01:00.0000000Adjusted to universal 15.04.2021 21:01:00Input: 2021-04-15T14:01:00.0000000 -7:00Adjusted to universal 15.04.2021 21:01:0012345678复制代码类型:[cpp]

我认为,DateTimeKind在文学和博客中代表性不足。但是,在解析日期字符串并将日期转换回字符串时,绝对应该考虑到这一点。另外,值得记住的是,ISO-8601格式的日期字符串与指定了时区信息的任何其他字符串一样,尽管乍一看可能并不明显。

(0)

相关推荐

  • 假设客车的座位数是9行4列,使用二维数组在控制台应用程序中实现简单的客车售票系统。

    具体要求为: 使用一个二维数组记录客车售票系统中的所有座位号,并在每个座位号上都显示有票,然后用户输入一个坐标位置,按Enter键,即可将该座位号显示为已售. 首先我定义的输入格式为:1,2 个人认为 ...

  • 如何批量修改word文档中字母的大小写

    在使用word文档编辑文字的时候,尤其是手动输入的时候往往不能考虑很周全,导致文档中的英文字母的大小写错误,或者由于完成稿件后,boss给出修改意见--文档中的字母的大小写需要修改.对于篇幅较短的文档 ...

  • 26个英语字母的大小写

    ‭‮好良‬‬的书写不仅让人赏心悦目,而且‭‮会还‬‬影响考试中你的得分哦![衰][衰]很多‭‮学同‬‬由于刚开始学英语时‭‮有没‬‬注意自己的书写,养成了一些‭‮好不‬‬的书写习惯,导致考试‭‮亏吃‬ ...

  • word如何快速切换英文字母的大小写

    word文档在不同的场景,对字母的大小写的要求不同.如果我们已经完成的文档的编辑,当我们将文档应用到其他场合时,我们不需要修改文本的内容,只需要修改文本中字母的大小写.有什么方法可以实现快速修改呢?下 ...

  • Excel教程:6个表格字母数值大小写转换技巧

    一.首字母转为大写 函数公式:=PROPER(A1) 二.英文单词大写 函数公式:=UPPER(A1) 三.英文单词小写 函数公式:=LOWER(A1) 四.中文小写数值 函数公式:=NUMBERST ...

  • Word办公技巧:如何快速切换英文字母的大小写?

    应用场景 将电影<泰坦尼克号>主题曲英文歌名'my heart will go on'快速在下图4种大小写显示形态之间进行切换. 方法一.通过'更改大小写'按钮进行切换. 操作办法: 先在 ...

  • 英文字母的大小写转换(Excel、Word)

    函数公式.职场模板 .财务应用.分析图表.练习题.软件工具.表格合并.图表及可视化.Office 365.Power Query.表格美化.符号作用.条件格式.学会骗.一本不正经.避坑指南.数据整理. ...

  • 大小写字母的转换

    Lower将文本变为小写:upper将文本为大写:proper将文本中第一个字母变为大写. 下表是不同函数返回的结果: 今天的分享到此结束,如果想看更多历史文章,请从菜单所有文章查看,或者点击所有文章 ...

  • 随机产生数字和大小写字母,你会吗?

    你好,我是刘卓.欢迎来到我的公号,excel函数解析.今天咱们来学习下随机产生数字和大小写字母的方法.也就是随机产生0-9,A-Z和a-z中的字符. -01- 随机产生数字和大小写字母 下图就是用函数 ...

  • 学习26个字母英文绘本来看看这本《Kipper's A to Z》

    绘本简介:这是一个关于小狗Kipper和小猪Arnold在玩耍过程中不断碰到不同字母开头的小动物和物品的故事.这场字母冒险之旅可谓状况百出,从小巧的蚂蚁,讲到大黄蜂,毛毛虫.最后登场的是俏皮可爱的斑马 ...