How do I calculate the week number given a date?

2019-01-03 06:03发布

If I have a date, how do I calculate the week number for that date within that year?

For example, in 2008, January 1st to January 6th are in week 1 and January 7th to the 13th are in week 2, so if my date was January 10th 2008, my week number would be 2.

An algorithm would be great to get me started and sample code would also help - I'm developing in C++ on Windows.

Related:

Getting week number off a date in MS SQL Server 2005?

14条回答
ゆ 、 Hurt°
2楼-- · 2019-01-03 06:45

I strongly recommend using the C Standard Library's time functions to calculate the week number. Specifically, the strftime function has specifiers to print the week number (among many other values) given a date in broken-down (struct tm) format. Here's a small sample program that illustrates this:

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

int
main(void)
{
  struct tm tm;
  char timebuf[64];

  // Zero out struct tm
  memset(&tm, 0, sizeof tm);

  // November 4, 2008 11:00 pm
  tm.tm_sec = 0;
  tm.tm_min = 0;
  tm.tm_hour = 23;
  tm.tm_mday = 4;
  tm.tm_mon = 10;
  tm.tm_year = 108;
  tm.tm_isdst = -1;

  // Call mktime to recompute tm.tm_wday and tm.tm_yday
  mktime(&tm);

  if (strftime(timebuf, sizeof timebuf, "%W", &tm) != 0) {
    printf("Week number is: %s\n", timebuf);
  }

  return 0;
}

The output from this program (compiled with GCC on Linux and Microsoft Visual Studio 2005 SP1 on Windows) is:

Week number is: 44

You can learn more about strftime here.

查看更多
霸刀☆藐视天下
3楼-- · 2019-01-03 06:45

My assumption was that the first week on the year may contain up to 7 day as illustrated in Olie's answer. The code does not handle the cultures where the week starts on another day than Sunday and that is a large part of the world.

tm t = ... //the date on which to find week of year

int wy = -1;

struct tm t1;
t1.tm_year = t.tm_year;
t1.tm_mday = t1.tm_mon = 1; //set to 1st of January
time_t tt = mktime(&t1); //compute tm

//remove days for 1st week
int yd = t.tm_yday - (7 - t1.tm_wday);
if(yd <= 0 ) //first week is now negative
  wy = 0;
else
  wy = (int)std::ceil( (double) ( yd/7) ); //second week will be 1 
查看更多
你好瞎i
4楼-- · 2019-01-03 06:53

To convert in both directions, see here: Wikipedia article on ISO week dates

查看更多
Animai°情兽
5楼-- · 2019-01-03 06:59
/**
 * @brief WeekNo
 * @param yr
 * @param mon
 * @param day
 * @param iso
 * @return
 *
 *  Given a date, return the week number
 *  Note. The first week of the year begins on the Monday
 *  following the previous Thursday
 *  Follows ISO 8601
 *
 *  Mutually equivalent definitions for week 01 are:
 *
 *  the week with the year's first Thursday in it (the ISO 8601 definition)
 *  the week with the Thursday in the period 1 – 7 January
 *  the week starting with the Monday in the period 29 December – 4 January
 *  the week starting with the Monday which is nearest in time to 1 January
 *  the week ending with the Sunday in the period 4 – 10 January
 *  the week with 4 January in it
 *  the first week with the majority (four or more) of its days in the starting year
 *    If 1 January is on a Monday, Tuesday, Wednesday or Thursday, it is in week 01.
 *    If 1 January is on a Friday, Saturday or Sunday, it is part of week 52 or 53 of the previous year.
 *    the week with the year's first working day in it (if Saturdays, Sundays, and 1 January are not working days).
 ***    strftime has a conversion of struct tm to weeknumber.  strptime fills in tm struct**
 *   Code uses strptime, strftime functions.
 */

int WeekNo( int yr,int mon, int day, int iso)
{
    struct tm tm;
    char format[32];
    //memset(tm,0,sizeof(tm));
    sprintf(format,"%d-%02d-%02d",yr,mon,day);
    strptime(format, "%Y-%m-%d", &tm);
    // structure tm is now filled in for strftime

   strftime(format, sizeof(format), iso? "%V":"%U", &tm);

    //puts(format);
    return atoi(format);
}

invoke as Weekno(2015,12,23,1); //For ISO week number. Weekno(2015,12,23,0) //For non ISO week number

查看更多
我想做一个坏孩纸
6楼-- · 2019-01-03 07:01

Boost provides gregorian::date::week_number() see http://www.boost.org/doc/libs/1_38_0/doc/html/boost/gregorian/date.html and http://www.boost.org/doc/libs/1_38_0/boost/date_time/gregorian/greg_date.hpp.

However I cannot see a way to get the year number which matches the week number (which may be different to the calendar year for that date).

查看更多
看我几分像从前
7楼-- · 2019-01-03 07:03

My definition which is non-ISO 8601 (good enough for my purposes and fast):

// week number of the year
// (Monday as the first day of the week) as a decimal number [00,53].
// All days in a new year preceding the first Monday are considered to be in week 0.
int GetWeek(const struct tm& ts)
{
    return (ts.tm_yday + 7 - (ts.tm_wday ? (ts.tm_wday - 1) : 6)) / 7;
}
查看更多
登录 后发表回答