13

In my system, I am storing a duration in Ticks, which is being passed to my client mobile application, and from there I want to convert ticks into a human readable form. In my case, days, hours and minutes.

My client mobile application is coded using Javascript, and so this is what I'm using to convert the duration to days/hours/minutes.

5 Answers 5

11

In C# .NET, a single tick represents one hundred nanoseconds, or one ten-millionth of a second. [Source].

Therefore, in order to calculate the number of days from the number of ticks (rounded to nearest whole numbers), I first calculate the number of seconds by multiplying by ten million, and then multiplying that by the number of seconds in a day (60 seconds in minute, 60 minutes in hour, 24 hours in day). I use the modulus operator (%) to get the remainder values that make up the duration of hours and minutes.

var time = 3669905128; // Time value in ticks
var days = Math.floor(time/(24*60*60*10000000)); // Math.floor() rounds a number downwards to the nearest whole integer, which in this case is the value representing the day
var hours = Math.round((time/(60*60*10000000)) % 24); // Math.round() rounds the number up or down
var mins = Math.round((time/(60*10000000)) % 60);

console.log('days: ' + days);   
console.log('hours: ' + hours);   
console.log('mins: ' + mins);

So, in the above example, the amount of ticks is equivalent to 6 minutes (rounded up).

And to take another example, with 2,193,385,800,000,000 ticks, we get 2538 days, 15 hours and 23 minutes.

Sign up to request clarification or add additional context in comments.

4 Comments

Please use 10e7 instead of 10000000, this is what exponential notation is useful for!
@Antonijn: This is quite acceptable behavior.
@CL4PTR4P Okay, I wasn't aware of this, thanks for enlightening me!
10e7 has 8 zero's after 1. 10000000 is actually 10e6 :)
10
var ticks = 635556672000000000; 

//ticks are in nanotime; convert to microtime
var ticksToMicrotime = ticks / 10000;

//ticks are recorded from 1/1/1; get microtime difference from 1/1/1/ to 1/1/1970
var epochMicrotimeDiff = Math.abs(new Date(0, 0, 1).setFullYear(1));

//new date is ticks, converted to microtime, minus difference from epoch microtime
var tickDate = new Date(ticksToMicrotime - epochMicrotimeDiff);

According to this page the setFullYear method returns "A Number, representing the number of milliseconds between the date object and midnight January 1 1970".

Check out this page for all the methods from the javascript Date object.

5 Comments

I have use this approach to calculate a date (636874594860000000 ticks), but I don't know why in Javascript I'm getting "Wed Mar 06 2019 10:12:50 GMT+0100" when actually it is "{06/03/2019 08:58:06}" (this is the value returned by new DateTime(636874594860000000) in .NET). I'm worried about the delay in the minutes (of course, the difference between the hours is normal).
That's quite strange. When I'm using this function with the ticks you specified I'm getting Wed Mar 06 2019 09:38:34 GMT+0100 (Mid-Europe standard time) which is the same as the C# DateTime. Are you sure you got the correct ticks? jsfiddle.net/pkmelee337/gwL5up4j/1
Yes, very, very weird...I've executed the jsfiddle you just posted, and I'm still getting the wrong date "Wed Mar 06 2019 10:12:50 GMT+0100 (hora estándar de Europa central)". Even the value you get is not the actual one...I would like to deepen into this issue, but I'm really lost...where I could start to check this problem?
Hmm it might have to do something with the timezones. (but still the difference in minutes is weird) Can you check this one? jsfiddle.net/pkmelee337/gwL5up4j/3 I added Date.UTC() to make sure the date is created on UTC. I really don't know where to start otherwise.
That worked! I just had to pass 0 to the year, setFullYear(0), because it was displaying the date in 2020 year. But at least, the minutes are correct now. Anyway, very weird issue related to timezones...
4

You need to consider 2 things:

Resolution
Ticks in .Net's DateTime are 0.1 Microsecond, while Javascript counts Milliseconds.

Offset
In addition, .Net counts from 1.1.0000 while Javascript counts from 1.1.1970.

TeaFiles.Net has a Time class that uses Java = Javascript ticks. It has a scale property and a predefined Timescale.Java scale, that converts from .Net to Javascript.

Comments

3

At the server-side, you can use a extension method, like this:

public static class DateTimeExtensions {
    private static readonly long UnixEpochTicks = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Ticks;

    public static long? ToJavascriptTicks(this DateTime? value) {
        return value == null ? (long?)null : (value.Value.ToUniversalTime().Ticks - UnixEpochTicks) / 10000;
    }
    public static long ToJavascriptTicks(this DateTime value) {
        return (value.ToUniversalTime().Ticks - UnixEpochTicks) / 10000;
    }
}

With this extensions, you can get the javascript ticks, and then you simply pass them to the client-side.

If you are using MVC:

You have the ViewModel:

public class MyViewModel {
   public long MyJsTicks { get; set; }
}

And the Controller:

public ActionResult Action() {
    long myJsTicks = DateTime.UtcNow.ToJavascriptTicks(); //<-- use the extension method

    MyViewModel viewModel = new MyViewModel();
    viewModel.MyJsTicks = myJsTicks;

    return View(viewModel);
}

At the client-side:

var jsticks = <the js ticks obtained from server-side>;
var mydatetime = new Date(jsticks);

If you are using Razor view engine for your mobile app, getting the calculated js ticks from the server-side in your view is extremely simple, using a in-line expression:

var jsticks = @(Model.MyJsTicks);
var mydatetime = new Date(jsticks);

Finally, to get days, hours and minutes from the javascript Date object:

var hours = mydatetime.getHours();
var minutes = mydatetime.getMinutes();
var seconds = mydatetime.getSeconds();

(as you can see in the javascript "Date" object reference: https://www.w3schools.com/jsref/jsref_obj_date.asp)

Comments

2

Let's make it simpler, shell we?....

according to microsoft: public const long TicksPerDay = 864000000000;

https://learn.microsoft.com/en-us/dotnet/api/system.timespan.ticksperday?view=net-5.0

private int GetDaysDiff(DateTime fromDate, DateTime toDate)
{
    long ticksPerDay = 864000000000;

    long ticksDiff = Math.Abs(fromDate.Ticks - toDate.Ticks);

    var days = ticksDiff / ticksPerDay;

    return (int)days;
}

that's all folks!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.