Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to return day of week #31

Open
Nikospax opened this issue Jul 30, 2017 · 5 comments
Open

Add function to return day of week #31

Nikospax opened this issue Jul 30, 2017 · 5 comments
Labels
topic: code Related to content of the project itself type: enhancement Proposed improvement

Comments

@Nikospax
Copy link

Is there a option to find the day of the week?

@GabrielNotman
Copy link
Contributor

It doesn't currently support querying the day of the week.
However, similar to how the epoch time is calculated, you could use mktime().
http://www.cplusplus.com/reference/ctime/mktime/

@drewfish
Copy link

drewfish commented Dec 2, 2020

There's actually a whole wikipedia article on just this :)
https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week

Here's code which I've used:

// returns 0=Sunday, etc
uint8_t getDayOfWeek() {
    uint16_t y = 2000 + rtc.getYear();
    uint16_t m = rtc.getMonth();
    uint16_t d = rtc.getDay();
    // http://stackoverflow.com/a/21235587
    return (d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;
}

@Nikospax
Copy link
Author

Nikospax commented Dec 2, 2020

i have use this code. Works but yours is too compact!!

hours = rtc.getHours() + GMT;
if(hours>=24)hours = hours - 24;
minutes = rtc.getMinutes();
secs = rtc.getSeconds();
year = rtc.getYear();
month = rtc.getMonth();
day = rtc.getDay();

// Calc the day of the week STARTS HERE
// Leap Year Calculation STARTS HERE
    if((fmod(year,4) == 0 && fmod(year,100) != 0) || (fmod(year,400) == 0))
    { leap = 1; }
    else 
    { leap = 0; }
// Leap Year Calculation ENDS HERE
 
 
// Calculating century
    c = year/100;

    // Calculating two digit year
    yy = fmod(year, 100);

    // Century value based on Table
    if(c == 19) { cTable = 1; }
    if(c == 20) { cTable = 0; }
    if(c == 21) { cTable = 5; }
    if(c == 22) { cTable = 3; }

    // Jan and Feb calculations affected by leap years
    if(month == 1)
    { if(leap == 1) { mTable = 6; }
      else          { mTable = 0; }}
    if(month == 2)
    { if(leap == 1) { mTable = 2; }
      else          { mTable = 3; }}
    // Other months not affected and have set values
    if(month == 10) { mTable = 0; }
    if(month == 8) { mTable = 2; }
    if(month == 3 || month == 11) { mTable = 3; }
    if(month == 4 || month == 7) { mTable = 6; }
    if(month == 5) { mTable = 1; }
    if(month == 6) { mTable = 4; }
    if(month == 9 || month== 12) { mTable = 5; }

// Enter the data into the formula
    SummedDate = day + mTable + yy + (yy/4) + cTable;
    
    // Find remainder
    DoW = fmod(SummedDate,7);  

    // Output result
    // Remainder determines day of the week

// Calc the day of the week ENDS HERE

@per1234 per1234 added type: enhancement Proposed improvement topic: code Related to content of the project itself labels Oct 6, 2022
@rtek1000
Copy link

Hi, I found this code:

https://www.hackster.io/erikuchama/day-of-the-week-calculator-cde704

I'm having problems with the DS3232RTC library (which makes use of the Time library). So I'm testing the uRTCLib library, but it seems like it's very basic and doesn't have automatic calculation of the day of the week.

I haven't tested the code for all dates in the functional range, but for the current date it is correct.

As the DS3232RTC library operates with Sunday at 1 and Saturday at 7, you need to get this right. In this code, Saturday is 0, and Sunday is 1.

// source: https://www.hackster.io/erikuchama/day-of-the-week-calculator-cde704
byte get_weekday(byte d, byte m, uint16_t yyyy) {
  int yy;          // Last 2 digits of the year (ie 2016 would be 16)
  int c;           // Century (ie 2016 would be 20)
  int mTable;      // Month value based on calculation table
  int SummedDate;  // Add values combined in prep for Mod7 calc
  int DoW;         // Day of the week value (0-6)
  int leap;        // Leap Year or not
  int cTable;      // Century value based on calculation table

  // Leap Year Calculation
  if ((fmod(yyyy, 4) == 0 && fmod(yyyy, 100) != 0) || (fmod(yyyy, 400) == 0)) {
    leap = 1;
  } else {
    leap = 0;
  }

  // Limit results to year 1900-2299 (to save memory)
  while (yyyy > 2299) { yyyy = yyyy - 400; }
  while (yyyy < 1900) { yyyy = yyyy + 400; }

  // Calculating century
  c = yyyy / 100;

  // Calculating two digit year
  yy = fmod(yyyy, 100);

  // Century value based on Table
  if (c == 19) { cTable = 1; }
  if (c == 20) { cTable = 0; }
  if (c == 21) { cTable = 5; }
  if (c == 22) { cTable = 3; }

  // Jan and Feb calculations affected by leap years
  if (m == 1) {
    if (leap == 1) {
      mTable = 6;
    } else {
      mTable = 0;
    }
  }
  if (m == 2) {
    if (leap == 1) {
      mTable = 2;
    } else {
      mTable = 3;
    }
  }
  // Other months not affected and have set values
  if (m == 10) { mTable = 0; }
  if (m == 8) { mTable = 2; }
  if (m == 3 || m == 11) { mTable = 3; }
  if (m == 4 || m == 7) { mTable = 6; }
  if (m == 5) { mTable = 1; }
  if (m == 6) { mTable = 4; }
  if (m == 9 || m == 12) { mTable = 5; }

  // Enter the data into the formula
  SummedDate = d + mTable + yy + (yy / 4) + cTable;

  // Find remainder
  DoW = fmod(SummedDate, 7);  // 0-6

  // // Remainder determines day of the week
  // if(DoW == 0) { Serial.println("Saturday"); }
  // if(DoW == 1) { Serial.println("Sunday"); }
  // if(DoW == 2) { Serial.println("Monday"); }
  // if(DoW == 3) { Serial.println("Tuesday"); }
  // if(DoW == 4) { Serial.println("Wednesday"); }
  // if(DoW == 5) { Serial.println("Thursday"); }
  // if(DoW == 6) { Serial.println("Friday"); }

  if (DoW == 0) {  // Saturday?
    DoW = 7;
  }

  return DoW;  // 1-7
}

@rtek1000
Copy link

There's actually a whole wikipedia article on just this :) https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week

Here's code which I've used:

// returns 0=Sunday, etc
uint8_t getDayOfWeek() {
    uint16_t y = 2000 + rtc.getYear();
    uint16_t m = rtc.getMonth();
    uint16_t d = rtc.getDay();
    // http://stackoverflow.com/a/21235587
    return (d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;
}

This code appears to be wrong.

I made a sketch to compare 3 codes, and it gave an error:

11:58:07.789 -> Year: 1992
11:58:07.982 -> Year: 1993
11:58:08.206 -> Year: 1994
11:58:08.399 -> Year: 1995
11:58:08.592 -> Year: 1996
11:58:08.784 -> Year: 1997
11:58:09.009 -> Year: 1998
11:58:09.202 -> Year: 1999
11:58:09.427 -> Year: 2000
11:58:09.684 -> Year: 2001
11:58:09.910 -> Year: 2002
11:58:10.135 -> Year: 2003
11:58:10.393 -> Year: 2004
11:58:10.618 -> Year: 2005
11:58:10.875 -> Year: 2006
11:58:11.101 -> Year: 2007
11:58:11.358 -> Year: 2008
11:58:11.615 -> Year: 2009
11:58:11.873 -> Year: 2010
11:58:12.130 -> Year: 2011
11:58:12.388 -> Year: 2012
11:58:12.677 -> Year: 2013
11:58:12.932 -> Year: 2014
11:58:13.222 -> Year: 2015
11:58:13.480 -> Year: 2016
11:58:13.770 -> Year: 2017
11:58:14.059 -> Year: 2018
11:58:14.348 -> Year: 2019
11:58:14.637 -> Year: 2020
11:58:14.669 -> 27-01-2021: - Fail - wd0 (time lib):4 (Wednesday) wd1:7 (Saturday) wd2:4 (Wednesday)

https://www.calculator.net/day-of-the-week-calculator.html ==> January 27, 2021 is a Wednesday

// Code comparison, by Rtek1000
#include "Time.h"

char daysOfWeek[7][10] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  Serial.println("\r\nStart");

  char line1[30] = { 0 };

  for (uint16_t y = 1970; y < 2100; y++) {
    for (byte m = 1; m < 12; m++) {
      for (byte d = 1; d < 28; d++) {
        byte wd0 = get_weekday_time_lib(d, m, y);
        byte wd1 = getDayOfWeek(d, m, y);
        byte wd2 = get_weekday(d, m, y);

        if ((wd0 != wd1) || (wd0 != wd2) || (wd1 != wd2)) {
          sprintf(line1, "%02d-%02d-%04u: ",
                  d, m, y);
          Serial.print(line1);

          Serial.print(" - Fail - wd0 (time lib):");
          Serial.print(wd0, DEC);
          Serial.print(" (");
          Serial.print(daysOfWeek[wd0 - 1]);
          Serial.print(") wd1:");
          Serial.print(wd1, DEC);
          Serial.print(" (");
          Serial.print(daysOfWeek[wd1 - 1]);
          Serial.print(") wd2:");
          Serial.print(wd2, DEC);
          Serial.print(" (");
          Serial.print(daysOfWeek[wd2 - 1]);
          Serial.println(")");

          while (1)
            ;
        }
      }
    }

    Serial.print("Year: ");
    Serial.println(y);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}

time_t t;
tmElements_t tm;

uint8_t get_weekday_time_lib(byte d, byte m, uint16_t yyyy) {
  tm.Year = CalendarYrToTm(yyyy);
  tm.Month = m;
  tm.Day = d;
  tm.Hour = 12;
  tm.Minute = 0;
  tm.Second = 0;

  t = makeTime(tm);

  return weekday(t);
}

// source: // http://stackoverflow.com/a/21235587
// returns 0=Sunday, etc
uint8_t getDayOfWeek(byte d, byte m, uint16_t yyyy) {
  return ((d += m < 3 ? yyyy-- : yyyy - 2, 23 * m / 9 + d + 4 + yyyy / 4 - yyyy / 100 + yyyy / 400) % 7) + 1;
}

// source: https://www.hackster.io/erikuchama/day-of-the-week-calculator-cde704
byte get_weekday(byte d, byte m, uint16_t yyyy) {
  int yy = 0;          // Last 2 digits of the year (ie 2016 would be 16)
  int c = 0;           // Century (ie 2016 would be 20)
  int mTable = 0;      // Month value based on calculation table
  int SummedDate = 0;  // Add values combined in prep for Mod7 calc
  int DoW = 0;         // Day of the week value (0-6)
  int leap = 0;        // Leap Year or not
  int cTable = 0;      // Century value based on calculation table

  // Leap Year Calculation
  if ((fmod(yyyy, 4) == 0 && fmod(yyyy, 100) != 0) || (fmod(yyyy, 400) == 0)) {
    leap = 1;
  } else {
    leap = 0;
  }

  // Limit results to year 1900-2299 (to save memory)
  while (yyyy > 2299) { yyyy = yyyy - 400; }
  while (yyyy < 1900) { yyyy = yyyy + 400; }

  // Calculating century
  c = yyyy / 100;

  // Calculating two digit year
  yy = fmod(yyyy, 100);

  // Century value based on Table
  if (c == 19) { cTable = 1; }
  if (c == 20) { cTable = 0; }
  if (c == 21) { cTable = 5; }
  if (c == 22) { cTable = 3; }

  // Jan and Feb calculations affected by leap years
  if (m == 1) {
    if (leap == 1) {
      mTable = 6;
    } else {
      mTable = 0;
    }
  }
  if (m == 2) {
    if (leap == 1) {
      mTable = 2;
    } else {
      mTable = 3;
    }
  }
  // Other months not affected and have set values
  if (m == 10) { mTable = 0; }
  if (m == 8) { mTable = 2; }
  if (m == 3 || m == 11) { mTable = 3; }
  if (m == 4 || m == 7) { mTable = 6; }
  if (m == 5) { mTable = 1; }
  if (m == 6) { mTable = 4; }
  if (m == 9 || m == 12) { mTable = 5; }

  // Enter the data into the formula
  SummedDate = d + mTable + yy + (yy / 4) + cTable;

  // Find remainder
  DoW = fmod(SummedDate, 7);  // 0-6

  // // Remainder determines day of the week
  // if(DoW == 0) { Serial.println("Saturday"); }
  // if(DoW == 1) { Serial.println("Sunday"); }
  // if(DoW == 2) { Serial.println("Monday"); }
  // if(DoW == 3) { Serial.println("Tuesday"); }
  // if(DoW == 4) { Serial.println("Wednesday"); }
  // if(DoW == 5) { Serial.println("Thursday"); }
  // if(DoW == 6) { Serial.println("Friday"); }

  if (DoW == 0) {  // Saturday?
    DoW = 7;
  }

  return DoW;  // 1-7
}

@per1234 per1234 changed the title Can i found the day?(Monday, Tuesday etc) Add function to return day of week Feb 12, 2024
@arduino-libraries arduino-libraries locked as too heated and limited conversation to collaborators Feb 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
topic: code Related to content of the project itself type: enhancement Proposed improvement
Projects
None yet
Development

No branches or pull requests

5 participants