วิธีพิมพ์เวลาในรูปแบบ: 2009‐08‐10 18: 17: 54.811


คำตอบ:


109

ใช้strftime ()

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

สำหรับส่วนมิลลิวินาทีลองดูคำถามนี้ จะวัดเวลาเป็นมิลลิวินาทีโดยใช้ ANSI C ได้อย่างไร?


เป็นคำตอบที่ดียิ่งขึ้นในตอนนี้และอุปกรณ์ประกอบฉากสำหรับการค้นหาวิธีจัดการกับส่วนมิลลิวินาที ฉันคิดว่าตอนนี้บัฟเฟอร์ของคุณยาวกว่าที่จำเป็นเล็กน้อย
Jack Kelly

16
ดีกว่ายาวกว่าสั้นกว่า :-)
paxdiablo

คำตอบที่ยอดเยี่ยม ฉันสามารถทำสิ่งต่างๆใน PHP ได้ แต่รู้ว่ามันมีอยู่แล้วใน C.
Vijay Kumar Kanta

1
บางทีบรรทัดtime(&timer)ควรเป็นtimer = time(NULL);อย่างน้อยสำหรับ Linux 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
คำตอบนั้นผิดอย่างน้อยหนึ่งกรณี (Linux) เนื่องจาก "struct tm" ที่ใช้โดย localtime () จะไม่เก็บข้อมูลเวลาใด ๆ ไว้ต่ำกว่าวินาที แทนที่จะใช้ "struct timeval" โดย gettimeofday () จะมีไมโครวินาทีซึ่งหารด้วย 1,000 จะให้ผลเป็นมิลลิวินาที การโหวตทั้งหมดนั้นผิดและทำให้เข้าใจผิดจริงๆ! เว้นแต่จะมีใครรายงานภายใต้สถาปัตยกรรมใดคุณจะได้รับรายละเอียดเวลาด้านล่างด้วย "struct tm"
EnzoR

32

คำตอบข้างต้นไม่สามารถตอบคำถามได้อย่างสมบูรณ์ (โดยเฉพาะส่วนมิลลิวินาที) วิธีแก้ปัญหาของฉันคือใช้ gettimeofday ก่อน strftime สังเกตการดูแลเพื่อหลีกเลี่ยงการปัดเศษมิลลิวินาทีเป็น "1,000" นี่เป็นไปตามคำตอบของ Hamid Nazari

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

gettimeofdayไม่สามารถใช้ได้กับการใช้งาน Windows
Mendes

โปรดเพิ่มตัวเลือก '-lm' เมื่อคุณสร้างมัน
ตึกระฟ้า

3
ฉันคิดว่าบัฟเฟอร์ [24] ก็เพียงพอแล้วเหตุผลก็เหมือนข้างล่างปปปป: MM: DD HH: MM: SS.mmm + '\ 0' คือ 24
ตึกระฟ้า

@Mendes ทำไมถึงพูดถึง Windows? คำถามเกี่ยวกับภาษาซีธรรมดา นี่คือคำตอบที่ดีกว่า (แม้ว่าจะไม่ใช่คำตอบที่ถูกก็ตาม) แม้จะมีการโหวตผิดทั้งหมด
EnzoR

2
user3624334: ไม่คุณไม่เข้าใจรหัส ขอเวลาอย่างเดียวก็มี ฉันคิดว่าคุณหมายถึงการโทรในพื้นที่ - เพียงแค่ฟอร์แมตเอาต์พุตจาก gettimeofday
คริส

12

time.hกำหนดstrftimeฟังก์ชันที่สามารถแสดงข้อความ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;
}

แต่จะไม่ให้ความละเอียดย่อยวินาทีเนื่องจากไม่สามารถใช้งานได้จากไฟล์time_t. มันส่งออก:

2010-09-09 10:08:34.000

หากคุณถูก จำกัด โดยข้อกำหนดและไม่ต้องการให้มีช่องว่างระหว่างวันและชั่วโมงให้ลบออกจากสตริงรูปแบบ


+1 สำหรับเคล็ดลับที่เหมาะสมสำหรับการกรอกข้อมูลการแสดงผลเป็นมิลลิวินาที ฉันมีลูกค้ารายหนึ่งที่ต้องการให้ฉันทำแบบนั้น แต่ด้วยตัวเลขที่ไม่ใช่ศูนย์จึงดูเหมือนว่ามีความสำคัญอยู่ที่นั่น ฉันพูดเขาออกไป แต่ตกลงที่จะใส่เลขศูนย์
RBerteig

4
เพื่อนของฉัน (ไม่ใช่ฉันแน่นอน) เคยใช้กลอุบายคล้าย ๆ กันพวกเขาเก็บสถิติที่มีวินาทีสุดท้ายและ "มิลลิวินาที" ในกรณีที่วินาทีไม่ได้เปลี่ยนไปจากครั้งที่แล้วพวกเขาเพิ่งเพิ่มค่าสุ่มระหว่าง 1 ถึง 200 ถึงมิลลิวินาที (ตรวจสอบให้แน่ใจว่าไม่เกิน 999 แน่นอน - ค่าสูงสุดที่แท้จริงสำหรับแรนด์ () คือค่าต่ำสุด 200 และครึ่งหนึ่งของระยะทางเป็น 999) เมื่อวินาทีเปลี่ยนไปพวกเขาตั้งค่ามิลลิวินาทีเป็น 0 ก่อนการเพิ่ม ดูเหมือนสุ่มที่ดี แต่มีการเรียงลำดับมิลลิวินาทีอย่างถูกต้องและลูกค้าก็ไม่มีใครฉลาด :-)
paxdiablo

5

รหัสต่อไปนี้จะพิมพ์ด้วยความแม่นยำระดับไมโครวินาที สิ่งที่เราต้องทำคือใช้gettimeofdayและstrftimeเปิดtv_secและผนวกtv_usecเข้ากับสตริงที่สร้างขึ้น

#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

คุณสามารถใช้ได้strftimeแต่struct tmไม่มีความละเอียดเป็นเสี้ยววินาที ฉันไม่แน่ใจว่าจำเป็นสำหรับวัตถุประสงค์ของคุณหรือไม่

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

เคล็ดลับ:

    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
โปรดอธิบายอย่างละเอียดว่าเหตุใดจึงได้ผล และเกิดอะไรขึ้นกันแน่
Raj Kamal

ทั้งหมดเหมือนกับตัวอย่างข้างต้น แต่มีประสิทธิภาพมากขึ้นเท่านั้น `time_len + = snprintf (log_buff + time_len, sizeof log_buff-time_len," log var คือ =% s ", logvar); int ret = เขียน (log_fd, log_buff, time_len); `
АндрейМельников

ฉันจะนำเข้า gettimeofday จากที่ไหน?
AndreyP

1

ไม่มีวิธีแก้ปัญหาใดในหน้านี้ที่ใช้ได้ผลสำหรับฉันฉันผสมมันเข้าด้วยกันและทำให้พวกเขาทำงานกับ Windows และ Visual Studio 2019 โดยมีวิธีดังนี้

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

ผลลัพธ์ :

2020: 08: 02 06: 41: 59.107

2020: 08: 02 06: 41: 59.196

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.