详细介绍见 Calculating the ISO week number. Jan Stout. http://www.proesite.com/timex/wkcalc.htm
Simple week number的定义如下:
1. 第一周开始于该年的一月一号
2. 第n+1周开始于第n周后的7天
SWN( y, m, d ) = 1 + ( DP( y, m ) + d-1 ) / 7
where DP ("Days Passed") is given by:
-
DP( y, 1 ) = 0
DP( y, m+1 ) = DP( y, m ) + ML( y, m )
and ML ("Month Length") is defined as:
ML( y, 1 ) = 31
ML( y, 2 ) = 28 + LEAP( y )
ML( y, 3 ) = 31
ML( y, 4 ) = 30
ML( y, 5 ) = 31
ML( y, 6 ) = 30
ML( y, 7 ) = 31
ML( y, 8 ) = 31
ML( y, 9 ) = 30
ML( y, 10 ) = 31
ML( y, 11 ) = 30
ML( y, 12 ) = 31
and LEAP( y ) is defined as:
- LEAP( y ) = ( y % 4 == 0 ) && ( ( y % 100 != 0 ) || ( y % 400 == 0 ) )
ISO week number[ISO8601]的定义如下:
1. 每周从星期一开始
2.一年的第一周是该calendar年中第一个包含星期四的星期,也就是说至少包含4天的第一个周。比如说2004年1月1号是星期四,则2004的第一周开始于2003.12.29.
ISO_WN( y, m, d )
{
dow = DOW( y, m, d ); // Day of the week
dow0101 = DOW( y, 1, 1 );
if ( m == 1 && 3 < dow0101 < 7 - (d-1) )
{
// days before week 1 of the current year have the same week number as
// the last day of the last week of the previous year
dow = dow0101 - 1;
dow0101 = DOW( y-1, 1, 1 );
m = 12;
d = 31;
}
else if ( m == 12 && 30 - (d-1) < DOW( y+1, 1, 1 ) < 4 )
{
// days after the last week of the current year have the same week number as
// the first day of the next year, (i.e. 1)
return 1;
}
return ( DOW( y, 1, 1 ) < 4 ) + 4 * (m-1) + ( 2 * (m-1) + (d-1) + dow0101 - dow + 6 ) * 36 / 256;
}