C# DateTime.Ticks equivalent in Java
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;
}
精彩评论