Hi I building this project but I need the (week number ) to display on screen
..(RTC DS1302 on 16x2 LCD display I2C), this is clock, day, month,
and want to add the WEEK NUMBER and need the code for
WEEK NUMBER please help any suggestion I look around cant find any info.
please help, thanks
Can't you calculate that from the date?
Also, week number seems like a not standard concept.
You will have to decide what week number even means.
Then use standard calendar algorithms to develop a day number into the year, plus an offset maybe (guessing) to get to the first Monday and divide by 7.
Algorithms for day of week and so forth are so old, maybe they were are old they never made it onto the internets.
But it would be worth a google.
Zeller’s congruence
maybe.
a7
What code are you using? In order for us to add to what you have, we need to know what you already have.
Please post your code inside code tags. Click on the </>
symbol to get them.
Do not think I've ever seen week number in any of the libraries, its likely you will need to calculate it yourself. Which week numbering system do you want to use, they differ on which day is the start of the week, and when week #1 begins in the year.
this is the code I try to use Thanks to http://www.bajdi.com
// http://www.bajdi.com
// Arduino digital clock
// Date and time shown on I2C LCD display
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
RTC_DS1307 RTC;
void setup () {
Wire.begin();
RTC.begin();
lcd.init(); // initialize the lcd
lcd.backlight();
}
void loop () {
DateTime now = RTC.now();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.setCursor(0, 1);
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
delay(1000);
}
Hi thanks for your help
not on the libraries but I seen an Arduino with week number on display
but they do not show code
thanks
It's well established in ISO8601: week1 contains the year's first Thursday.
It may be written down, but that doesn't mean every organisation uses it or that it is the week number @javaox wants.
I have worked in organisations which use at least 2 different week numbering systems at the same time. The two systems are defined differently and the current week number in one system was always ahead of the other, but not always by the same difference. Both systems included week 53 in some years, but not generally in the same years. It was common to hear something like
"What were sales in week 47?"
"Which week 47?"
The difficult part is determining when week #1 begins, after that calculating the week number within the year would be easy using the unix timestamp.
Which is exactly why the ISO and their standards exist.
By the way, OP, unless you have a compelling reason for using the 1302, like maybe you bought a container load, you will find life easier if you go for the newer I2C 1307 and even newer and better 3231.
This function might be useful:
int ymdToWeekNumber (int y, int m, int d) {
// reject out-of-range input
if ((y < 1965)||(y > 2099)) return 0;
if ((m < 1)||(m > 12)) return 0;
if ((d < 1)||(d > 31)) return 0;
// compute correction for year
// If Jan. 1 falls on: Mo Tu We Th Fr Sa Su
// then the correction is: 0 +1 +2 +3 -3 -2 -1
int corr = ((((y - 1965) * 5) / 4) % 7) - 3;
// compute day of the year (in range 1-366)
int doy = d;
if (m > 1) doy += 31;
if (m > 2) doy += (((y%4)==0) ? 29 : 28);
if (m > 3) doy += 31;
if (m > 4) doy += 30;
if (m > 5) doy += 31;
if (m > 6) doy += 30;
if (m > 7) doy += 31;
if (m > 8) doy += 31;
if (m > 9) doy += 30;
if (m > 10) doy += 31;
if (m > 11) doy += 30;
// compute corrected day number
int cdn = corr + doy;
// check for boundary conditions
// if our calculation would give us "week 53",
// we need to find out whether week 53 really exists,
// or whether it is week 1 of the following year
if (cdn > 364) {
// check for year beginning on Thurs.
if (corr==3) return 53;
// check for leap year beginning on Wed.
if (((y%4)==0) && (corr==2)) return 53;
// otherwise, there is no week 53
return 1;
}
// if our calculation would give us "week 0",
// then go to the previous year
// and find out whether we are in week 52 or week 53
if (cdn < 1) {
// first, compute correction for the previous year
corr = ((((y - 1966) * 5) / 4) % 7) - 3;
// then, compute day of year with respect to that same previous year
doy = d + (((y%4)==1)?366:365);
// finally, re-compute the corrected day number
cdn = corr + doy;
}
// compute number of weeks, rounding up to nearest whole week
return ((cdn + 6) / 7);
}
I know that that function is long and maybe ugly, but it's what I came up with.
Test here: P873cQ - Online C++ Compiler & Debugging Tool - Ideone.com
Nice. For what range of year numbers does this work?
My only observation is that you doing lotsa the same calculations that might be needed elsewhere… so I would have the week number thing using the functions or structure that already have figured out all the other data, or has been suggested use the epoch unix timestamp and cede trust to a widely used and presumably less likely to fail piece of software.
But it is fun to play with the problem. Probably something no two people new to the problem woukd code up in the same way.
a7
// reject out-of-range input
if ((y < 1965)||(y > 2099)) return 0;
although (after posting I realized) there is a bug for the first few days of 1965, so the answer to your question should really be 1966 to 2099.
Thanks I will tray this code
lcd.print(now.year(), DEC);
What does this show you for the year number? Is it 2022, or just 22?
I extended the range of my function. Now it handles dates from 1901 to 2099. I chose this range because, within this range, a leap year occurs exactly once every four years. (Outside this range, that simple leap year rule doesn't work. Google "Gregorian calendar" for more info.)
int ymdToWeekNumber (int y, int m, int d) {
// reject out-of-range input
if ((y < 1901)||(y > 2099)) return 0;
if ((m < 1)||(m > 12)) return 0;
if ((d < 1)||(d > 31)) return 0;
// compute correction for year
// If Jan. 1 falls on: Mo Tu We Th Fr Sa Su
// then the correction is: 0 +1 +2 +3 -3 -2 -1
int corr = ((((y - 1881) * 5) / 4) % 7) - 3;
// compute day of the year (in range 1-366)
int doy = d;
if (m > 1) doy += 31;
if (m > 2) doy += (((y%4)==0) ? 29 : 28);
if (m > 3) doy += 31;
if (m > 4) doy += 30;
if (m > 5) doy += 31;
if (m > 6) doy += 30;
if (m > 7) doy += 31;
if (m > 8) doy += 31;
if (m > 9) doy += 30;
if (m > 10) doy += 31;
if (m > 11) doy += 30;
// compute corrected day number
int cdn = corr + doy;
// check for boundary conditions
// if our calculation would give us "week 53",
// we need to find out whether week 53 really exists,
// or whether it is week 1 of the following year
if (cdn > 364) {
// check for year beginning on Thurs.
if (corr==3) return 53;
// check for leap year beginning on Wed.
if (((y%4)==0) && (corr==2)) return 53;
// otherwise, there is no week 53
return 1;
}
// if our calculation would give us "week 0",
// then go to the previous year
// and find out whether we are in week 52 or week 53
if (cdn < 1) {
// first, compute correction for the previous year
corr = ((((y - 1882) * 5) / 4) % 7) - 3;
// then, compute day of year with respect to that same previous year
doy = d + (((y%4)==1)?366:365);
// finally, re-compute the corrected day number
cdn = corr + doy;
}
// compute number of weeks, rounding up to nearest whole week
return ((cdn + 6) / 7);
}
Test here: dt1yNa - Online C++ Compiler & Debugging Tool - Ideone.com
Haha, I'll take your word for it. Nice work.
That 400 year thing is always a complication, yeah. Calendar code can be a mess.
I approve of using online compilers to develop and perfect algorithms but it would be wise to use standard names for the specific integer sizes so you don't get surprised moving from the 32 bit ints you might find one place to the 16 bit ints on a different system. No energy to look hard and be sure you wouldn't be caught up by that in this case.
Also the long if thing doing the month correction might be shorter and look better with an array of 12 correction factors and a hack for leap year, no problem because the algorithm is basically one long miserable hack already (as they all seem to be…), or two arrays of 12 correction factors, one for leap and the other for not leap &c.
But who cares? Those are subtleties and once working the whole thing can be ignored. One would hope.
I note that weeks are numbered from 01. I wondered since many times things are numbered from 0 in C/C++.
The matter gives me a heads ache, and any time I do this stuff it makes me appreciate the sheer brilliance of a 360 day system with 5 or 6 days of unaccounted hard partying inserted to maintain synchrony with the Earth's orbit around the Sun. Well back then I guess the Sun might still have been moving around the Earth.
Of course these days that just wouldn't do, time being money and all.
a7
I am trying to keep my numbers small enough to fit in a (signed) 16-bit int. According to my figuring, they do fit into a 16-bit int, but you are welcome to check, in case I made a mistake.
It would look better on the screen, maybe, but an array would use up the Arduino's precious RAM.
I wonder if a big switch
statement, with the months in backward order and no break
s between them, would be more elegant. I'm not about to try, though, at least not right now.
Here is a version which is maybe easier to read, and which has full Gregorian leap year handling:
int ymdToWeekNumber (int y, int m, int d) {
// reject out-of-range input
if ((y < 1583)||(y > 25000)) return 0;
if ((m < 1)||(m > 12)) return 0;
if ((d < 1)||(d > 31)) return 0;
// compute correction for year
// If Jan. 1 falls on: Mo Tu We Th Fr Sa Su
// then the correction is: 0 +1 +2 +3 -3 -2 -1
int corr = ((y + 2 + (y-1)/4 - (y-1)/100 + (y-1)/400) % 7) - 3;
// compute day of the year (in range 1-366)
int doy = d;
if (m > 1) doy += 31;
if (m > 2) doy += (((y%100) ? (y%4) : (y%400)) ? 28 : 29);
if (m > 3) doy += 31;
if (m > 4) doy += 30;
if (m > 5) doy += 31;
if (m > 6) doy += 30;
if (m > 7) doy += 31;
if (m > 8) doy += 31;
if (m > 9) doy += 30;
if (m > 10) doy += 31;
if (m > 11) doy += 30;
// compute corrected day number
int cdn = corr + doy;
// compute number of weeks, rounding up to nearest whole week
// this gives us our week number
int wknum = ((cdn + 6) / 7);
// check for boundary conditions:
// if our calculation would give us "week 0",
// then it is really the final week of the previous year
// and we need to find out whether that is week 52 or week 53
if (wknum < 1) {
// first, compute correction for the previous year
corr = ((y + 1 + (y-2)/4 - (y-2)/100 + (y-2)/400) % 7) - 3;
// then, compute day of year with respect to that same previous year
doy = d + ((((y-1)%100) ? ((y-1)%4) : ((y-1)%400)) ? 365 : 366);
// finally, re-compute the corrected day number and the week number
cdn = corr + doy;
wknum = ((cdn + 6) / 7);
return wknum;
}
// if our calculation would give us "week 53",
// we need to find out whether week 53 really exists,
// or whether it is week 1 of the following year
if (wknum > 52) {
// check for year beginning on Thurs.
if (corr==3) return 53;
// check for leap year beginning on Wed.
if (((y%4)==0) && (corr==2)) return 53;
// otherwise, there is no week 53
return 1;
}
return wknum;
}
Test page here: tY4iOy - Online C++ Compiler & Debugging Tool - Ideone.com