- Community
- Example Programs
- Example Code
- Document

Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Calculating week number according to ISO8601 using LabWindows/CVI

by:
RobertoBozzolo

06-29-2006
04:44 PM

Last Edited by:
RobertoBozzolo
12-13-2019
09:39 AM
Document options

- Document History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Email to a Friend
- Printer Friendly Page
- Report to a Moderator

To download NI software, including the products shown below, visit ni.com/downloads.

- Other

Download All

Virus scan in progress. Please wait to download attachments.

**1. Overview:**

Calculate week of year for current date according to ISO 8601 specifications.

**2. Description:**

ISO 8601 indicates week 1 of the year as the one that includes the first Thursday. Since there is actually no CVI native function that calculates week number according to this specification I adapted for CVI the algorithm published by Rick McCarty. The function will return the wek number of the year.

**3. Requirements**

- LabWindows/CVI 2012 (or compatible)

**4. Steps to Implement or Execute Code**

- Download zip file and extract
- Incorperate method into your own native code
- Run your program

**5. Additional Information or References**

**This document has been updated to meet the current required format for the NI Code Exchange.**

Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community

________________________________________

If I have helped you, why not giving me a kudos?

Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.

Comments

Options

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Email to a Friend
- Report to a Moderator

12-13-2019
01:58 AM

i would like to share this function to calculate the ISO week number of a specified date.

this is a necessary function to calculate Current Time Zone Offset.

```
/// HIRET l'offset in secondi della time zone attuale, considerando anche il daylight saving time (DST).
static time_t CurrentTimeZoneOffset(void)
{
time_t rawtime = time(NULL);
struct tm ptm = *gmtime(&rawtime);
ptm.tm_isdst = -1; // Request that mktime() looksup dst in timezone database
return (time_t)difftime(rawtime, mktime(&ptm));
}
```

and this is the same function to calculate ISO week number but with parameters.

feel free to correct it if you find any problem, but please share the solution!

```
int CalculateISOweekNumWithParameter(unsigned short wYear, unsigned short wMonth, unsigned short wDay)
{
/*
Calcolates week number acording to ISO 8601
Procedure by Rick McCarty, 1999
Adapted to CVI by R.Bozzolo, 2006
Requires #include <windows.h>
Input: None
Output: Number of week in the year for local current date
Algorithm for Converting Gregorian Dates to ISO 8601 Week Date
(Y2K Compliant)
Rick McCarty, 1999
From: Gregorian Year-Month-Day
To: ISO YearNumber-WeekNumber-Weekday
ISO 8601 specifies that Week 01 of the year is the week containing
the first Thursday; Monday is Weekday 1, Sunday is Weekday 7;
WeekNumber requires two digits (W01, W02, etc.; "W" is optional)
Algorithm Conventions:
"/" = integer division, discard remainder (5/2 = 2)
"%" = modulus, keep only remainder (5%2 = 1)
"&" = concatenation ("W" & 12 = "W12")
"!=" = unequal (7 != 8 is true)
"+=" = add right value to left variable,
if F = 3, then (F += 4) yields F = 7
"-=" = subtract right value from left variable
1. Convert input to Y M D
Y = Year (full specification; input 98 = year 0098)
(Y must be larger than -1)
M = Month (1 through 12)
D = Day (1 through 31)
2. Find if Y is LeapYear
if (Y % 4 = 0 and Y % 100 != 0) or Y % 400 = 0
then
Y is LeapYear
else
Y is not LeapYear
3. Find if Y-1 is LeapYear
4. Find the DayOfYearNumber for Y M D
Mnth[1] = 0 Mnth[4] = 90 Mnth[7] = 181 Mnth[10] = 273
Mnth[2] = 31 Mnth[5] = 120 Mnth[8] = 212 Mnth[11] = 304
Mnth[3] = 59 Mnth[6] = 151 Mnth[9] = 243 Mnth[12] = 334
DayOfYearNumber = D + Mnth[M]
if Y is LeapYear and M > 2
then
DayOfYearNumber += 1
5. Find the Jan1Weekday for Y (Monday=1, Sunday=7)
YY = (Y-1) % 100
C = (Y-1) - YY
G = YY + YY/4
Jan1Weekday = 1 + (((((C / 100) % 4) x 5) + G) % 7)
6. Find the Weekday for Y M D
H = DayOfYearNumber + (Jan1Weekday - 1)
Weekday = 1 + ((H -1) % 7)
7. Find if Y M D falls in YearNumber Y-1, WeekNumber 52 or 53
if DayOfYearNumber <= (8-Jan1Weekday) and Jan1Weekday > 4
then
YearNumber = Y - 1
if Jan1Weekday = 5 or (Jan1Weekday = 6 and Y-1 is LeapYear)
then
WeekNumber = 53
else
WeekNumber = 52
else
YearNumber = Y
8. Find if Y M D falls in YearNumber Y+1, WeekNumber 1
if YearNumber = Y
then
if Y is LeapYear
then
I = 366
else
I = 365
if (I - DayOfYearNumber) < (4 - Weekday)
then
YearNumber = Y + 1
WeekNumber = 1
9. Find if Y M D falls in YearNumber Y, WeekNumber 1 through 53
if YearNumber = Y
then
J = DayOfYearNumber + (7 - Weekday) + (Jan1Weekday -1)
WeekNumber = J / 7
if Jan1Weekday > 4
WeekNumber -= 1
10. Output ISO Week Date:
if WeekNumber < 10
then
WeekNumber = "0" & WeekNumber (WeekNumber requires 2 digits)
Print: YearNumber & "-" & WeekNumber & "-" & Weekday (Optional: "-W" & WeekNumber)
*/
int YY = {0};
int C = {0};
int G = {0};
int I = {0};
int J = {0};
int DayOfYearNumber = {0};
int Jan1Weekday = {0};
int Weekday = {0};
int YearNumber = {0};
int LeapYear = {0};
int precLeapYear = {0};
int WeekNumber = {0};
int Mnth[] = { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
SYSTEMTIME dh = {0};
double DateTime = {0};
time_t rawtime = {0};
struct tm ptm = {0};
//1. Convert input to Y M D
//2. Find if Y is LeapYear
MakeDateTime (0, 0, 0, wMonth, wDay, wYear, &DateTime);
rawtime = (time_t)DateTime - CurrentTimeZoneOffset();
ptm = *localtime(&rawtime);
dh.wYear = wYear;
dh.wMonth = wMonth;
dh.wDayOfWeek = ptm.tm_wday;
dh.wDay = wDay;
if ((dh.wYear % 4 == 0 && dh.wYear % 100 != 0) || dh.wYear % 400 == 0)
{
LeapYear = 1;
}
//3. Find if Y-1 is LeapYear
if (((dh.wYear - 1) % 4 == 0 && (dh.wYear - 1) % 100 != 0) || (dh.wYear % 400 - 1) == 0)
{
precLeapYear = 1;
}
//4. Find the DayOfYearNumber for Y M D
DayOfYearNumber = dh.wDay + Mnth[dh.wMonth];
if (LeapYear && dh.wMonth > 2)
{
DayOfYearNumber++;
}
//5. Find the Jan1Weekday for Y (Monday=1, Sunday=7)
YY = (dh.wYear - 1) % 100;
C = (dh.wYear - 1) - YY;
G = YY + YY / 4;
Jan1Weekday = 1 + (((((C / 100) % 4) * 5) + G) % 7);
//6. Find the Weekday for Y M D
Weekday = dh.wDayOfWeek;
if (!Weekday)
{
Weekday = 7; // Gestisce correttamente la domenica (0 in SYSTEMTIME)
}
//7. Find if Y M D falls in YearNumber Y-1, WeekNumber 52 or 53
if (DayOfYearNumber <= (8 - Jan1Weekday) && Jan1Weekday > 4)
{
YearNumber = dh.wYear - 1;
if (Jan1Weekday == 5 || (Jan1Weekday == 6 && precLeapYear))
{
WeekNumber = 53;
}
else
{
WeekNumber = 52;
}
}
else
{
YearNumber = dh.wYear;
}
//8. Find if Y M D falls in YearNumber Y+1, WeekNumber 1
if (YearNumber == dh.wYear)
{
if (LeapYear)
{
I = 366;
}
else
{
I = 365;
}
if ((I - DayOfYearNumber) < (4 - Weekday))
{
YearNumber = dh.wYear + 1;
WeekNumber = 1;
}
}
//9. Find if Y M D falls in YearNumber Y, WeekNumber 1 through 53
if (YearNumber == dh.wYear)
{
J = DayOfYearNumber + (7 - Weekday) + (Jan1Weekday - 1);
WeekNumber = J / 7;
if (Jan1Weekday > 4)
{
WeekNumber -= 1;
}
}
return WeekNumber;
}
```

Davide Vittorio G. - TLGB S.R.L.

Italian SW Developer

Italian SW Developer