2017-03-02 8 views
2

私はISO8601の週番号をCで取得しようとしています。私のPCにMinGWがインストールされています。 GCCのバージョンは5.3.0です。下のコードを見ることができます。 strftimeは、指定子 "%V"では機能しません。しかし、指定子 "%W"でうまく動作します。しかし、それは私が望むものではありません。私はISO 8601形式で年の週番号が必要です。CのISO 8601週番号

私は2つの異なるオンラインCコンパイラで自分のコードを試してみましたが、どちらもうまくいきました。私のPC上のコンパイラがうまく構成されていないのではないかと思う。誰かが私に間違っていることを教えてもらえますか?どんな助けもありがとう。

#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

あなたのコードは私のためにうまく動作します - [click](http://coliru.stacked-crooked.com/a/af8765f61e764251)。 '%V'フォーマット指定子はロケール依存であることに注意してください。コードは上手く見えるので、これを掘り下げてみてください* C以外のC++ *。 – mpiatek

答えて

2

C

strftime()"%V"が利用可能であるか、または問題にならない場合、コードは8601週ISOを計算指向することができるとISO8601週番号を取得します。今年の


ISO 8601 週は月曜日に始まります。

年のISO 8601 weekを探したいときは、しばしば対応する「年」も必要です。

月の第1週は月曜日から始まり、1月は少なくとも4日です。または、以下のコードが使用されると、年の最初の木曜日が第1週になります。

12月31日が翌年の1週目にある可能性があります。
Jan 1が前年の52/53週にある可能性があります。

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

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

出力は2008年12月31日2009年の週1かです。これは上記の議論により予想され、OPのコードに関する主張されていないOPの説明を説明するかもしれない。

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

私はいくつかのコードでISO 8601の週を計算しましたが、あなたのコードはより良く短くなりました。私はこれに切り替えます。どうもありがとう。 –

2

MinGWのはMSVCRTの定義、which doesn't provide %Vで独自のstrftimeが、リンクを提供していません:

は、ここに私のコードです。

あなた自身が見逃しているものを実装するか、別の実装を使用してください。here's BSD's strftime

関連する問題