Saat şu biçimde nasıl yazdırılır: 2009-08-10 18: 17: 54.811


100

Zamanı C biçiminde yazdırmanın en iyi yöntemi nedir 2009‐08‐10 
18:17:54.811?

Yanıtlar:


111

Strftime () kullanın .

#include <stdio.h>
#include <time.h>

int main()
{
    time_t timer;
    char buffer[26];
    struct tm* tm_info;

    timer = time(NULL);
    tm_info = localtime(&timer);

    strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
    puts(buffer);

    return 0;
}

Milisaniyeler için bu soruya bir göz atın. ANSI C kullanarak milisaniye cinsinden süre nasıl ölçülür?


Şimdi daha da iyi bir cevap ve milisaniye kısmının nasıl işleneceğini araştırmak için gerekli. Sanırım tampon belleğiniz artık olması gerekenden biraz daha uzun.
Jack Kelly

16
Daha kısa olmaktan daha uzun olmak daha iyidir :-)
paxdiablo

Harika cevap. PHP'de her tür şeyi yapabilirdim, ama her şeyin zaten C'de olduğunu biliyordum. Teşekkürler.
Vijay Kumar Kanta

1
Belki hat time(&timer)yerine olmalıdır timer = time(NULL);en azından Linux için. The tloc argument is obsolescent and should always be NULL in new code. When tloc is NULL, the call cannot fail.
Antonin Décimo

6
En az bir durumda (Linux) yanıt kesinlikle yanlıştır çünkü localtime () tarafından kullanılan "struct tm" saniyenin altında herhangi bir zaman bilgisini tutmaz. Bunun yerine gettimeofday () tarafından kullanılan "struct timeval" mikrosaniyelere sahiptir ve 1000'e bölündüğünde milisaniye elde edilir. Tüm bu olumlu oylar gerçekten yanlış ve yanıltıcı! Birisi hangi mimari altında "struct tm" ile saniyenin altında zaman ayrıntılarını aldığınızı bildirmediği sürece.
EnzoR

35

Yukarıdaki cevaplar soruyu tam olarak cevaplamıyor (özellikle milisaniye kısmı). Buna çözümüm, strftime'dan önce gettimeofday kullanmaktır. Milisaniyeyi "1000" e yuvarlamaktan kaçınmaya dikkat edin. Bu, Hamid Nazari'nin cevabına dayanmaktadır.

#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>

int main() {
  char buffer[26];
  int millisec;
  struct tm* tm_info;
  struct timeval tv;

  gettimeofday(&tv, NULL);

  millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
  if (millisec>=1000) { // Allow for rounding up to nearest second
    millisec -=1000;
    tv.tv_sec++;
  }

  tm_info = localtime(&tv.tv_sec);

  strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", tm_info);
  printf("%s.%03d\n", buffer, millisec);

  return 0;
}

gettimeofdayWindows uygulamalarında mevcut değil
Mendes

Lütfen oluştururken '-lm' seçeneklerini ekleyin.
skysign

3
Tamponun [24] yeterli olduğunu düşünüyorum, nedeni aşağıdaki gibi, YYYY: MM: DD SS: DD: SS.mmm + '\ 0', 24.
skysign

@Mendes, neden Windows'tan bahsediyorsun? Soru sade C dili ile ilgili. Tüm bu yanlış oylamalara rağmen bu daha iyi bir cevaptır (doğru olmasa da)!
EnzoR

2
user3624334: Hayır, kodu anlamıyorsun. Zaman için tek bir istek var. Yerel zaman çağrısını kastettiğinizi varsayıyorum - sadece gettimeofday'ın çıktısını yeniden biçimlendiriyor.
Chris

13

time.hstrftimeaşağıdaki gibi bir kullanımın metinsel temsilini verebilecek bir işlevi tanımlar time_t:

#include <stdio.h>
#include <time.h>
int main (void) {
    char buff[100];
    time_t now = time (0);
    strftime (buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime (&now));
    printf ("%s\n", buff);
    return 0;
}

ancak bu size bir saniyenin altında bir çözünürlük vermez, çünkü bu bir time_t. Çıktıları:

2010-09-09 10:08:34.000

Spesifikasyonlarla gerçekten kısıtlandıysanız ve gün ile saat arasında boşluk olmasını istemiyorsanız, biçim dizesinden kaldırmanız yeterlidir.


Ekranı milisaniyeye kadar doldurmak için uygun numara için +1. Bir zamanlar bunu yapmamı isteyen bir müşterim vardı, ancak sıfır olmayan rakamlarla bu yüzden orada bir önem varmış gibi görünüyordu. Onu bunun dışında tuttum ama sıfırlar koymayı kabul ettim.
RBerteig

4
Bir arkadaşım (tabii ki ben değil) bir zamanlar benzer bir numara kullandı - son saniyeyi ve "milisaniyeyi" içeren statiği sakladılar. İkincisinin son seferden değişmediği durumlarda, 1 ile 200 ile milisaniye arasında rastgele bir değer eklediler (tabii ki 999'u geçmediğinden emin olarak - rand () için gerçek maksimum her zaman min. 200'e ve 999'a mesafenin yarısı). İkincinin değiştiği yerde, eklemeden önce milisaniyeyi 0 olarak ayarlarlar. Görünüşte rastgele ama doğru şekilde dizilmiş milisaniyeler ve müşteri hiçbiri akıllıca değildi :-)
paxdiablo

6

Aşağıdaki kod, mikrosaniye hassasiyetinde yazdırılır. Tek yapmamız gereken kullanmakgettimeofday ve strftimeüzerinde tv_secve ekleme tv_usecinşa dize.

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int main(void) {
    struct timeval tmnow;
    struct tm *tm;
    char buf[30], usec_buf[6];
    gettimeofday(&tmnow, NULL);
    tm = localtime(&tmnow.tv_sec);
    strftime(buf,30,"%Y:%m:%dT%H:%M:%S", tm);
    strcat(buf,".");
    sprintf(usec_buf,"%dZ",(int)tmnow.tv_usec);
    strcat(buf,usec_buf);
    printf("%s",buf);
    return 0;
}

2

Kullanabilirsiniz strftime, ancak struct tmsaniyeler boyunca çözünürlüğe sahip değilsiniz. Amaçlarınız için bunun kesinlikle gerekli olup olmadığından emin değilim.

struct tm tm;
/* Set tm to the correct time */
char s[20]; /* strlen("2009-08-10 18:17:54") + 1 */
strftime(s, 20, "%F %H:%M:%S", &tm);

2

hile:

    int time_len = 0, n;
    struct tm *tm_info;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    tm_info = localtime(&tv.tv_sec);
    time_len+=strftime(log_buff, sizeof log_buff, "%y%m%d %H:%M:%S", tm_info);
    time_len+=snprintf(log_buff+time_len,sizeof log_buff-time_len,".%03ld ",tv.tv_usec/1000);

1
Lütfen bunun neden işe yaradığını açıklayın. ve tam olarak ne olduğunu.
Raj Kamal

Hepsi yukarıdaki örneklerle aynı, ancak yalnızca daha etkili. `time_len + = snprintf (log_buff + time_len, sizeof log_buff-time_len," log var =% s ", logvar); int ret = yazma (log_fd, log_buff, zaman_len); `
Андрей Мельников

Gettimeofday'i nereden içe aktarırım?
AndreyP

1

Bu sayfadaki çözümlerin hiçbiri benim için işe yaramadı, onları karıştırdım ve Windows ve Visual Studio 2019 ile çalışmasını sağladım, İşte Nasıl:

#include <Windows.h>
#include <time.h> 
#include <chrono>

static int gettimeofday(struct timeval* tp, struct timezone* tzp) {
    namespace sc = std::chrono;
    sc::system_clock::duration d = sc::system_clock::now().time_since_epoch();
    sc::seconds s = sc::duration_cast<sc::seconds>(d);
    tp->tv_sec = s.count();
    tp->tv_usec = sc::duration_cast<sc::microseconds>(d - s).count();
    return 0;
}

static char* getFormattedTime() {
    static char buffer[26];

    // For Miliseconds
    int millisec;
    struct tm* tm_info;
    struct timeval tv;

    // For Time
    time_t rawtime;
    struct tm* timeinfo;

    gettimeofday(&tv, NULL);

    millisec = lrint(tv.tv_usec / 1000.0);
    if (millisec >= 1000) 
    {
        millisec -= 1000;
        tv.tv_sec++;
    }

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", timeinfo);
    sprintf_s(buffer, 26, "%s.%03d", buffer, millisec);

    return buffer;
}

Sonuç:

2020: 08: 02 06: 41: 59.107

2020: 08: 02 06: 41: 59.196

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.