2017-03-02 3 views
2

J'essaie d'obtenir le numéro de semaine ISO8601 avec C. MinGW est installé sur mon PC. La version de GCC est 5.3.0. Vous pouvez voir mon code ci-dessous. strftime ne fonctionne pas pour le spécificateur "% V". Mais cela fonctionne bien avec le spécificateur "% W". Mais ce n'est pas ce que je veux. J'ai besoin du numéro de semaine de l'année au format ISO 8601.Numéro de semaine ISO 8601 en C

J'ai essayé mon code avec 2 différents compilateurs en ligne C et ils ont tous deux bien fonctionné. Je doute que le compilateur sur mon PC ne soit pas bien configuré. Quelqu'un peut-il me dire ce que je fais mal? Toute aide serait appréciée.

Voici mon 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

Votre code fonctionne très bien pour moi - [cliquez] (http://coliru.stacked-crooked.com/a/af8765f61e764251). Notez que le spécificateur de format '% V' dépend des paramètres régionaux. Essayez de creuser parce que le code semble bien - * sauf que C n'est pas C++ *. – mpiatek

Répondre

2

pour obtenir le numéro de la semaine avec C ISO8601

Lorsque "%V" avec strftime() ne sont pas disponibles ou problématique, le code peut calculer la semaine DIRECTIVITE ISO 8601.


ISO 8601 semaines de l'année commence le lundi.

Quand on veut trouver le ISO 8601 week de l'année, souvent l'année correspondante est également nécessaire.

La première semaine de l'année, semaine 1, est la première semaine, commençant le lundi, qui a au moins 4 jours en janvier - ou comme le code ci-dessous utilise, le premier jeudi de l'année est en semaine 1.

Il est possible que le 31 décembre soit la semaine 1 de l'année suivante.
Il est possible que le 1er janvier soit dans la semaine 52/53 de l'année précédente.

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

Exemple

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

sortie est la semaine 1 de 2009 pour le 31 décembre 2008 ou . Cela est prévu par la discussion ci-dessus et peut expliquer la préoccupation non déclarée de OP par le code OP.

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

Bien que j'ai calculé la semaine ISO 8601 avec du code, votre code ici est meilleur et plus court. Je vais passer à celui-ci. Merci beaucoup. –

2

MinGW ne fournit pas ses propres strftime, mais des liens dans la définition de MSVCRT, which doesn't provide %V. Mettez en œuvre ce que vous avez manqué vous-même ou utilisez une implémentation alternative, par exemple.here's BSD's strftime.