كيفية تحويل التاريخ والوقت ليونيكس الزمني في ج؟

StackOverflow https://stackoverflow.com/questions/1002542

  •  05-07-2019
  •  | 
  •  

سؤال

والسيناريو هو: أحصل على التاريخ والوقت في شكل "YYYY-MM-DD HH: MM: SS" مع libexif. لتقليل تكلفة الادخار، وأريد تحويل التاريخ والوقت ليونيكس الزمني أو على حد سواء والتي تكلف فقط 64BIT أو 32BIT و. هل هناك أي طريقة واضحة مع ج؟

هل كانت مفيدة؟

المحلول

هل يمكن أن محاولة الجمع بين strptime و <لأ href = "HTTP: / /linux.die.net/man/3/ctime "يختلط =" noreferrer "> mktime

struct tm tm;
time_t epoch;
if ( strptime(timestamp, "%Y-%m-%d %H:%M:%S", &tm) != NULL )
  epoch = mktime(&tm);
else
  // badness

نصائح أخرى

وتحويل كل جزء من الوقت / التاريخ إلى عدد صحيح لملء struct tm، ثم تحويل هذه الأفكار إلى time_t باستخدام <لأ href = "http://linux.die.net/man/3/ctime" يختلط = " نوفولو noreferrer "> mktime .

وهنا هو الحل السلكية في ج / رمز زائف أنا فقط اخترق معا. حظا سعيدا!

char * runner = NULL;
char *string_orig = "YYYY-MM-DD HH:MM:SS";
time_t time = 0;
struct tm tmp;

use strstr(string_orig, "-") and atoi foreach

  tmp->tm_year .. 
  tmp->tm_mon  .. 
  tmp->tm_mday ..  
  tmp->tm_hour  .. 
  tmp->tm_min  .. 
  tmp->tm_sec .. 

with *runner as help

time = mktime(&tm)

وماذا عن sscanf؟

struct tm tmVar;
char *strVar = "YYYY-MM-DD HH:MM:SS";
time_t timeVar;
if(sscanf(strVar, "%d-%d-%d %d:%d:%d", &tm.tm_year, /* the other fields */)==6)
    timeVar = mktime(&tmVar);
else
    // bad format

إليك قصاصة جاهزة عندما strptime غير متوفر:

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

time_t string_to_seconds(const char *timestamp_str)
{
    struct tm tm;
    time_t seconds;
    int r;

    if (timestamp_str == NULL) {
        printf("null argument\n");
        return (time_t)-1;
    }
    r = sscanf(timestamp_str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
    if (r != 6) {
        printf("expected %d numbers scanned in %s\n", r, timestamp_str);
        return (time_t)-1;
    }

    tm.tm_year -= 1900;
    tm.tm_mon -= 1;
    tm.tm_isdst = 0;
    seconds = mktime(&tm);
    if (seconds == (time_t)-1) {
        printf("reading time from %s failed\n", timestamp_str);
    }

    return seconds;
}

وضبط نفسك سلسلة في sscanf إلى ما تحتاج إليه. تجاهل المنطقة الزمنية وتحويل دائما كما substract GMT / UTC على timezone (أو _timezone) من seconds (يتم تعريف timezone العالمية في time.h. DST يتم تجاهل بالفعل التصفير الحقل tm_isdst من tm.

ولينكس يدعم وظيفة getdate()، التي أعتقد أنها أكثر عملية من استدعاء strptime() مباشرة. وذلك لأن وظيفة getdate() يتحقق تلقائيا <م> كثير أشكال بالنسبة لك. وهو ما يعادل يدعو strptime() مع أشكال مختلفة حتى تعمل وظيفة أو تم اختبار جميع الأشكال.

// setenv() should be called only once
setenv("DATEMSK", "/usr/share/myprog/datemsk.fmt", 0);

// convert a date
struct tm * t1(getdate("2018-03-31 14:35:46"));
if(t1 == nullptr) ...handle error...
time_t date1(timegm(t1));

// convert another date
struct tm * t2(getdate("03/31/2018 14:35:46"));
if(t2 == nullptr) ...handle error...
time_t date2(timegm(t2));

ملحوظة: timegm() يشبه mktime() إلا أنه يتجاهل لغة ويستخدم UTC. في معظم الحالات أن هذه هي الطريقة الصحيحة لتحويل التواريخ.

وملف datemsk.fmt ستشمل على الأقل هذه صيغتين لدعم التواريخ المذكورة أعلاه:

%Y-%b-%d %H:%M:%S
%b/%d/%Y %H:%M:%S

وعدد من أشكال الدعم لا يقتصر، على الرغم من أنك قد لا تريد أن يكون لها عدد كبير جدا. انها سوف تكون بطيئة نوعا ما إذا كان لديك الكثير من الأشكال. يمكنك أيضا حيوي إدارة الأشكال الخاصة بك، وندعو strptime() في حلقة.

ولينكس كما يقدم وظيفة getdate_r() وهو خيط آمنة.

ورجل الصفحة: http://pubs.opengroup.org/onlinepubs/ 7908799 / xsh / getdate.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top