74

I have been reading that if you want to convert from JavaScript dates to C# dates you should use getTime() and then add that result to a C# DateTime.

Suppose I have this JavaScript time:

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

It renders to 1310522400000 milliseconds

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

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

So this is wrong. I am not sure what I need to do.

Moob
  • 14,420
  • 1
  • 34
  • 47
chobo2
  • 83,322
  • 195
  • 530
  • 832

17 Answers17

95

You could use the toJSON() JavaScript method, it converts a JavaScript DateTime to what C# can recognise as a DateTime.

The JavaScript code looks like this

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

Note: The result will be in UTC time

Garth
  • 3,237
  • 2
  • 18
  • 28
  • its is good solution, but it subtracts time from actual time, means i have norwegian time which is 11:34 it gives me 09:34, can you please explain? – Ninja May 25 '19 at 09:48
  • I had to accept this as a "string" on my REST service, then convert it to a DateTime. Otherwise, the REST service method wasn't being called due to an incorrect signature. – Cryptc Jun 04 '19 at 16:40
  • 3
    @MHanif - I believe if is because the .toJSON() is in UTC time – Gwasshoppa Jun 30 '19 at 22:36
  • Yes @Gwasshoppa correct, I've updated the answer to reflect your comment. Thanks! – Garth Mar 31 '20 at 14:54
  • 1
    @MHanif on server side UTC time you can easily convert to local using .ToLocalTime() https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tolocaltime?view=net-5.0 – adopilot Mar 31 '21 at 12:56
48

First create a string in your required format using the following functions in 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; 

Pass this string to codebehind function and accept it as a string parameter.Use the DateTime.ParseExact() in codebehind to convert this string to DateTime as follows,

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

Hope this helps...

Ryan Den-Kaat
  • 118
  • 1
  • 5
Harun
  • 5,109
  • 4
  • 38
  • 60
  • I am not sure if I should DateTime.ParseExact it seems very picky. I think sometimes the javascript will send like 2 digits for the hours and sometimes one. If it sends one then it won't parse since the pattern you have has "HH". So should I do something like DateTime.Parse(Start);? – chobo2 Jul 15 '11 at 16:15
  • 5
    You should append a "0" in front if javascript returns only a single digit. For that you should use "HH.length()","mm.length()",etc.... and construct the string (var Time)accordingly. – Harun Jul 16 '11 at 01:11
  • 4
    getYear is deprecated. Use .getFullYear – Sheldon Hage Apr 29 '13 at 01:14
  • 1
    It worked for me but as it has been said before, I used Date.getFullYear(). – makoshichi Nov 14 '13 at 17:33
  • 3
    Use getDate() getDay() returns day of week (index) – Rune Jeppesen Apr 01 '14 at 13:27
  • 3
    Also getMonth() starts from zero in javascript, so you will get 6 for July which will result in wrong month in C# – Pravin Jul 07 '15 at 14:34
  • 1
    You could also pass `day,month,year,hour,minute,second` to your controller as `int`'s and then have C# make a `new DateTime(year, month, day, hour, minute, second);` This can solve the problem where C# rejects strings like "1/1/2016" because it's not "01/01/2016". – jmbmage Jun 01 '16 at 19:06
  • it should also be getDate() instead of getDay() as getDay() returns the day of the week not month. – jmona789 Jan 12 '17 at 19:43
  • But you'll lose time zone info in this case – iroel Apr 05 '18 at 05:13
  • Such a bad day man.. for not prepending zero in one missed field!!! oohhh.. @Harun – Thameem Jun 08 '21 at 07:53
34

You were almost right, there's just need one little fix to be made:

var a = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
    .AddMilliseconds(1310522400000)
    .ToLocalTime();
JG in SD
  • 5,427
  • 3
  • 34
  • 46
vasiliy
  • 366
  • 3
  • 4
10

If you want to send dates to C# from JS that is actually quite simple - if sending UTC dates is acceptable.

var date = new Date("Tue Jul 12 2011 16:00:00 GMT-0700");
var dateStrToSendToServer = date.toISOString();

... send to C# side ...

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

C# DateTime already understands ISO date formats and will parse it just fine.

To format from C# to JS just use DateTime.UtcNow.ToString("o").

Personally, I'm never comfortable relying on math and logic between different environments to get the milliseconds/ticks to show the EXACT same date and time a user may see on the client (especially where it matters). I would do the same when transferring currency as well (use strings instead to be safe, or separate dollars and cents between two different integers). Sending the date/time as separate values would be just a good (see accepted answer).

James Wilkins
  • 6,836
  • 3
  • 48
  • 73
9

DateTime.Parse is a much better bet. JS dates and C# dates do not start from the same root.

Sample:

DateTime dt = DateTime.ParseExact("Tue Jul 12 2011 16:00:00 GMT-0700",
                                  "ddd MMM d yyyy HH:mm:ss tt zzz",
                                  CultureInfo.InvariantCulture);
Mrchief
  • 75,126
  • 20
  • 142
  • 189
  • The problem with this is I don't know how to get that hardcoded string you have from ajax to my MVC action method. If I try to pass in the date object it does not send it. Even if I use like "string" as the parameter in my action method. – chobo2 Jul 15 '11 at 16:09
  • 3
    You mean you're not able to serialize your JS `Date` as `string` to a known format (like `Date.toUTCString()` and send it to your MVC action? Can you post your ajax code? – Mrchief Jul 15 '11 at 16:15
  • `Date.toUTCString()` returns an ending of `GMT` (no timezone offset #). The `GMTzzzzz` part of the formatting causes parsing to fail. Also, you're missing a comma. Finally, it will not work well with all clients with different regional settings. On my system it is "Sun, 04 Feb 2018 09:50:00 GMT" (notice the day BEFORE the month). – James Wilkins Feb 04 '18 at 09:51
  • @JamesWilkins Thanks for pointing out the typo in the format string. Also, these answers are not meant to be production ready code nor handle every possible permutation there can be. The example code is based on OP's code sample. Localization/Internationalization is a much deeper subject. – Mrchief Feb 05 '18 at 21:20
  • I'm basing it on the question "How to convert Javascript datetime to C# datetime?". The OP only showed a Date output, it was not part of their code. The approach to use _anything_ other than the ISO format between JS and C# is a BAD idea for anyone new reading this. ;) Use `{Date}.toISOString()` and C# will parse it naturally. – James Wilkins Feb 06 '18 at 02:05
  • While I agree that ISO string is probably the best between cross systems, you realize this answer was written when `toISOString` was not a standard? Or when IE was still the most dominant browser? Anyway, you're welcome to edit this answer. – Mrchief Feb 06 '18 at 14:18
5

Since I'm in a different timezone, my JavaScript and C# end up having 2 hours difference between the same date (even when I tried to send the date to a webservice as a date [not converted to string/another object]).

I tried to use the getTime() in JavaScript and add the milliseconds to a C# date (starting on 1970-01-01) but I've always ended up with two hours in advance on my C# date.

To grant that I would get the same Date and Hour in both sides I ended up doing this:

In JavaScript I've used the UTC function:

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

And in C# to get the correct DateTime I did this:

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

Hope it helps someone.

Rafael Merlin
  • 2,517
  • 1
  • 25
  • 31
5

If you are using moment.js in your application.

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

Pass x to codebehind function and accept it as a string parameter. Use the DateTime.ParseExact() in c# to convert this string to DateTime as follows,

DateTime.ParseExact(YourString, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
raga
  • 899
  • 10
  • 14
  • your javascript code should probably be HH:mm:ss since you have HH in backend. If not, 1700 hours becomes 0500 hours. – sindrem Nov 28 '17 at 13:35
4

UPDATE: From .NET Version 4.6 use the FromUnixTimeMilliseconds method of the DateTimeOffset structure instead:

DateTimeOffset.FromUnixTimeMilliseconds(1310522400000).DateTime
Andriy Tolstoy
  • 5,690
  • 2
  • 31
  • 30
1

If you are in the U.S. Pacific time zone, then the epoch for you is 4 p.m. on December 31, 1969. You added the milliseconds since the epoch to

new DateTime(1970, 01, 01)

which, since it did not have a timezone, was interpreted as being in your timezone.

There is nothing really wrong with thinking of instants in time as milliseconds since the epoch but understand the epoch is only 1970-01-01T00:00:00Z.

You can't think of instants in times, when represented as dates, without timezones.

Ray Toal
  • 86,166
  • 18
  • 182
  • 232
0

JavaScript (HTML5)

function TimeHelper_GetDateAndFormat() {
    var date = new Date();

    return MakeValid(date.getDate()).concat(
        HtmlConstants_FRONT_SLASH,
        MakeValid(date.getMonth() + 1),
        HtmlConstants_FRONT_SLASH,
        MakeValid(date.getFullYear()),
        HtmlConstants_SPACE,
        MakeValid(date.getHours()),
        HtmlConstants_COLON,
        MakeValid(date.getMinutes()),
        HtmlConstants_COLON,
        MakeValid(date.getSeconds()));
}

function MakeValid(timeRegion) {
    return timeRegion !== undefined && timeRegion < 10 ? ("0" + timeRegion).toString() : timeRegion.toString();
}

C#

private const string DATE_FORMAT = "dd/MM/yyyy HH:mm:ss";

public DateTime? JavaScriptDateParse(string dateString)
{
    DateTime date;
    return DateTime.TryParseExact(dateString, DATE_FORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None, out date) ? date : null;
}
MyKuLLSKI
  • 5,285
  • 3
  • 20
  • 39
0

There were some mistakes in harun's answer which are corrected below:

1) date where harun used getDay() which is incorrect should be getDate()

2) getMonth() gives one less month than actual month, So we should increment it by 1 as shown below

var date = new Date();
var day = date.getDate();           // yields 
var month = date.getMonth() + 1;    // yields month
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; 

Pass this string to codebehind function and accept it as a string parameter.Use the DateTime.ParseExact() in codebehind to convert this string to DateTime as follows,

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

This Worked for me! Hope this help you too.

Rohit Arora
  • 2,246
  • 2
  • 24
  • 40
0

JS:

 function createDateObj(date) {
            var day = date.getDate();           // yields 
            var month = date.getMonth();    // yields month
            var year = date.getFullYear();      // yields year
            var hour = date.getHours();         // yields hours 
            var minute = date.getMinutes();     // yields minutes
            var second = date.getSeconds();     // yields seconds
            var millisec = date.getMilliseconds();
            var jsDate = Date.UTC(year, month, day, hour, minute, second, millisec);
            return jsDate;
        }

JS:

var oRequirementEval = new Object();
var date = new Date($("#dueDate").val());

CS:

requirementEvaluations.DeadLine = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
    .AddMilliseconds(Convert.ToDouble( arrayUpdateRequirementEvaluationData["DeadLine"]))
    .ToLocalTime();
Jaydeep Shil
  • 1,894
  • 22
  • 21
0

You can also send Js time to C# with Moment.js Library :

JavaScript : var dateString = moment(new Date()).format('LLLL')

C# : DateTime.Parse(dateString);

AminSojoudi
  • 1,904
  • 2
  • 18
  • 42
0

I think you can use the TimeZoneInfo....to convert the datetime....

    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();
    }
shenhengbin
  • 4,236
  • 1
  • 24
  • 33
0
var date = new Date(this.newItemDate).toDateString();

this line of code works for me

Hamed
  • 21
  • 1
  • 10
0
var date = new Date(2022,11,9).toISOString();

This creates the ISO string variant of the date in javascript, and in your .net API, you can expect a DateTime type of parameter, because c# automatically translates iso string dates into DateTime objects.

Honorable mention:

enter image description here

dezox
  • 146
  • 9
-3
Newtonsoft.Json.JsonConvert.SerializeObject(Convert.ToDateTime(dr[col.ColumnName])).Replace('"', ' ').Trim();