如何将Javascript日期时间转换为C#日期时间?

77

我看到很多人提到,如果你想将JavaScript日期转换为C#日期,应该使用getTime()函数,并将其结果加到一个C# DateTime对象上。

假设我有以下JavaScript时间:

Date {Tue Jul 12 2011 16:00:00 GMT-0700 (Pacific Daylight Time)}

它渲染成 1310522400000 毫秒

var a = new DateTime(1970, 01, 01).AddMilliseconds(1310522400000);

// result
7/13/2011 2:00:00 AM

所以这是错误的。我不确定我需要做什么。


1
它们是相同的... 2011年7月13日2:00:00 AM - 7 (GMT delta) -1 夏令时 = 2011年7月12日星期二16:00:00 GMT-0700(太平洋夏令时间) - Chandu
1
@Cybernate,我认为你已经下线了。16:00和2:00之间相差10个小时。 - Hand-E-Food
1
@Hand:你是对的。我想是时候去睡觉了。 - Chandu
可能是重复问题:https://dev59.com/OXI-5IYBdhLWcg3wZ3YR - MD. SHAKIL AHMED.
17个回答

95

您可以使用JavaScript中的toJSON()方法,将JavaScript DateTime转换为C#可识别的DateTime。

JavaScript代码如下:

var date = new Date();
date.toJSON(); // this is the JavaScript date as a c# DateTime

注意:结果将以协调世界时表示


这是一个不错的解决方案,但它会从实际时间中减去时间,也就是说,我有挪威时间是11:34,它给我09:34,你能解释一下吗? - Ninja
我必须将其作为“字符串”在我的REST服务上接受,然后将其转换为DateTime。否则,由于签名不正确,REST服务方法将无法被调用。 - Cryptc
3
@MHanif - 我相信之所以会这样是因为 .toJSON() 返回的是 UTC 时间。 - Gwasshoppa
是的,@Gwasshoppa 正确,我已经更新了答案以反映您的评论。谢谢! - Garth
2
@MHanif 在服务器端使用 UTC 时间,您可以轻松地使用 .ToLocalTime() 方法将其转换为本地时间。https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tolocaltime?view=net-5.0 - adopilot

49

使用JavaScript中的以下函数首先创建符合你所需格式的字符串。

var date = new Date();
var day = date.getDate();       // yields date
var month = date.getMonth() + 1;    // yields month (add one as '.getMonth()' is zero indexed)
var year = date.getFullYear();  // yields year
var hour = date.getHours();     // yields hours 
var minute = date.getMinutes(); // yields minutes
var second = date.getSeconds(); // yields seconds

// After this construct a string with the above results as below
var time = day + "/" + month + "/" + year + " " + hour + ':' + minute + ':' + second; 

将此字符串传递给代码后端函数并将其作为字符串参数接受。在代码后端中使用DateTime.ParseExact()将此字符串转换为DateTime,如下所示:

DateTime.ParseExact(YourString, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);

希望这可以帮助到你...


5
如果Javascript返回的是单个数字,您需要在前面附加一个“0”。为此,您应该使用“HH.length()”,“mm.length()”等,并相应构造字符串(变量Time)。 - Harun
4
getYear已被弃用,应使用.getFullYear。 - Sheldon Hage
1
它对我起作用了,但正如之前所说,我使用了Date.getFullYear()。 - makoshichi
3
使用getDate()和getDay()方法可以分别获取日期和星期几(索引)。 - Rune Jeppesen
3
另外在JavaScript中getMonth()从零开始,所以七月会返回6,在C#中会得到错误的月份。 - Pravin
显示剩余5条评论

35

你的想法基本正确,只需要做出一个小修正:

var a = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
    .AddMilliseconds(1310522400000)
    .ToLocalTime();

当我测试这个时,时间差了2分50秒。 - Jon Dosmann

11
如果你想从JS发送日期到C#,那么其实非常简单——如果发送UTC日期是可以接受的话。
var date = new Date("Tue Jul 12 2011 16:00:00 GMT-0700");
var dateStrToSendToServer = date.toISOString();

...发送到C#端...

var success = DateTimeOffset.TryParse(jsISOStr, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var result);

C# DateTime 已经能够理解ISO日期格式,可以很好地解析它。

要从C#格式化到JS,只需使用 DateTime.UtcNow.ToString("o")

个人而言,我从不放心在不同环境之间依靠数学和逻辑来获取毫秒/刻度以显示用户可能在客户端上看到的完全相同的日期和时间(特别是在重要场合)。我在转移货币时也会这样做(使用字符串更安全,或将美元和分离成两个不同的整数)。发送日期/时间作为单独的值也是一个好方法(请参见接受的答案)。


9

DateTime.Parse 是一个更好的选择。JS日期和C#日期不是从同一根源开始的。

示例:

DateTime dt = DateTime.ParseExact("Tue Jul 12 2011 16:00:00 GMT-0700",
                                  "ddd MMM d yyyy HH:mm:ss tt zzz",
                                  CultureInfo.InvariantCulture);

问题在于我不知道如何将你从ajax中硬编码的字符串传递到我的MVC操作方法中。如果我尝试传递日期对象,它不会发送。即使我在我的操作方法中使用"string"作为参数。 - chobo2
3
你的意思是无法将JS中的Date序列化成已知格式(例如Date.toUTCString()),并将其发送到MVC操作中?你能贴出你的Ajax代码吗? - Mrchief
Date.toUTCString() 返回 GMT 结尾(没有时区偏移 #)。格式中的 GMTzzzzz 部分会导致解析失败。此外,您缺少一个逗号。最后,它将无法与所有具有不同区域设置的客户端良好地配合使用。在我的系统上,它是 "Sun, 04 Feb 2018 09:50:00 GMT"(注意月份之前的日期)。 - James Wilkins
@JamesWilkins 感谢您指出格式字符串中的拼写错误。此外,这些答案并不意味着是生产就绪的代码,也不能处理可能存在的每种排列组合。示例代码基于 OP 的代码样本。本地化/国际化是一个更深入的主题。 - Mrchief
我基于问题“如何将Javascript日期时间转换为C#日期时间?”进行操作。 OP仅显示了一个日期输出,它不是他们代码的一部分。对于任何新读者来说,使用JS和C#之间的ISO格式以外的任何东西都是一个坏主意;) 使用{Date} .toISOString(),C#将自然解析它。 - James Wilkins
虽然我认为 ISO 字符串可能是跨系统之间最好的选择,但你意识到这个答案是在 toISOString 还不是标准时写的吗?或者当 IE 仍然是最流行的浏览器时?无论如何,欢迎您编辑这个答案。 - Mrchief

5

如果您的应用程序中使用moment.js。

var x = moment(new Date()).format('DD/MM/YYYY hh:mm:ss')

x传递给codebehind函数并将其作为字符串参数接受。在C#中使用DateTime.ParseExact()将此字符串转换为DateTime,如下所示:

DateTime.ParseExact(YourString, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);

你的 JavaScript 代码应该使用 HH:mm:ss 格式,因为后端已经使用了 HH 格式。如果不这样做,1700 小时会变成 0500 小时。 - sindrem

5

由于我所在的时区不同,我的JavaScript和C#在同一日期上会有2小时的差异(即使我试图将日期作为日期发送到Web服务,而不是转换为字符串/其他对象)。

我尝试使用JavaScript中的getTime()函数,并将毫秒数添加到C#日期(从1970-01-01开始),但我始终会提前两个小时得到我的C#日期。

为了确保两边获取相同的日期和时间,我最终做了这个:

在JavaScript中,我使用了UTC函数:

var jsDate = Date.UTC(year,month,day,hours,minutes,seconds,millisec);

在C#中获取正确的DateTime,我是这样做的:

var date = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddMilliseconds(jsDate);

希望能够帮助到某些人。

4

更新:从 .NET 版本 4.6 开始,请使用 FromUnixTimeMilliseconds 方法,该方法位于 DateTimeOffset 结构中:

DateTimeOffset.FromUnixTimeMilliseconds(1310522400000).DateTime

1

如果您在美国太平洋时区,那么对于您来说,纪元是1969年12月31日下午4点。您需要将自纪元以来的毫秒数加上

new DateTime(1970, 01, 01)

由于它没有时区,因此被解释为处于您的时区。

将时间瞬间视为自纪元以来的毫秒数并没有什么问题,但要理解纪元只有1970-01-01T00:00:00Z。

如果表示为日期,您无法考虑不带时区的时间瞬间。


0

我认为你可以使用 TimeZoneInfo 来转换日期时间。

    static void Main(string[] args)
    {
        long time = 1310522400000;
        DateTime dt_1970 = new DateTime(1970, 1, 1);
        long tricks_1970 = dt_1970.Ticks;
        long time_tricks = tricks_1970 + time * 10000;
        DateTime dt = new DateTime(time_tricks);

        Console.WriteLine(dt.ToShortDateString()); // result : 7/13
        dt = TimeZoneInfo.ConvertTimeToUtc(dt);

        Console.WriteLine(dt.ToShortDateString());  // result : 7/12
        Console.Read();
    }

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