开发者

C# DateTime.Ticks equivalent in Java

开发者 https://www.devze.com 2023-01-16 14:22 出处:网络
What is the Java equivalent of DateTime.Ticks in C#? DateTime dt = new DateTime(201开发者_运维技巧0, 9, 14, 0, 0, 0);

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

DateTime dt = new DateTime(201开发者_运维技巧0, 9, 14, 0, 0, 0);
Console.WriteLine("Ticks: {0}", dt.Ticks);

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


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 :(


In Java is:

long TICKS_AT_EPOCH = 621355968000000000L; 
long tick = System.currentTimeMillis()*10000 + TICKS_AT_EPOCH;


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


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


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)
    */
}


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


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

精彩评论

暂无评论...
验证码 换一张
取 消