Tıpkı Java'nın aldığı 1970 yılından bu yana milisaniye cinsinden güncel zaman damgası nasıl alınır


135

Java'da, System.currentTimeMillis()çağ zamanından bu yana Milisaniye cinsinden geçerli zaman damgasını almak için kullanabiliriz -

1 Ocak 1970 UTC'de geçerli saat ile gece yarısı arasındaki milisaniye cinsinden ölçülen fark.

C ++ 'da aynı şey nasıl elde edilir?

Şu anda bunu geçerli zaman damgasını almak için kullanıyorum -

struct timeval tp;
gettimeofday(&tp, NULL);
long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000; //get current timestamp in milliseconds

cout << ms << endl;

Bu doğru görünüyor mu değil mi?

Yanıtlar:


240

C ++ 11 kitaplıklarına erişiminiz varsa, std::chronokitaplığa bakın. Unix Epoch'tan bu yana geçen milisaniyeleri şu şekilde elde etmek için kullanabilirsiniz:

#include <chrono>

// ...

using namespace std::chrono;
milliseconds ms = duration_cast< milliseconds >(
    system_clock::now().time_since_epoch()
);

92
Güzel. Temel tür biçiminde milisaniye sayısını elde etmek için satırın sonuna count () ekleyin.
P1r4nh4

1
@lining: Her iki dönem de büyük olasılıkla aynıdır, ancak değerleri farklı olabilir. steady_clockdaima ileriye doğru ilerleyecektir, çağından bu yana geçen zamanın gerçek bir ölçüsü iken system_clock, çağdan beri mantıksal zamanın bir temsili olabilir. Her artık saniye için ikisi, sistemin uygulamasına bağlı olarak daha da büyüyebilir.
Oz.

4
Bildiğim kadarıyla, her bir saatin dönemi uygulamaya bağlıdır. Konvansiyon, system_clockUNIX çağıyla aynı olması içindir, ancak teknik özellikler yalnızca bunun sistem genelinde gerçek zamanlı duvar saati olması gerektiğini söylüyor. steady_clockGerçeğe uyma şartı yoktur , sadece ileriye doğru hareket eder.
Oz.

1
@Jason gettimeofday'ın Windows'ta mevcut olmamasının yanı sıra, krono kitaplığı size daha yüksek çözünürlük sağlayabilir (gtod, mikrosaniye ile sınırlıdır), zaman birimlerini tür açısından güvenli bir şekilde sağlar, böylece derleyici birim dönüştürmeleri uygulayabilir ve normal aritmetik operatörlerle çalışır ( timevalyapı eklemek can sıkıcıdır).
Oz.

3
Javascript geliştiricileri şunu
görmeme

42

kullanım <sys/time.h>

struct timeval tp;
gettimeofday(&tp, NULL);
long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;

bakın bu .


iyi bir çözüm, ayrıca gettimeofday (& tp, NULL) olması gerektiğini düşünüyorum;
Adem

4
Her şeyden önce, bu C ++ değil, C. İkincisi, orada gettimeofday sorunlar vardır bakın bu örneğin.
rustyx

18

Bu cevap Oz'a oldukça benziyor , <chrono>C ++ için kullanıyor - Onu Oz'dan almadım. rağmen...

Bu sayfanın altından orijinal pasajı aldım ve tam bir konsol uygulaması olacak şekilde biraz değiştirdim. Bu küçük 'ol' şeyi kullanmayı seviyorum. Çok fazla komut dosyası yazıyorsanız ve Windows'ta, VB veya daha az modern, daha az okuyucu dostu kod kullanmadan gerçek milisaniyeler içinde dönemi elde etmek için güvenilir bir araca ihtiyacınız varsa harika.

#include <chrono>
#include <iostream>

int main() {
    unsigned __int64 now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    std::cout << now << std::endl;
    return 0;
}

Negatif bir sayı aldım -560549313, bu doğru değil, değil mi?
Noitidart

1
@Noitidart Bana hangi platformu ve C ++ derleyicisini kullandığınızı söyleyebilir misiniz? Bu şeyi her zaman otomasyon araçlarıyla kullanıyorum ve olumsuz bir çıktı görmedim o.0 Yine de kontrol etmekten çok mutluyum. Ayrıca, bu doğrudan bir kopya mı yoksa değiştirilmiş / entegre bir program mı? Sadece bu koddan geldiğinden emin olmak istiyorum.
kayleeFrye_onDeck

5
Ah @kayleeFrye_onDeck onun çünkü ben kullanıyordum int! int nowms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();. Bunu olarak değiştirdim int64_tve işe yarıyor! Yardım etmek için daha fazla bilgi istediğin için çok teşekkürler!
Noitidart

unsigned long longdaha taşınabilir ve __int64yalnızca MSVC'de mevcuttur.
SS Anne

__int64standart C ++ 'da tür yoktur . Bunun std::int64_tyerine kullanılabilir.
jaskmar

15

C ++ 11'den beri şunları kullanabilirsiniz std::chrono:

  • geçerli sistem saatini al: std::chrono::system_clock::now()
  • çağdan beri zaman al: .time_since_epoch()
  • temeldeki birimi milisaniyeye çevirin: duration_cast<milliseconds>(d)
  • std::chrono::millisecondstamsayıya çevir ( uint64_ttaşmayı önlemek için)
#include <chrono>
#include <cstdint>
#include <iostream>

uint64_t timeSinceEpochMillisec() {
  using namespace std::chrono;
  return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}

int main() {
  std::cout << timeSinceEpochMillisec() << std::endl;
  return 0;
}

Bunun unsigned long longyerine kullanmayı öneririm uint64_t.
csg

Neden unsigned long longyerine uint64_t? Daha kısa
yazıyı yazmak

13

Gettimeofday kullanıyorsanız, uzun süre çevirmeniz gerekir, aksi takdirde taşmalar elde edersiniz ve bu nedenle, dönemden beri gerçek milisaniye sayısı olmaz: long int msint = tp.tv_sec * 1000 + tp.tv_usec / 1000; size 767990892 gibi çağdan 8 gün sonra yuvarlak olan bir sayı verecektir ;-).

int main(int argc, char* argv[])
{
    struct timeval tp;
    gettimeofday(&tp, NULL);
    long long mslong = (long long) tp.tv_sec * 1000L + tp.tv_usec / 1000; //get current timestamp in milliseconds
    std::cout << mslong << std::endl;
}

-25

İşlevi dahil edin <ctime>ve kullanın time.


31
Bu, dönemden bu yana geçen saniyeleri döndürür. Milisaniye değil.
Progo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.