【问题标题】:Parse JS date to C# DateTime将 JS 日期解析为 C# DateTime
【发布时间】:2012-09-04 16:48:38
【问题描述】:

我有一个 javascript 日期对象,它给我一个日期字符串,格式为“Tue Sep 04 2012B0100 (GMT Daylight Time)”

我正在尝试使用 ParseEaxcat 解析 here,但它会引发无效的日期异常 - 任何人都指向正确格式的方向

                string date = "Tue Sep 04 2012B0100 (GMT Daylight Time)";
                dt = DateTime.ParseExact(date,"ddd MMM dd yyyyBzzzz",
                     CultureInfo.InvariantCulture);

我也很不高兴地看着这个: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

【问题讨论】:

  • 我可能错了,但我想格式字符串中的破折号“-”在这里会造成一些麻烦,因为它们不在源字符串中?
  • 这听起来像是一种非标准的日期时间格式,你确定 B 不是加号吗?您可能需要对字符串进行一些预处理以让 .NET 对其进行解析。
  • 如果您有英文日期和月份名称,使用 InvariantCulture 可能会很糟糕。

标签: c# javascript datetime


【解决方案1】:

如果可以(听起来好像你有对象),我建议从 Javascript (.getTime()) 中提取自 1970/01/01 以来的毫秒数,将其转换为 .Net 刻度(100 纳秒单位),并使用它来解析为 C# DateTime。

var ticks = (jsMillis * 10000) + 621355968000000000;
var date = new DateTime(ticks);

其中 jsMillis 是您通过在 Javascript DateTime 对象上调用 getTime() 获得的数字。

621355968000000000 用于将 C# 的日期来源(0001 年 1 月 1 日午夜)转换为 javascript 的日期来源。

【讨论】:

  • +1 - 在 JS 中使用date.getTime() 获取纪元时间是解决此问题的正确方法。试图解析date.toString() 的结果充满了危险。另请参阅C# epoch conversion functions here
  • 这不是 getTime() - 考虑使用 valueOf(),它是从 1970 年 1 月 1 日午夜开始的毫秒数
【解决方案2】:

这行得通。不过,您可能希望在传递之前去掉 GMT 夏令时部分,以避免内联拆分。

string date = "Tue Sep 04 2012B0100 (GMT Daylight Time)";
var dt = DateTime.ParseExact(date.Split('(')[0].Replace("B","+").Trim(), "ddd MMM dd yyyyzzz", CultureInfo.InvariantCulture);

已编辑以考虑偏移量。

【讨论】:

  • 您会注意到,如果您使用 ToString 表示 dt,您会得到类似 2012 年 4 月 39 日的信息。 3 是您的星期几。如果你需要在另一边像这样格式化它; dt.ToString("mm/dd/yy");
  • 这将在它不会引发异常的意义上起作用,但它不会只是将 UTC 偏移设置为日期的小时和分钟吗?
  • 要用 zzz 解析偏移量,它似乎在寻找一个 + 修饰符。通过将 B 替换为 + 应该会得到您想要的结果。
【解决方案3】:

我从 JavaScript 中获得了不同的日期时间格式。这是我必须做的:

public void Main()
{
    Console.WriteLine(
        ConvertJsDate("Fri Apr 18 2014 16:23:18 GMT-0500 (Central Daylight Time)"));
    //test more regular date
    Console.WriteLine(
        ConvertJsDate("4/18/2014 16:23:18")); 
}

public DateTime ConvertJsDate(string jsDate)
{
    string formatString = "ddd MMM d yyyy HH:mm:ss";

    var gmtIndex = jsDate.IndexOf(" GMT");
    if (gmtIndex > -1) 
    {
        jsDate = jsDate.Remove(gmtIndex);
        return DateTime.ParseExact(jsDate, formatString, null);
    }
    return DateTime.Parse(jsDate);
}

【讨论】:

    【解决方案4】:

    日期似乎与格式字符串不匹配。格式字符串有连字符,并且缺少括号部分。此外,没有提及具有 4 个 z 的格式字符串,因此您可以将第一个 z 更改为 0。

    【讨论】:

      【解决方案5】:

      另一种方法是在 JavaScript 端将日期转换为合理的表示形式,这将明显更加健壮:无需猜测服务器端的语言,可以正确处理时区。

      如果您使用某种自动转换(即 JSON.stringify),您可能需要添加一个与日期字段平行的字段,并使用相同值的字符串表示,并在服务器端使用它而不是原始字段。

      { dateFied: new Date(),
        dateFiledAsIsoString: "....." }
      

      如果决定采用这条路线,请考虑将时区(时间偏移)传递给服务器端代码或在 JavaScript 端将时间转换为 UTC。考虑使用 ISO8601 格式的日期:yyyy-MM-ddTHH:mm:ss.fffffffzzz。

      【讨论】:

      • 你在第一部分是对的 - JS 应该将 Date 转换为更可靠的表示。但是,与其处理字符串,不如使用getTime() 来获取自纪元以来的滴答数。这样一来,您就完全不用担心时区了。
      • @josh3736,我不确定如果您使用刻度,您如何避免不处理时区(除非您先转换为 UTC 而不是刻度,我认为这不是您建议)?
      • getTime 总是自动处理 UTC。
      • @josh3736,愿意提供链接吗?据我所知,它只是从当地时间(1970 年 1 月 1 日)的特定时刻偏移,但您无法在不知道计算时区的情况下将 1346789616870 之类的数字转换为更正时间...
      • getTime on MDN:“返回按照世界时指定日期时间对应的数值。”
      【解决方案6】:

      有很多方法可以做到这一点……但这是我发现的最简单的方法……

      // JavaScript
      var d = new Date();
      d.toLocaleString();
      // =>   "6/26/2015, 2:07:25 PM"
      
      // Can be Parsed by the C# DateTime Class
      DateTime d = DateTime.Parse( @"6/26/2015, 2:07:25 PM" );
      Console.WriteLine( d.ToLongDateString() );
      // =>   Friday, June 26, 2015
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多