将JS日期解析为C# DateTime

3
我有一个 JavaScript 日期对象,它给我一个日期字符串,格式如下:"Tue Sep 04 2012B0100 (GMT Daylight Time)"。
我正在尝试使用 ParseExact 进行解析,就像这里提到的一样(链接),但它会抛出无效日期异常。请问有人可以指导我正确的日期格式吗?
                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


7
可能我错了,但是我认为格式字符串中的破折号“-”会引起一些问题,因为它们在源字符串中不存在。 - sybkar
听起来像是一个非标准的日期时间格式,你确定B不是加号吗?你可能需要对字符串进行一些预处理,以便让.NET解析它。 - driis
如果你使用英文日期和月份名称,那么在使用InvariantCulture时可能会有问题。 - driis
6个回答

8

如果您能够(而且看起来您已经可以了,因为您拥有该对象),我建议从Javascript中提取自1970年01月01日以来的毫秒数(使用.getTime()方法),将其转换为.Net滴答数(100纳秒单位),然后使用它来解析成C# DateTime。

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

在 Javascript DateTime 对象上调用 getTime() 函数所得到的数字就是 jsMillis。

而 621355968000000000 则是将 C# 的日期起始点(即公元 1 年 1 月 1 日午夜)转换为 Javascript 的日期起始点。


1
+1 - 在JS中使用date.getTime()获取纪元时间是解决此问题的正确方法。尝试解析date.toString()的结果充满了危险。另请参见C#纪元转换函数 - josh3736
不是 getTime() - 考虑使用 valueOf(),它是从1970年1月1日午夜开始的毫秒数。 - Yuki

3

这行代码是可用的。不过,在传入之前你可能需要去掉GMT Daylight Time部分,以避免内联拆分。

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的输出结果类似于39/04/12。其中3代表星期几。如果需要在另一端进行格式化,可以使用以下代码:dt.ToString("mm/dd/yy")。 - J. Tanner
这段代码在语法上是正确的,不会抛出异常,但它只是将UTC偏移量设置为日期上的小时和分钟吗? - BikerP
要使用zzz解析偏移量,似乎需要添加一个 + 修饰符。通过将B替换为+,你应该可以得到所需的结果。 - J. Tanner

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);
}

0

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

// 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

0

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


0

另一种方法是将日期转换为JavaScript端的合理表示,这将显着提高鲁棒性:无需在服务器端猜测语言,可以正确处理时区。

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

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

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

你在第一部分是正确的 - JS 应该将 Date 转换为更可靠的表示形式。然而,与其处理字符串,不如直接使用 getTime() 获取自纪元以来的滴答数。这样,您就完全不必担心时区问题了。 - josh3736
@josh3736,如果你使用ticks,我不确定你如何避免处理时区(除非你先转换为UTC再转换为ticks,但我认为这不是你所建议的)? - Alexei Levenkov
getTime 自动处理 UTC 时间。 - josh3736
@josh3736,能提供一个链接吗?据我所知,它只是相对于本地时间(1970年1月1日)的特定时刻的偏移量,但如果不知道计算时所在的时区,就无法将像1346789616870这样的数字转换为正确的时间... - Alexei Levenkov
2
在 MDN 上的 getTime:返回一个数字值,该值对应于指定日期根据世界协调时间的时间。 - josh3736

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接