2012-05-20 4 views
2

특정 연도의 주 번호가 주어지면 C/C++를 사용하여 쉬운 방법으로 주중 첫 번째 날짜와 마지막 날을 결정할 수 있습니까? 미리 감사드립니다.특정 연도에 지정된 주 번호 (1-53)의 첫 번째 날짜와 마지막 날짜 (일 및 월)를 얻는 방법은 무엇입니까?

+1

자신이 어떤 노력을했는지 표시하지 않으면 사람들이 o 귀하의 질문에 enmasse downvote! – DumbCoder

+0

좀 더 정확하게 입력해야 할 수도 있습니다. 주 번호 지정 표준에는 여러 유형이 있습니다. 당신은 당신이 원하는 것을 알아야합니다. 내가 C를 한 지 오래 됐기 때문에 날짜를 어떻게 다룰 지 기억이 안납니다. 다른 날짜 마스크 ([PHP에서와 같이] (http://php.net/manual/en/function.date.php))를 가져올 수있는 형식 구성에 무언가가 없음 – cartbeforehorse

+0

앞으로 또는 뒤로 이동 제 시간에? 그리고 어디? 내가 살고있는 로케일에서는 미국 모델과 비슷한 주 숫자를 사용했지만 ISO 표준 주 숫자로 변경되었습니다. –

답변

1

이것은 주 번호 지정에 대한 지역 규칙의 영향을 많이받습니다. 어떤 주일이 주일인지에 대한 최소한 두 가지 공통 규칙이 있습니다. 연초에 세 번째 주에 대해 세 가지 공통 규칙이 있습니다.

그런 종류의 코드를 끊임없이 고수하고 라이브러리를 사용하지 마십시오. ICU 라이브러리는 이것을 Calendar 클래스로 다룬다. 관련 소개 페이지 is here. 페이지 하단의 WEEK_OF_YEAR 필드에 메모를 확인하십시오.

+0

'주간 번호에 대한 지역 규칙의 영향이 큽니다. 아니요, [ISO 8601] (https://en.wikipedia.org/wiki/ISO_8601#Week_dates)은 주 번호 지정에 대해 아주 분명합니다. , 아아, 당신의 사용자가 그것을 사용하지 않는 한. – kebs

+0

전형적인 ISO 제품인 Hmya. 그것은 표준이 아니며, 모든 사람을 똑같이 불행하게 만드는 타협입니다. –

+0

나는 그것을 얻지 않는다. WP는 그것을'국제 표준 [...]'이라고 묘사한다. 그래서 ** ** 표준이 아니라면 무엇입니까? – kebs

2

이전 질문에 대한 새로운 대답입니다.

이 답변에는 표준화를 위해 제안되었으며 거절 된 코드가 포함되어 있습니다. 내가 언급 한 이유는 코드가 제안을 위해 네임 스페이스 std::chrono에 있다는 것입니다. 그러나이 제안이 받아 들여지지 않았다는 사실을 깨닫는 것이 중요합니다. 따라서 사용하는 경우 제안 된 부분을 자신의 네임 스페이스로 옮겨야합니다. 그들은 표준의 일부가 아니며 심지어 표준화를 고려하지도 않습니다!

여기에 user documentation for my date class이 있습니다.이 계산은 상당히 쉽습니다 (ISO 표준 주 번호 매김이라고 가정). 문서는 하나의 헤더 <date>과 제안서를 구현하는 하나의 소스 date.cpp을 가리 킵니다.

이 소스와 아래에 표시된 두 가지 매우 간단한 도우미 함수를 사용하여 다음과 같은 주간 번호와 연도가 걸린 프로그램이 있는데이 프로그램은 그 주 중 첫 번째 일 (월요일)과 마지막 일요일 (일요일)을 시민 그레고리오) 달력 :

#include "date" 
#include <utility> 
#include <iostream> 

std::chrono::date 
week_to_date(int weeknum, std::chrono::weekday wd, std::chrono::year y) 
{ 
    using namespace std::chrono; 
    return (mon <= jan/_4th/y) + days((weeknum - 1)*7 + (wd == 0 ? 6 : wd - 1)); 
} 

std::pair<std::chrono::date, std::chrono::date> 
get_dates(unsigned week_num, unsigned y) 
{ 
    using namespace std::chrono; 
    return std::make_pair(week_to_date(week_num, mon, year(y)), 
          week_to_date(week_num, sun, year(y))); 
} 

int main() 
{ 
    auto p = get_dates(9, 2013); 
    std::cout << p.first << '\n'; 
    std::cout << p.second << '\n'; 
} 

은 나를 위해이 출력합니다 :

,832 :

2013-02-25 
2013-03-03 

week_to_date에서 return 문은 약간의 설명을 사용할 수 있습니다 10

위의 표현식은 연도 y의 1 월 4 일 또는 그 이전의 월요일 인 날짜를 구성합니다. 주 일 (wd)이 일요일 인 경우

+ days((weeknum - 1)*7 

가 그리고 마지막으로, 나는 다른 내가 날이 번호가 wd-1일 추가 6 일 추가 : 나는 그 일에 weeknum하기 전에 일주일에 7 일을 추가 월요일 == 1, 화요일 == 2, 토요일 == 6 (일요일 == 0).

+ (wd == 0 ? 6 : wd - 1)) 

이 마지막 단계는 ISO 주 기반 달력 주 월요일에 시작하는 날짜 클래스의 구현은 일요일에 시작하는 주의 C/C++ 규칙을 따르는 반면, 고려 것입니다.

에는 실제적으로 week_to_date의 정의와 ISO 주 기준 연도가 포함되어 있습니다. 이는 제안서에 날짜 클래스를 사용하는 방법의 예와 마찬가지로 제안서의 일부가 아니지만 포함됩니다.

자유롭게 코드를 사용할 수 있지만, 먼저 네임 스페이스 std에서 코드를 제거하는 것이 좋습니다. 근원은 이것 같이 사소한 수정이 곤란하면 안된다 충분히 짧다.


업데이트

링크는이 대답에 부실 갔다 그래서 나는 그들 업데이트되었습니다. 그러나 링크를 업데이트하는 것 외에도 위에 링크 된 라이브러리의 재 설계에주의를 환기하고 싶습니다. 재 설계는 컴파일 타임에 모든 입력을 알고있는 컴파일 타임 날짜 계산을 포함하여 효율성에 새로운 초점을 맞 춥니 다.

"날짜 상수"는 이제 C++ 14가 지원되면서 실제입니다.

이 새롭게 디자인 된 라이브러리는 documented here이며 문서에서 링크 된 단일 헤더 구현입니다. 구문은 아니지만 정확한 위에서 제시된 것과 비슷하다 :

#include "date.h" 
#include <iostream> 

constexpr 
date::year_month_day 
week_to_date(int weeknum, date::weekday wd, date::year y) 
{ 
    using namespace date; 
    auto const dp = sys_days(jan/4/y); 
    auto const wdjan4 = weekday(dp); 
    return dp - (wdjan4 - mon) 
     + days((weeknum - 1)*7 + (wd == sun ? 6 : static_cast<unsigned>(wd) - 1)); 
} 

constexpr 
std::pair<date::year_month_day, date::year_month_day> 
get_dates(int week_num, date::year y) 
{ 
    using namespace date; 
    return std::make_pair(week_to_date(week_num, mon, y), 
          week_to_date(week_num, sun, y)); 
} 

int 
main() 
{ 
    using namespace date; 
    constexpr auto p = get_dates(9, 2013_y); 
    static_assert(p.first == feb/25/2013, ""); 
    static_assert(p.second == 2013_y/mar/3, ""); 
    std::cout << p.first << '\n'; 
    std::cout << p.second << '\n'; 
} 

두 가지 주요 차이 (14 C++로)을 계산이 constexpr을 할 수 있습니다. 그리고 operator<=은 더 이상 평일이 날짜와 같거나 그 이전 인 날짜를 찾을 수 없습니다. 대신이 기능은 "평일 뺄셈"에 의해 처리되며, 항상 양수로 나타납니다 (평일 1에서 평일 2까지 며칠이 소요됩니까?).

이 프로그램은 이전 버전과 같은 짓을 출력합니다

2013-02-25 
2013-03-03 

가장 큰 차이점은 이제 상수 std::cout에 출력되는되는 컴파일 시간이다. 그러나 동일한 코드 (마이너스 static_asserts)는 런타임 입력에 문제없이 작동합니다.

그리고 이길

새로운 호환 "iso_week.h" 라이브러리와, 상기 도입 된 라이브러리 결합에 진행은 상기 연산에 대한 구문은 크게 간소화된다 출력하는

#include "date.h" 
#include "iso_week.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace iso_week::literals; 
    auto y = 2013_y; 
    auto wn = 9_w; 
    std::cout << "The dates for " << y/wn << " are " 
       << date::year_month_day{y/wn/mon} << " through " 
       << date::year_month_day{y/wn/sun} << '\n'; 
} 

:

The dates for 2013-W09 are 2013-02-25 through 2013-03-03 
+0

업데이트 해 주셔서 감사합니다. –

관련 문제