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 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
4 Réponses :
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. p> blockQuote>
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. P>
- TimeStamp Début du programme et associez-le avec un compteur li>
- Utilisez le compteur pour des mesures séquentielles à intervalles fixes li>
- TimeStamp Nouvelle valeur compteur (s) telle que nécessaire pour garder vos données correctement synchronisées li> ol>
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. P>
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, P>
http://skarnet.org/software/skalibs/libstddjb/tai.html < / a> p>
Vous devez implémenter une horloge tai basée sur C ++ std :: starting_clock ou similaire. Pour synchroniser votre horloge tai, vous pouvez compter sur GPS ou NTP. P>
Option TAI de NTP: Votre implémentation de TAI aurait besoin de connaissances sur les secondes. Probablement protocole NTP ou Ressources référencées sont les sources les plus fiables des sauts actuels et futurs secondes. p>
Option TAI à partir de GPS: GPS Horloge a un décalage fixe à TAI, vous n'avez pas à vous désordre avec des secondes sautées p>
Vérifiez à l'aide de clock_realTime code> et clock_tai code> renvoie de même parce que le paramètre Kernel Tai_offset code> est zéro. P>
ADJTIMEX (TIMEX TMX) CODE> et lisez la valeur. Je pense que NTPD code> le définira s'il est assez nouveau (> 4.2.6 code>) 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 () code> peut définir tai_offset code> manuellement lorsqu'il est exécuté en tant que root. Vous aurez besoin d'un nouvel ish man code> page pour adjtimex code> pour voir les paramètres à définir. Mon man code> est trop vieux mais la commande a fonctionné. P>
En plus de la réponse acceptée correcte, je mentionnerais également la librairie Il utilise une horloge monotone basée sur 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>
Java.Time Code> ne peut pas faire tout), Li>
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> 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)
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 code> 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.