2017-03-02 4 views
2

Ich versuche die ISO8601 Wochennummer mit C zu bekommen. MinGW ist auf meinem PC installiert. GCC-Version ist 5.3.0. Sie können meinen Code unten sehen. strftime funktioniert nicht für Spezifizierer "% V". Aber es funktioniert gut mit dem Spezifizierer "% W". Aber das will ich nicht. Ich brauche die Wochennummer im ISO 8601 Format.ISO 8601 Wochennummer in C

Ich habe meinen Code mit 2 verschiedenen Online-C-Compiler versucht und beide funktionierten gut. Ich bezweifle, dass der Compiler auf meinem PC nicht gut konfiguriert ist. Kann mir jemand sagen, was mache ich falsch? Jede Hilfe wäre willkommen.

Hier ist mein Code:

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

int main() 
{ 
    time_t timep; 
    struct tm * time_inf; 
    char buff [80]; 

    time (&timep); 
    time_inf = localtime (&timep); 

    time_inf->tm_year = 2008 - 1900; 
    time_inf->tm_mon = 11; 
    time_inf->tm_mday = 31; 

    mktime (time_inf); 

    strftime (buff, sizeof(buff), "%V", time_inf) ; 
    puts (buff); //prints nothing 

    printf("%d", strlen(buff)); //prints 0 

    return 0; 
} 
+0

Ihr Code funktioniert gut für mich - [click] (http://coliru.stacked-crooked.com/a/af8765f61e764251). Beachten Sie, dass der Formatbezeichner% V länderabhängig ist. Versuchen Sie, dies zu untersuchen, da Code gut aussieht - * außer es ist C nicht C++ *. – mpiatek

Antwort

2

die ISO8601 Wochennummer mit C

Wenn "%V" mit strftime() bekommen nicht verfügbar oder problematisch ist, kann Code Richt die ISO 8601 Woche berechnen.


ISO 8601 Wochen des Jahres beginnt montags.

Wenn man die ISO 8601 week des Jahres finden möchte, wird oft auch das entsprechende "Jahr" benötigt.

Die erste Woche des Jahres, Woche # 1, ist die erste Woche, beginnend am Montag, die mindestens 4 Tage im Januar hat - oder wie der folgende Code verwendet, ist der erste Donnerstag des Jahres in Woche 1.

Es ist möglich, dass Dec 31 in Woche 1 des nächsten Jahres ist.
Es ist möglich, dass Jan 1 in der Woche 52/53 des Vorjahres ist.

#include <time.h> 

// return 1 on failure, 0 on success 
int tm_YearWeek(const struct tm *tmptr, int *year, int *week) { 
    // work with local copy 
    struct tm tm = *tmptr; 
    // fully populate the yday and wday fields. 
    if (mktime(&tm) == -1) { 
    return 1; 
    } 

    // Find day-of-the-week: 0 to 6. 
    // Week starts on Monday per ISO 8601 
    // 0 <= DayOfTheWeek <= 6, Monday, Tuesday ... Sunday 
    int DayOfTheWeek = (tm.tm_wday + (7 - 1)) % 7; 

    // Offset the month day to the Monday of the week. 
    tm.tm_mday -= DayOfTheWeek; 
    // Offset the month day to the mid-week (Thursday) of the week, 3 days later. 
    tm.tm_mday += 3; 
    // Re-evaluate tm_year and tm_yday (local time) 
    if (mktime(&tm) == -1) { 
    return 1; 
    } 

    *year = tm.tm_year + 1900; 
    // Convert yday to week of the year, stating with 1. 
    *week = tm.tm_yday/7 + 1; 
    return 0; 
} 

Beispiel

int main() { 
    struct tm tm = { 0 }; 
    tm.tm_year = 2008 - 1900; 
    tm.tm_mon = 12 - 1; 
    tm.tm_mday = 31; 
    tm.tm_isdst = -1; 
    int y = 0, w = 0; 
    int err = tm_YearWeek(&tm, &y, &w); 
    printf("Err:%d Year:%d Week:%d %02d%02d\n", err, y, w, y%100, w); 
    return 0; 
} 

Ausgang ist Woche 1 von 2009 31. Dezember 2008 oder . Dies wird gemäß der obigen Diskussion erwartet und könnte OPs unausgesprochene Bedenken bezüglich des OP-Codes erklären.

Err:0 Year:2009 Week:1 0901 
+1

Obwohl ich die ISO 8601 Woche mit etwas Code berechnet habe, ist Ihr Code hier besser und kürzer. Ich werde zu diesem wechseln. Danke vielmals. –

2

MinGW bieten keine eigene strftime, sondern Links in MSVCRT Definition, which doesn't provide %V.

Entweder implementieren Sie, was Sie selbst vermissen, oder verwenden Sie eine alternative Implementierung, z. B. , z.here's BSD's strftime.