【问题标题】:Date Formatting C#日期格式化 C#
【发布时间】:2013-07-07 12:52:23
【问题描述】:

我在将此日期格式转换为另一种格式时遇到问题。我希望这里的人能够帮助我。

这是我的代码:

string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz"; 
string toFormat = "yyyy-MM-dd";

DateTime newDate = DateTime.ParseExact("Mon, 25 03 2013 00:00:00 GMT", fromFormat, null);

Console.WriteLine(newDate.ToString(toFormat));

-------编辑--------

通过将日期从 22 更改为 25,我能够摆脱错误。我的新问题是试图让时区从 GMT 转换为 EST。有人有什么想法吗?

-------编辑#2-------

这是我当前的代码。我仍然遇到时区转换问题。

var date = "Mon, 25 03 2013 00:00:00 GMT";

// Cuts off "GMT" portion of string
string newdate = date.Substring(0, 24);

// Switches the output of date
string fromFormat = "ddd, dd MM yyyy HH:mm:ss";
string toFormat = "yyyy-MM-dd";

DateTime newDate = DateTime.ParseExact(newdate, fromFormat, null);
string finaldate = newDate.ToString(toFormat);

// Output final date
Console.WriteLine(finaldate);

-------编辑#3-------

代码:

var input = "Mon, 25 03 2013 00:00:00 GMT";
var inner = input.Substring(0, 24);
var format = "ddd, dd MM yyyy HH:mm:ss";
var zoneId = "Eastern Standard Time";

var parsed = DateTime.ParseExact(inner, format, CultureInfo.InvariantCulture);

var utcDateTime = DateTime.SpecifyKind(parsed, DateTimeKind.Utc);
var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTime, zoneId);


Console.WriteLine(eastern);

错误:

Unhandled Exception: System.TimeZoneNotFoundException: Exception of type
   'System.TimeZoneNotFoundException' was thrown.
at System.TimeZoneInfo.FindSystemTimeZoneByFileName (System.String id, System.String
   filepath) [0x00000] in :0 
at System.TimeZoneInfo.FindSystemTimeZoneById (System.String id) [0x00000] in :0 
at System.TimeZoneInfo.ConvertTimeBySystemTimeZoneId (DateTime dateTime, System.String 
   destinationTimeZoneId) [0x00000] in :0 
at Program.Main () [0x00000] in :0 

任何帮助将不胜感激!谢谢!

-------最终编辑-------

这就是最终更改时区并转换为我需要的格式的原因。特别感谢@MattJohnson 的所有帮助!

// Cuts off 'GMT' portion of string
var newdate = date.Substring(0, 24);

var fromFormat = "ddd, dd MM yyyy HH:mm:ss";
var toFormat = "yyyy-MM-dd";
var zoneId = "Eastern Standard Time";


var parsed = DateTime.ParseExact(newdate, fromFormat, CultureInfo.InvariantCulture);

// Specifies UTC time and converts it to EST timezone
var utcDateTime = DateTime.SpecifyKind(parsed, DateTimeKind.Utc);
var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTime, zoneId);

// Converts date to final format needed
var finaldate = eastern.ToString(toFormat);

【问题讨论】:

  • 您最好从 JavaScript 发送正确的 ISO8601 字符串(类似于 2013-22-03T00:00Z)...

标签: c# datetime


【解决方案1】:

22 03 2013 00:00:00 GMT 不是星期一而是星期五

试试

            string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz";
            string toFormat = "yyyy-MM-dd";

            Console.WriteLine(DateTime.ParseExact("Fri, 22 03 2013 00:00:00 +00:00", fromFormat,
                             CultureInfo.InvariantCulture).ToString(toFormat));

【讨论】:

    【解决方案2】:
    string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz"; 
    

    错误是您的zzz,它是expecting the numerical representation of the timezone,而不是时区的缩写。

    所以可接受的版本是

    DateTime newDate = DateTime.ParseExact("Mon, 22 03 2013 00:00:00 +0:00", fromFormat, null);
    

    但这会引发不同的 FormatExecption 并显示消息 “字符串未被识别为有效的 DateTime,因为星期几不正确。” 如果您使 the Monday to Friday correction 解析有效

    DateTime newDate = DateTime.ParseExact("Fri, 22 03 2013 00:00:00 +0:00", fromFormat, null);
    

    我认为没有格式说明符可以接受时区的文本缩写版本。

    【讨论】:

    • 没有。为此,他必须自己动手。
    • 即使我取出代码的zzz 和GMT 部分,它仍然会抛出相同的错误。当我删除 ddd 和 zzz 部分时,错误将停止。
    • 2013 年 3 月 22 日的确切解析是星期五 - 这就是抛出 FormatException 的原因。如果您从外部来源获取日期,则数据不正确。
    • 您误会了,因为您测试的日期不正确。 2013-03-22 不是星期一,而是星期五。
    • 如果Mon、Tue、Wed 不可靠,您必须在尝试解析它并删除 ddd 部分之前将其从字符串中删除。
    【解决方案3】:

    要查看问题所在,请使用您的 fromString 打印 DateTime:

    DateTime dt = new DateTime(2013, 3, 22);
    string s = dt.ToString(fromFormat);
    

    你会看到输出是:

    Fri, 22 03 2013 00:00:00 -04:00
    

    这就是它所期望的格式。

    您也许可以从 this article 获得一些关于缩写的帮助。

    【讨论】:

      【解决方案4】:

      有两个问题:

      1) 选择的日期是星期五而不是星期一

      2) 'zzz' 想要正负 0:00

      所以,要让它工作是:

      string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz";
      string toFormat = "yyyy-MM-dd";
      
      DateTime newDate = DateTime.ParseExact("Fri, 22 03 2013 00:00:00 +0:00", fromFormat, null);
      
      Console.WriteLine(newDate.ToString(toFormat));
      

      【讨论】:

        【解决方案5】:

        没有简单的内置方法可以将时区缩写转换为偏移量或专有名称。这将在本主题中讨论:

        Timezone Abbreviations

        您需要创建要使用的缩写表,映射到偏移量或专有名称,或者您需要更改传入日期/时间字符串的格式以使用偏移量。

        【讨论】:

          【解决方案6】:
          string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz"; 
          string toFormat = "yyyy-MM-dd";
          
          DateTime newDate = DateTime.ParseExact("Mon, 22 03 2013 00:00:00 +00:00", fromFormat, null);
          
          Console.WriteLine(newDate.ToString(toFormat));
          

          【讨论】:

            【解决方案7】:

            正如其他人指出的那样,您拥有的输入值是自不一致的。它将 2013 年 3 月 22 日称为星期一,而实际上它是星期五。因此,您应该返回源数据并找出发生这种情况的原因。相信你一定听过“垃圾进,垃圾出”这句话。

            如果您确定要忽略星期几,并且确定时区始终为 GMT,那么您可以这样做:

            var input = "Mon, 22 03 2013 00:00:00 GMT";
            var inner = input.Substring(5, 19);
            var format = "dd MM yyyy HH:mm:ss";
            var parsed = DateTime.ParseExact(inner, format, CultureInfo.InvariantCulture);
            var utcDateTime = DateTime.SpecifyKind(parsed, DateTimeKind.Utc);
            

            请注意,我将类型明确设置为 UTC,因为您引入了 GMT 值。 GMT 和 UTC 在所有实际用途中都是相同的。

            如果可能会传递其他时区值,请提供不同可能输入的样本,也许我们可以找到一种方法来适应这种情况。

            顺便说一句 - 这个字符串看起来与RFC822/RFC1123 formatted dates 非常相似,除了您将月份作为数字而不是三个字母的缩写之一传递。你是故意这样做的吗?如果是这样,您已经破坏了这种格式的规范。如果您的意图是从数据中删除潜在的可本地化字符串,那么请使用已经为此设计的格式,例如 ISO8601/RFC3339。

            按时区

            您说您想转换为 EST,您的意思可能是“美国东部时间”,它在 EST 和 EDT 之间交替进行夏令时。尽管如此,Windows 时区数据库还是使用“东部标准时间”的 id 来指代这两个值 - 所以尽量不要在这一点上感到困惑。

            一旦您将日期设为 DateTime 或 Utc 类型,如上所示,您可以使用以下命令将其转换为东部时间:

            var zoneId = "Eastern Standard Time"; // don't get confused here! :)
            var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTime, zoneId);
            

            请小心使用此值。如果您将其显示给用户,那么您就可以了。只需这样做:

            var s = eastern.ToString("g"); // or whatever format you want.
            

            但是,如果您对此进行数学运算,或将其存储为记录的事件时间,则可能会在结果中引入错误。这是由于夏令时转换。避免这种情况的一种方法是改用 DateTimeOffset 类型:

            var utcDateTimeOffset = new DateTimeOffset(utcDateTime, TimeSpan.Zero);
            var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTimeOffset, zoneId);
            

            现在,当您使用这些值时,任何歧义都会被偏移量捕获。

            如果这让您感到非常困惑,请不要担心 - 您并不孤单。您可能想尝试改用Noda Time。它可以防止你射中自己的脚。

            【讨论】:

            • 哇,写得真好!我一定错过了昨天发布的所有其他帖子:)不过,我有一些答案和问题要问你!首先,它始终是GMT 时间,只需将其转换为EST 时间。正如您在上面显示的那样,我是否需要转换为UTC 才能让它转到EST 时间?或者我可以保持原样吗?另外,您上面显示的代码是否会考虑夏令时?我知道你告诉我不要混淆,但我做到了:)对不起!
            • GMT 是 UTC。您需要告诉它您有 UTC,否则 DateTime 转换为 ET 将不正确。对于DateTimeOffset 转换,您可以跳过它,但将其保留在原位更正确。是的,代码(原样)将考虑 DST。这就是 TimeZoneInfo 转换所做的一部分。
            • 我在尝试合并您的代码时仍然遇到问题。似乎我收到了字符串错误。我在上面所做的新编​​辑是我用来让它在没有时区转换的情况下工作的。我尝试添加您的代码行:var zoneId = "Eastern Standard Time";var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTime, zoneId);var utcDateTimeOffset = new DateTimeOffset(utcDateTime, TimeSpan.Zero);var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTimeOffset, zoneId); 我确实更改了变量名称,但仍然没有骰子...
            • 那里有两个不同的选项,选择一个。不要同时使用两者。但是,如果您遇到字符串错误,那么它与上半部分有关。您必须更具体地说明您尝试过的内容以及无效的内容。
            • 查看您的编辑,我看到您正在传递null,您应该传递CultureInfo.InvariantCulture。 null 表示使用当前的文化,这取决于您实际使用的文化可能会或可能不会起作用。此外,请确保在尝试转换为 EST 之前将类型指定为 Utc。我在上面的DateTime.SpecifyKind
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多