Question

constructeur java.sql.Timestamp aller comme ceci:

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

Il accepte essentiellement le temps en milliseconde, puis extrait les 3 derniers chiffres et fait Nanos. Donc, pour une valeur de milliseconde 1304135631 421 , je me fais Timestamp.getnanos () comme 421000000 . Ce calcul est simple (ajout de 6 zéros à la fin) ... ne semble pas être optimale.

Une meilleure façon aurait pu être constructeur Timestamp qui accepte le temps en nanosecondes et calcule ensuite la valeur de nanoseconde de cela.

Si vous exécutez le programme ci-dessous, vous verrez la différence entre nanosecondes réelle et celle retournée par Horodatage de calcul nanosecods.

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

Donc la discussion sur Timestamp qui dit qu'il stocke le temps jusqu'à nanosecondes, ne semble pas être si bon .. est-ce pas?

Était-ce utile?

La solution

Le temps Millis ne représente pas le temps nanos. Plus précisément, il peut tout simplement pas. Vous êtes censé utiliser Timestamp#setNanos() pour définir les véritables nanos.

long timeInMillis = System.currentTimeMillis();
long timeInNanos = System.nanoTime();

Timestamp timestamp = new Timestamp(timeInMillis);
timestamp.setNanos((int) (timeInNanos % 1000000000));

// ...

Autres conseils

Depuis l'introduction de java.time.*, il y a une nouvelle méthode d'usine java.sql.Timestamp: Timestamp.from(Instant.now()) fera le travail (avec une précision de nanosecondes). Il y a aussi Timestamp.toInstant() pour le convertir dans l'autre sens.

Bien qu'il soit un ancien poste, je voudrais ajouter que les documents de Timestamp ne déclarer qu'il « détient des fractions de seconde en permettant la spécification des fractions de seconde à une précision de nanaoseconds ». La partie est source de confusion « hold ». Cela semble déroutant au début, mais si on le comprend bien, il ne fait pas état qu'il détient nanaoseconds value.It dit qu'il « détient » valeur fractionnelle et lui permet d'être une « précision » de la nanoseconde. La précision doit être comprise en termes de représentation du nombre total de chiffres. Donc, il essentiellement signifie que la partie est en fait fractionnée (encore millisecondes) mais est multiplié par 1000000 pour le représenter comme nanosecondes.

La réponse acceptée (par toujours utile Baluc) résume bien.

Je aime la mise en œuvre de OpenJPA de TimestampHelper . Il utilise initialiseurs statiques pour garder une trace de nanosecondes se sont écoulées entre les appels à faire un horodatage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top