java.sql.Timestamp konstruktor iść tak:java.sql.Timestamp sposób przechowywania nanosekund
public Timestamp(long time) {
super((time/1000)*1000);
nanos = (int)((time%1000) * 1000000);
if (nanos < 0) {
nanos = 1000000000 + nanos;
super.setTime(((time/1000)-1)*1000);
}
}
Zasadniczo przyjmuje czas w milisekundach, a następnie wyodrębnia 3 ostatnie cyfry i sprawia, że nano. Tak więc dla wartości milisekundowej 1304135631 , otrzymuję Timestamp.getnanos() jako . To proste obliczenie (dodanie 6 zer na końcu) ... nie wydaje się optymalne.
Lepszym sposobem może być konstruktor znacznika czasu, który akceptuje czas w nanosekundach, a następnie oblicza wartość nanosekundy.
Jeśli uruchomisz poniższy program, zobaczysz różnicę między rzeczywistymi nanosekundami a tą zwróconą przez sposób obliczania nanosekund.
long a = System.currentTimeMillis();
for(;;){
long b = System.currentTimeMillis();
Timestamp tm = new Timestamp(System.currentTimeMillis());
System.out.println(tm.getTime());
System.out.println(tm.getNanos());
System.out.println("This is actual nanos" + System.nanoTime()%1000000000);
System.out.println("--------------------------");
if(b-a >= 1)
break;
}
więc cała dyskusja o Timestamp, które mówi, że przechowuje czas do nanosekund, nie wydaje się być tak poprawne .. Czy nie?
Tak ... To na pewno zadziała. Aby znacznik czasu faktycznie przechowywał nanopy, powinien to być proces dwuetapowy. Nieco niewygodne, zamiast tego Konstruktor, który akceptuje nanos (od 1 stycznia 1970) byłby lepszym rozwiązaniem. – Vicky
Nie jest to bezpieczne! Omija! Problem polega na tym, że 'currentTimeMillis' i' nanoTime' mogą nie zgodzić się na większą rozdzielczość. na przykład 'nanoTime' zwraca wartości 12: 06: 30.9999, 12:06: ** 31 ** .1111, ale' currentTimeMillis' zwraca 12: 06: 30.666 12:06: ** 30 ** .777, a następnie używając powyższego kodu aby zainicjować znacznik czasu, pojawią się znaczniki czasu 12: 06: 30.9999, 12:06: ** 30 ** .1111. Oddzielnie, komentarz re @Vicky, jak zainicjowałbyś znacznik czasu przed 1970? – Luciano
To prawda, że ustawienie sekund nano musi być ustawione osobno, ale użycie 'System # nanoTime()' w ten sposób nie jest poprawne. Dokumentacja API dla 'System # nanoTime()' mówi: "Ta metoda może być używana tylko do pomiaru czasu, który upłynął i nie jest związana z żadnym innym pojęciem czasu systemu lub zegara ściennego.Zwrócona wartość reprezentuje nanosekundy od pewnego ustalonego, ale arbitralnego czasu (być może w przyszłości, więc wartości mogą być ujemne). "(Zobacz http://download.oracle.com/javase/6/docs/api/java/lang/System .html # nanoTime% 28% 29) –