Cách in thời gian ở định dạng: 2009‐08‐10 18: 17: 54.811


96

Phương pháp tốt nhất để in ra thời gian ở định dạng C là 2009‐08‐10 
18:17:54.811gì?

Câu trả lời:


108

Sử dụng hàm 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;
}

Đối với phần mili giây, hãy xem câu hỏi này. Làm cách nào để đo thời gian bằng mili giây bằng ANSI C?


Đó là một câu trả lời thậm chí còn tốt hơn bây giờ và các công cụ để tìm kiếm cách xử lý phần mili giây. Tôi nghĩ rằng bộ đệm của bạn bây giờ dài hơn một chút so với mức cần thiết.
Jack Kelly

14
Tốt hơn để thể dài hơn ngắn hơn :-)
paxdiablo

Câu trả lời tuyệt vời. Tôi có thể làm tất cả mọi thứ bằng PHP, nhưng biết rằng tất cả đã có trong C. THanks.
Vijay Kumar Kanta

1
Có lẽ dòng time(&timer)này nên như vậy timer = time(NULL);, ít nhất là đối với 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

5
Câu trả lời chắc chắn là sai trong ít nhất một trường hợp (Linux) vì "struct tm" được sử dụng bởi localtime () không chứa bất kỳ thông tin thời gian nào bên dưới giây. Thay vào đó, "struct timeval" được sử dụng bởi gettimeofday () có micro giây, chia cho 1000 sẽ thu được mili giây. Tất cả những ủng hộ đó thực sự sai và gây hiểu lầm! Trừ khi ai đó báo cáo theo kiến ​​trúc nào, bạn sẽ nhận được chi tiết thời gian bên dưới giây với "struct tm".
EnzoR

30

Các câu trả lời trên không trả lời đầy đủ câu hỏi (cụ thể là phần mili giây). Giải pháp của tôi cho điều này là sử dụng gettimeofday trước strftime. Lưu ý cẩn thận để tránh làm tròn số mili giây thành "1000". Điều này dựa trên câu trả lời của 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;
}

gettimeofdaykhông khả dụng trên các triển khai Windows
Mendes

Vui lòng thêm các tùy chọn '-lm' khi bạn xây dựng nó.
tòa nhà chọc trời

3
Tôi nghĩ rằng bộ đệm [24] là đủ, lý do là như dưới đây, YYYY: MM: DD HH: MM: SS.mmm + '\ 0', là 24.
skysign

@Mendes, tại sao lại nhắc đến Windows? Câu hỏi là về ngôn ngữ C đơn giản. Đây là một câu trả lời tốt hơn (mặc dù không phải là câu đúng), bất chấp tất cả những ủng hộ sai đó!
EnzoR

2
user3624334: Không, bạn không hiểu mã. Chỉ có một yêu cầu về thời gian. Tôi cho rằng ý bạn là cuộc gọi localtime - nó chỉ định dạng lại đầu ra từ gettimeofday.
Chris

12

time.hxác định một strftimehàm có thể cung cấp cho bạn một biểu diễn dạng văn bản của một hàm time_tnhư:

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

nhưng điều đó sẽ không cung cấp cho bạn độ phân giải phụ thứ hai vì nó không có sẵn từ a time_t. Nó xuất ra:

2010-09-09 10:08:34.000

Nếu bạn thực sự bị giới hạn bởi các thông số kỹ thuật và không muốn có khoảng cách giữa ngày và giờ, chỉ cần xóa nó khỏi chuỗi định dạng.


+1 cho thủ thuật cấp tốc để điền vào màn hình đến mili giây. Tôi đã từng có một khách hàng muốn tôi làm điều đó, nhưng với các chữ số khác 0 nên có vẻ như có ý nghĩa ở đó. Tôi đã nói với anh ấy về nó nhưng đồng ý đưa vào số không.
RBerteig

4
Một người bạn của tôi (tất nhiên không phải tôi) đã từng sử dụng một thủ thuật tương tự - họ giữ các ảnh tĩnh chứa giây cuối cùng và "mili giây". Trường hợp giây không thay đổi so với lần trước, họ chỉ thêm một giá trị ngẫu nhiên từ 1 đến 200 vào mili giây (tất nhiên là đảm bảo rằng nó không vượt quá 999 - giá trị tối đa thực tế cho hàm rand () luôn là giá trị tối thiểu của 200 và một nửa khoảng cách đến 999). Trường hợp thứ hai đã thay đổi, họ chỉ đặt mili giây thành 0 trước khi thêm. Đẹp dường như ngẫu nhiên nhưng trình tự đúng mili giây và khách hàng là không khôn ngoan hơn :-)
paxdiablo

5

Sau các bản in mã với độ chính xác micro giây. Tất cả những gì chúng ta phải làm là sử dụng gettimeofdaystrftimebật tv_secvà nối tv_usecvào chuỗi đã xây dựng.

#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

Bạn có thể sử dụng strftime, nhưng struct tmkhông có độ phân giải cho các phần của giây. Tôi không chắc liệu điều đó có hoàn toàn cần thiết cho mục đích của bạn hay không.

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

lừa:

    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
Vui lòng giải thích tại sao nó hoạt động. và chính xác thì điều gì đang xảy ra.
Raj Kamal

Tất cả tương tự như các ví dụ trên, nhưng hiệu quả hơn. `time_len + = snprintf (log_buff + time_len, sizeof log_buff-time_len," log var is =% s ", logvar); int ret = write (log_fd, log_buff, time_len); `
Андрей Мельников Ngày

Tôi nhập gettimeofday từ đâu?
AndreyP

1

Không có giải pháp nào trên trang này phù hợp với tôi, tôi đã trộn chúng và làm cho chúng hoạt động với Windows và Visual Studio 2019, Đây là cách thực hiện:

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

Kết quả :

2020: 08: 02 06: 41: 59.107

2020: 08: 02 06: 41: 59.196

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.