Days since January 1st, 0 AD (Gregorian calendar)

hi everyone,

SSLClient.h need to set time manually, in particular there is an function to set time "setVerificationTime(uint32_t days, uint32_t seconds)".

days: days since January 1st, 0 AD (Gregorian calendar).

seconds: seconds since midnight (0 to 86400).

Is there any function to get this data from ESP32 RTC internal(Setted in setup())?

Thanks

@abinformatica ,

Your topic was moved to its current location as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

It will help you get the best out of the forum in the future.

Thank you

the typical functions using a struct tm

uint32_t getDaysSinceEpoch(const struct tm& timeInfo) {
    int year = timeInfo.tm_year + 1900;
    int month = timeInfo.tm_mon + 1;
    int day = timeInfo.tm_mday;

    // Calculate number of days since January 1st, 0 AD
    int a = (14 - month) / 12;
    int y = year + 4800 - a;
    int m = month + 12 * a - 3;

    uint32_t days = day + (153ul * m + 2) / 5 + 365ul * y + y / 4ul - y / 100ul + y / 400ul - 32045ul;
    return days;
}

uint32_t getSecondsSinceMidnight(const struct tm& timeInfo) {
    int hour = timeInfo.tm_hour;
    int minute = timeInfo.tm_min;
    int second = timeInfo.tm_sec;

    uint32_t seconds = hour * 3600ul + minute * 60ul + second;
    return seconds;
}

(see this post to get the time from an NTP server)

Can you explain me those constant?

The calendar that's in use in most of the world doesn't have a year zero, not AD or BC. That's because it was established when Roman numerals were the way people counted, and they had no zero but always started a count with 1.

Google the formula and you’ll see lots of littérature explaining the maths

There is no year zero in a calendar.

If you have a look at e.g. a thermometer then you find a point of zero degrees, but the range around that point extends to either +1 or -1 degrees. Likewise a year at the calendar origin will extend to +1 or -1, the first year after or before Christ. See AD = p.C.n in wikipedia.

There is no human system more messed up than time keeping.

But the science and astronomy knowledge / maths behind the Gregorian calendars is fascinating.

It was a bold move to decide to get 10 days forward in one night (The Julian calendar day Thursday, 4 October 1582 was followed by the first day of the Gregorian calendar, Friday, 15 October 1582) a decision that was applied over the globe at different moment due to the religious connotation of the decision.

See Gregorian calendar - Wikipedia

There are many others - like the Mayan wheels - that are also fun to read about

Thanks J-M-L for faster answer.

I'm not a math expert, actually.
I researched a bit on the internet about your formula and I understood something..

I have only one question:
Using online converters like this and this the results are and respectively 738715 and 738.716 days.

Instead with this formula it returns me 2415020.

I got printed

  • day: 0
  • months: 1
  • year: 1900

There seems to be a huge gap between the results, which is the right one?

Integral time values in computer programs and/or RTC chips traditionally started at a random date, like 1900 or 1970. Unsigned numbers prevent handling of dates before that starting point. Consequently dates are exchangable across programs/systems only in verbose y/m/d form, not in day numbers.

struct tm timeInfo;
  
  int year = timeInfo.tm_year + 1900;
  int month = timeInfo.tm_mon + 1;
  int day = timeInfo.tm_mday;

  // Calculate number of days since January 1st, 0 AD
  int a = (14 - month) / 12;
  int y = year + 4800 - a;
  int m = month + 12 * a - 3;

  uint32_t days = day + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 32045;

  log_i("%d/%d/%d", day, month, year);

  log_i("Days %d\n", days);

with what input?

Please see my code posted

What has that code to do with the input you gave to various online converters?

In chronology and periodization, an epoch or reference epoch is an instant in time chosen as the origin of a particular calendar era. The "epoch" serves as a reference point from which time is measured.

The formula I provided is used to calculate the Julian Day Number (JDN) for a given date in the Gregorian calendar. The JDN represents the number of days since noon on January 1, 4713 BCE (start of the Julian date calendar).

âžś This formula can be used to convert a date to the JDN format

if you want the number of days since January 1st, 0001 you need to subtract from the JDN you calculate for the chosen date the JDN for 1/1/1 which is a constant since both dates are known = 1 721 426

the formula would be then

unsigned long days = day + ((153ul * m + 2) / 5) + (365ul * y) + (y / 4ul) - (y / 100ul) + y / 400ul - 32045ul - 1721426ul;

here is a code example for ESP32 that will give you 738714

#include <WiFi.h>
#include "time.h"

const char * ssid = "xxx";
const char * wifipw = "xxx";


void setTimezone(const char * timezone) {
  Serial.print("Setting Timezone to ");
  Serial.println(timezone);
  setenv("TZ", timezone, 1);
  tzset();
}

void initTime(const char * timezone) {
  struct tm timeinfo;

  Serial.println("Getting time from NTP server");
  configTime(0, 0, "pool.ntp.org");    // First connect to NTP server, use 0 TZ offset
  if (!getLocalTime(&timeinfo)) {
    Serial.println("  Failed to obtain time");
    return;
  }
  Serial.println("OK, Got the time from NTP");
  setTimezone(timezone); // then set your timezone
}

void printLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("printLocalTime: Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S zone %Z %z ");
}

// Calculate number of days since January 1st, 1 AD
unsigned long getDaysSinceFirstDay(const struct tm& timeInfo) {
  unsigned long year = timeInfo.tm_year + 1900;
  unsigned short month = timeInfo.tm_mon + 1;
  unsigned short day = timeInfo.tm_mday;

  unsigned short a = (14 - month) / 12;
  unsigned short y = year + 4800 - a;
  unsigned short m = month + 12 * a - 3;
  unsigned long days = day + ((153ul * m + 2) / 5) + (365ul * y) + (y / 4ul) - (y / 100ul) + y / 400ul - 32045ul - 1721426ul;  return days;
}

unsigned long getSecondsSinceMidnight(const struct tm& timeInfo) {
  unsigned short hour = timeInfo.tm_hour;
  unsigned short minute = timeInfo.tm_min;
  unsigned short second = timeInfo.tm_sec;

  unsigned long seconds = hour * 3600ul + minute * 60ul + second;
  return seconds;
}

void printSetVerificationTimeInfo() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("printSetVerificationTimeInfo: Failed to obtain time");
    return;
  }
  Serial.print("Now : "); printLocalTime();
  unsigned long daysSinceFirstDay = getDaysSinceFirstDay(timeinfo);
  unsigned long secondsSinceMidnight = getSecondsSinceMidnight(timeinfo);

  Serial.print("Days since Jan 1, 0001: "); Serial.println(daysSinceFirstDay);
  Serial.print("Seconds since midnight: "); Serial.println(secondsSinceMidnight);
}

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);

  WiFi.begin(ssid, wifipw);
  Serial.println("Connecting Wifi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("\nWifi OK");

  // find your TZ string in https://sites.google.com/a/usapiens.com/opnode/time-zones
  initTime("CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00"); // France
}

void loop() {
  printSetVerificationTimeInfo();
  Serial.println();
  delay(5000);
}

Ok, I have this result of day:738714 its correct?

Because from an converter online is 738714
and an other converter online is 738715

say we are Wednesday - how many days ago was Monday?

easy enough : Monday - Tuesday - Wednesday

some people will say it was 2 days ago but from a time elapsed perspective at the end of Wednesday you are three days (3 x 24h) away from the start of Monday

âžś it depends if you count the current day or not

I disagree. From the end of Monday to the beginning of Wednesday is just Tuesday, so 1 day.

I think the point is that you have to be clear what you are including when you define an interval.

That’s true too :slight_smile: