27

What is the Java equivalent of DateTime.Ticks in C#?

DateTime dt = new DateTime(2010, 9, 14, 0, 0, 0);
Console.WriteLine("Ticks: {0}", dt.Ticks);

What will be the equivalent of above mentioned code in Java?

Kyle Rosendo
  • 25,001
  • 7
  • 80
  • 118

7 Answers7

49

Well, java.util.Date/Calendar only have precision down to the millisecond:

Calendar calendar = Calendar.getInstance();    
calendar.set(Calendar.MILLISECOND, 0); // Clear the millis part. Silly API.
calendar.set(2010, 8, 14, 0, 0, 0); // Note that months are 0-based
Date date = calendar.getTime();
long millis = date.getTime(); // Millis since Unix epoch

That's the nearest effective equivalent. If you need to convert between a .NET ticks value and a Date/Calendar you basically need to perform scaling (ticks to millis) and offsetting (1st Jan 1AD to 1st Jan 1970).

Java's built-in date and time APIs are fairly unpleasant. I'd personally recommend that you use Joda Time instead. If you could say what you're really trying to do, we can help more.

EDIT: Okay, here's some sample code:

import java.util.*;

public class Test {

    private static final long TICKS_AT_EPOCH = 621355968000000000L;
    private static final long TICKS_PER_MILLISECOND = 10000;

    public static void main(String[] args) {
        long ticks = 634200192000000000L;

        Date date = new Date((ticks - TICKS_AT_EPOCH) / TICKS_PER_MILLISECOND);
        System.out.println(date);

        TimeZone utc = TimeZone.getTimeZone("UTC");
        Calendar calendar = Calendar.getInstance(utc);
        calendar.setTime(date);
        System.out.println(calendar);
    }
}

Note that this constructs a Date/Calendar representing the UTC instant of 2019/9/14. The .NET representation is somewhat fuzzy - you can create two DateTime values which are the same except for their "kind" (but therefore represent different instants) and they'll claim to be equal. It's a bit of a mess :(

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • In my current scenario i had saved Ticks value calculated in C#; now what i want is read that tick value and get the same date in Java. –  Sep 14 '10 at 05:37
  • 1
    @Asoo: Okay. Walking to work ATM - code in twenty minutes. Basically divide by ticks per millisecond and subtract an offset. You should also bear timezone offsets in mind. – Jon Skeet Sep 14 '10 at 05:41
  • Thanks @Skeet....But if i want to calculate the ticks in Java and read them in C#.....i tried this but it does not gives the identical value: TimeZone utc = TimeZone.getTimeZone("UTC"); Calendar calendar = Calendar.getInstance(utc); calendar.set(2010,8,14,0,0,0); System.out.println(calendar.getTimeInMillis() * TICKS_PER_MILLISECOND + TICKS_AT_EPOCH); –  Sep 14 '10 at 06:27
  • @Asoo: It looks like it's keeping the existing millis-in-second value - call `calendar.set(Calendar.MILLISECOND, 0);` before the other call to `calendar.set()`. I'll update my answer. – Jon Skeet Sep 14 '10 at 06:39
  • There's a tiny, tiny, tiny improvement you could make, if you added 5000 to (ticks - TICKS_AT_EPOCH) before you divide by TICKS_PER_MILLISECOND. Then you'd be rounding to the nearest millisecond instead of truncating down. – RenniePet Mar 05 '15 at 02:51
  • @RenniePet: I wouldn't say that's always an improvement - it depends on the situation. But in the OP's case, it looks like there'll never be a sub-millisecond value anyway. – Jon Skeet Mar 05 '15 at 06:20
23

In Java is:

long TICKS_AT_EPOCH = 621355968000000000L; 
long tick = System.currentTimeMillis()*10000 + TICKS_AT_EPOCH;
Sruit A.Suk
  • 7,073
  • 7
  • 61
  • 71
Cristian Keller
  • 231
  • 2
  • 2
  • 2
    using Local zone (analogue of DateTime.Now.Ticks) `long tick = (System.currentTimeMillis() + TimeZone.getDefault().getRawOffset()) * 10000 + TICKS_AT_EPOCH;` – Alex78191 Jan 28 '19 at 14:16
  • @Alex78191 has pointed out a good (missing) point as in answer. Time Zone must be considered otherwise will not calculate correct current time outside of GMT. "import java.util.*" is required to compile suggested change. – S.ATTA.M Aug 04 '20 at 07:27
10

System.nanoTime() gives you nanoseconds in Java (since 1.6). You'll still need to shift/rescale, but no precision will be lost.

Andrey Breslav
  • 24,795
  • 10
  • 66
  • 61
  • nanoTime has nothing with clock time, which means it can't be converted or compared with Ticks from .net DateTime. Here is quote from javadoc: This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). – Stas Nov 08 '15 at 21:15
3

Base on Jon Skeet I developed this class

import java.util.Calendar;
import java.util.Date;

public class DateHelper {

    private static final long TICKS_AT_EPOCH = 621355968000000000L;
    private static final long TICKS_PER_MILLISECOND = 10000;

    public static long getUTCTicks(Date date){

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return (calendar.getTimeInMillis() * TICKS_PER_MILLISECOND) + TICKS_AT_EPOCH;

    }

    public static Date getDate(long UTCTicks){

        return new Date((UTCTicks - TICKS_AT_EPOCH) / TICKS_PER_MILLISECOND);

    }

}

It works for me

Pablo V
  • 71
  • 2
  • this is the only one that worked for me? maybe i was missing something! – Nicholas DiPiazza Nov 10 '18 at 05:42
  • +1 It works, although the method names have totally nothing to do with UTC. Just `Ticks from Date` and `Date from Ticks`. This is useful for an Android app written in Xamarin, the DB libraries store DateTime as ticks in the DB - this works for it. – Pierre Jun 24 '19 at 14:23
0

And for those of us showing up trying to get the current number of ticks as defined by the UUID specification:

/**
    Returns the current tick count.
    Ticks are the number of 100 ns intervals since October 15, 1582
    @return
*/
private static long getUtcNowTicks() {

    final long UNIX_EPOCH_TICKS = 122192928000000000L; //Number of ticks from 10/16/1582 to 1/1/1970
    Instant i = Clock.systemUTC().instant(); //get the current time
    long ticks = UNIX_EPOCH_TICKS; // number of ticks as of 1/1/1970
    ticks += i.getEpochSecond()*10000000; //number of whole seconds (converted to ticks) since 1/1/1970
    ticks += i.getNano() / 100; //number of ticks since the start of the second

    return ticks;

    /*
    Some interesting tick values

    Date            Ticks
    ==========  ==================
    10/15/1582                   0  Start of UUID epoch; the date we switched to the Gregorian calendar)
     1/01/1601    5748192000000000  Start of Windows epoch (start of 1st Gregorian 400-year cycle)
    12/30/1899  100101312000000000  Start of Lotus 123, Excel, VB, COM, Delphi epoch
     1/01/1900  100103040000000000  Start of SQL Server epoch
     1/01/1970  122192928000000000  Start of UNIX epoch
     1/01/2000  131659776000000000
     1/01/2010  134815968000000000
     1/01/2020  137971296000000000
     1/19/2038  143714420469999999  UNIX Y2k38 problem (January 19, 2038  3:14:07 am)
    */
}
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
-1

To convert .Net Ticks to millis in java use this :

static final long TICKS_PER_MILLISECOND = 10000;
long ticks = 450000000000L; // sample tick value
long millis = (ticks  / TICKS_PER_MILLISECOND);
ReZa
  • 1,273
  • 2
  • 18
  • 33
-1

There are 10,000 ticks in a millisecond, and C# considers the beginning of time January 1, 0001 at midnight. Here's a one-liner which converts an Instant to ticks.

public static long toTicks(Instant i)
{
   return Duration.between(Instant.parse("0001-01-01T00:00:00.00Z"), i).toMillis() * 10000;
}
Dima
  • 2,601
  • 1
  • 18
  • 9