8
votes

Comment obtenir le temps tai actuel?

Comment puis-je obtenir le temps de tai actuel en millisecondes sous Linux en utilisant Java ou C ++?

La raison dont j'ai besoin de cela est de pouvoir prendre avec précision des horodatages sur une longue période (sur l'ordre des années) et toujours être capable de les comparer, sans se soucier de sauter des secondes. Il est possible que de multiples mesures aient lieu au cours d'une seconde saut et toutes les mesures doivent être sans ambiguïté, croissantes monotoniquement et augmenter linéairement. Ce sera un serveur Linux dédié. Ceci est pour un projet scientifique qui a besoin de précision d'environ 0,5 seconde. P>

Je souhaite actuellement investir dans un cheader GPS et espère utiliser NTP pour la piscine.ntp.org afin de conserver le système. horloge sur la piste. p>

J'ai examiné les solutions suivantes: p>

Java 8 ou le projet Thratéen Strong> Le seul moyen d'obtenir un taiinstant est d'utiliser un instant, puis de le convertir, ce qui, selon les spécifications, "la conversion d'un instant ne sera pas complètement précise à proximité d'un saut seconde conformément à l'UTC-SLS". Qu'en soie et en soi n'est pas une grosse affaire (en fait, l'UTC-SLS serait également acceptable). Cependant, en utilisant maintenant () en la classe instantanée semble également être un wrapper pour System.Currenttimemémis (), ce qui me fait penser que pendant le saut de seconde, le temps sera toujours ambigu et le projet ne me donnera pas de temps à tai . Les spécifications Java 8 indiquent également: P>

Les implémentations de l'échelle temporelle Java à l'aide de l'API JSR-310 sont pas nécessaire pour fournir toute horloge sous-seconde précise, ou que progresse monotone ou doucement fort>. Les implémentations sont donc non requis pour effectuer réellement le SLS UTC-SLS ou pour être autrement au courant des secondes saut. p> blockQuote>

en utilisant un droit /? Timezone strong> Cela semble que cela fonctionnerait, mais je ne sais pas si la mise en œuvre est suffisamment intelligente pour continuer à travailler pendant une seconde saut ou si System.CurrentTimemillis () donnerait même à Tai Time. En d'autres termes, la mise en œuvre sous-jacente utiliserait-elle toujours UTC, donnant ainsi une période ambiguë au cours de la seconde LEAP, qui est ensuite convertie en TAI, ou utilise-t-il un TAI qui fonctionne avec TAI à l'aide de System.Currenttimemillis () Toujours (même pendant saut seconde)? p>

Utiliser horlock_tai strong> J'ai essayé d'utiliser horlock_tai dans le noyau Linux, mais j'ai trouvé qu'il est complètement identique à Clock_RealTime dans mon test: CODE: P>

1427744797
6896
1427744797


0 commentaires

4 Réponses :


3
votes

La raison pour laquelle j'ai besoin de cela est de pouvoir prendre avec précision des horodatages sur une longue période de temps (sur l'ordre des années) et être capable encore Pour les comparer, sans vous soucier de sauter des secondes. C'est possible pour plusieurs mesures à avoir lieu pendant une seconde saut et tout les mesures doivent être sans ambiguïté, croissant monotone et augmentation linéaire.

Alors votre conception est sous-optimal. Vous ne pouvez pas utiliser le temps, puis en quelque sorte vous mêler à des secondes. Cela revient effectivement assez souvent et les gens tombent dans le même piège des mesures d'horodatage utilisant une horloge murale.

  1. TimeStamp Début du programme et associez-le avec un compteur
  2. Utilisez le compteur pour des mesures séquentielles à intervalles fixes
  3. TimeStamp Nouvelle valeur compteur (s) telle que nécessaire pour garder vos données correctement synchronisées

    Si vous évitez que l'horodatage pendant 1 seconde que peut se produire (minuit!), vous êtes gratuit, car ceux-ci peuvent être ajustés plus tard.

    Maintenant, si vous insistez sur l'utilisation de TAI sans comptoir, tout ce dont vous avez besoin est une table avec des secondes saut qui doivent être comptabilisées. Ensuite, utilisez simplement le temps monotonique. Il existe également des bibliothèques qui peuvent le faire pour vous, mais elles peuvent être obsolètes pour que vous puissiez les maintenir vous-même,

    http://skarnet.org/software/skalibs/libstddjb/tai.html < / a>


0 commentaires


4
votes

clock_realTime et clock_tai renvoie de même parce que le paramètre Kernel Tai_offset est zéro.

Vérifiez à l'aide de ADJTIMEX (TIMEX TMX) et lisez la valeur. Je pense que NTPD le définira s'il est assez nouveau (> 4.2.6 ) et a un deuxième fichier saut. Il peut également être capable de le faire des serveurs en amont, mais je n'ai pas pu vérifier. L'appel adjtimex () peut définir tai_offset manuellement lorsqu'il est exécuté en tant que root. Vous aurez besoin d'un nouvel ish man page pour adjtimex pour voir les paramètres à définir. Mon man est trop vieux mais la commande a fonctionné.


0 commentaires

3
votes

En plus de la réponse acceptée correcte, je mentionnerais également la librairie Java Library Time4J fort> ( MIN Version v4.1 ) La solution possible parce que

  • Je l'ai écrit pour remplir un écart dans Java World ( Java.Time Code> ne peut pas faire tout), Li>
  • Autres réponses données jusqu'à présent, ne parlez qu'à propos de C ++ (mais vous avez également demandé Java), LI>
  • Cela fonctionne selon les mêmes principes décrits par @ user3427419. li> ul>

    Il utilise une horloge monotone basée sur System.nanotime () code> mais permet même des implémentations personnalisées via l'interface TickProvider code>. Aux fins de l'étalonnage, vous pouvez utiliser net.time4j.systemclock.monotonic code> ou vous utilisez une horloge SNTP nommée sntpconnector code> qui nécessite simplement une configuration simple pour se connecter à tout serveur de temps NTP que vous voulez. Et grâce à la TIME-TAIRE LEAP intégrée4J peut même vous montrer le saut annoncé deuxième à la fin de ce mois - dans la notation ISO-8601 ou même comme une chaîne horodatale locale formatée dans n'importe quel fuseau horaire (utilisation I18N-Module) . P>

    Recalibration (dans le cas de NTP - Reconnect) des horloges est possible signifie que les horloges peuvent être adaptées aux ajustements de temps intermédiaires (bien que je recommande vivement de ne pas le faire pendant vos mesures ou pendant une seconde sauvegarde ). Bien qu'une telle reconnexion d'une horloge SNTP entraîne normalement le temps de descente dans certains cas Time4j tente d'appliquer un algorithme de lissage (s'il est activé dans la configuration de l'horloge) pour assurer un comportement monotone. La documentation détaillée est disponible en ligne . P>

    Exemple: strong> P>

    URL url = new URL("https://www.ietf.org/timezones/data/leap-seconds.list");
    BufferedReader br =
        new BufferedReader(
            new InputStreamReader(url.openStream(), "US-ASCII"));
    String line;
    PlainDate expires = null;
    Moment ntpEpoch = PlainTimestamp.of(1900, 1, 1, 0, 0).atUTC();
    List<PlainDate> events = new ArrayList<PlainDate>();
    
    try {
        while ((line = br.readLine()) != null) {
            if (line.startsWith("#@")) {
                long expraw = Long.parseLong(line.substring(2).trim());
                expires = ntpEpoch.plus(
                  expraw, TimeUnit.SECONDS)
                .toZonalTimestamp(ZonalOffset.UTC).toDate();
                continue;
            } else if (line.startsWith("#")) {
                continue; // comment line
            }
    
            // this works for some foreseeable future
            long epoch = Long.parseLong(line.substring(0, 10)); 
    
            // this is no leap second 
            // but just the official introduction of modern UTC scale
            if (epoch == 2272060800L) {
                continue;
            }
    
            // -1 because we don't want to associate 
            // the leap second with the following day
            PlainDate event = 
              ntpEpoch.plus(epoch - 1, TimeUnit.SECONDS)
                      .toZonalTimestamp(ZonalOffset.UTC).toDate();
            events.add(event); // we don't assume any negative leap seconds here for simplicity
        }
    } finally {
        br.close();
    }
    
    // now let's write the result into time4j-format
    // use a location relative to class path of main program (see below)
    String path = "C:/work/leapseconds.txt"; 
    Writer writer = new FileWriter(new File(path));
    String sep = System.getProperty("line.separator");
    
    try {
        for (PlainDate event : events) {
            writer.write(event + ", +" + sep);
        }
        writer.write("@expires=" + expires + sep);
    } finally {
        writer.close();
    }
    
    System.out.println(
      "Leap second file was successfully written from IETF-resource.");
    
    // And finally, we can start the main program in a separate process
    // with the system property "net.time4j.scale.leapseconds.path"
    // set to our leapsecond file path (must be relative to class path)
    


5 commentaires

Comment votre bibliothèque gère-t-elle les secondes à long terme? En d'autres termes, si une demande est redémarrée plusieurs années à l'avenir, comment puis-je vous assurer qu'elle a une connaissance de secondes saut qui se sont produites au cours des dernières années?


@DanielCenterore NOUVEAU LEAP SECONDES Peut être importé en mettant ainsi à jour vos deux secondes Data, soit via une nouvelle version de la bibliothèque, soit via la mise à jour du module TZData (en fait l'importation d'une nouvelle version TZDB de iana.org/tz). TIME4J gère également un Drapeau d'expiration qui pourrait Soyez utilisé pour la programmation d'alertes pour le sysadmin si les deuxième données sautent devenues vieilles. N'oubliez pas le fait qu'il n'est pas possible de conserver les données plus de 6 mois à l'avance dans un état valide.


Y a-t-il un moyen recommandé de simplement gérer cela automatiquement, en téléchargeant automatiquement les ressources d'Internet?


@DanielCenterore Je ne suis au courant d'aucune bibliothèque Java qui télécharge et installe automatiquement la dernière version TZDB. Mais je peux imaginer qu'il est possible d'écrire un net.time4j.tz.zoneprovider qui fait exactement cela et remplacera logiquement le module TZData de TIME4J. Ce n'est pas une petite tâche de programmation et un peu hors de portée de la bibliothèque de temps car elle inclurait beaucoup de code de connexion Internet spécialisé, déballer des fichiers tar et éventuellement casser si Iana décide de déplacer ou de modifier ses ressources de téléchargement dans le futur. .


Et si je devais télécharger le fichier IETF ( ietf.org/timezones/data/ Leap-secondes.list ) et analysez les secondes à succès au début du programme? Je ne suis tout simplement pas sûr de la façon dont la façon recommandée d'ajouter une deuxième connaissance sauvegarde serait. Mise à jour d'autres informations sur le fuseau horaire n'est pas particulièrement importante pour moi.