Calculating day-of-week in years greater than 9999 - algorithm

I was wondering if there are any algorithms that calculate the day of week in years that are greater than the year 9999.
Algorithms such Zeller’s algorithm or this one here gives false results, since they handle only 4 digit year.
Thank you.

You don't actually need a new algorithm. As long as you have one algorithm with a range of 400 years (or more), you can bring any date inside the range of that algorithm. This works because the Gregorian calendar repeats every 400 years (XX/YY/ZZZZ is the same weekday as XX/YY/(ZZZZ+400)).
So, if we assume that you have some algorithm that works for the dates 1/1/1600 to 31/12/1999 (both inclusive), you can calculate the weekday for any date by using (year mod 400)+1600 as the year.
If you don't have a 400-year range starting on 1/1/XXXX (where XXXX mod 400 = 0), you need to manipulate the date slightly different to get the right result (instead of adding 1600 to the year, add X*400, where X is an integer such that some of the dates will be in the range, then add or subtract 400 to the year for those dates that are outside of the range).

http://lxr.linux.no/linux/net/netfilter/xt_time.c for example simply counts it out. To reduce the number of iterations in loops, static tables may be used, as has been done there.

Related

Simple algorithm to alternate days

I need to alternate between 2 tasks every day, and I need a simple algorithm to know which task I need to do.
I need to be able to run this algorithm by head, using simple general knowledge (like day of week, day of month, etc), and it must not rely of which task has been done the previous day (because I have a crappy memory).
I have tried checking for parity in a combination of day of week / day of month / # of month, etc, but couldn't find a suitable system: day of week have 2 consecutive odd numbers, same goes for day of month every so often.
I am afraid that this is impossible: if you can't remember what you did the day before, any other procedure will require more mnemonic effort.
remember what you did on January first (or another date),
remember the parities of the cumulated months: oeoeoeooeoe or ooeoeoeeoeo for a leap year,
add the cumulated parity of the month before* to the parity of the day,
add that to the parity of the first task.
E.g. if A on January 1st 2022, then on March 17, 2022: e + o = o gives B.
*In January, use even.
You can also state the month parity rule as: until August inclusive, use the co-parity of the month number; then use the parity. But for a leap year, change that parity after February (excluded).
I need to be able to run this algorithm by head
So, you don't need to take help of Computer science. You can use cognitive human ability to map a thing to another thing.
Note: This need not make sense to everybody though, if you are thinking out of the box.
Map task 1 as God's day.
Map task 2 as Devil's day in your brain.
This should be simple just like day and night.
Now, remember that devil's evil karma is always burnt by God the next day and that devil never learns his lesson. So this way, alternating would be easy.
Friends Episode snippet on Youtube
Just count the number of days in between your date and a given "zero" one...then use parity.
Take number of seconds (or milli, or whatever) since EPOCH (common zero for date and time), divide (integer division) by 60x60x24 (or 1000x60x60x24, or what is appropriate), you then get the number of days since EPOCH.
----EDIT----
Example: Got 1653910695 seconds since EPOCH (at the time of my experience). Dividing it by 60x60x24 give 19142 days. To morrow it will give 19143, etc.
<?php
$day = Date('j');
$previous_day = date('j', strtotime("-1 days"));
if($day%2==0 OR $previous_day%2!=0)
echo "Task 1";
}else{
echo "Task 2";
}
?>

How to calculate month and any additional days between two dates using google sheet formula?

I want to calculate month between two date and output how month and any additional days by using google sheet
I use this formula to calculate month but i don't know how to calculate any additional days after a complete month.
DATEDIF(AG2,TODAY(),"M")
Quoting this reference of DATEDIF (emphasis mine): https://sheetshelp.com/datedif/
Syntax
=DATEDIF(start_date,end_date,unit)
start_date Date at which to start the calculation
end_date Date at which to end the calculation
unit Type of output. Choices are “Y”, “M”, “D”, “YM”, “YD”, or “MD”.
...
"M" – Number of whole months elapsed between start and end dates
"MD" – Number of days elapsed after the number of months shown with the “M” or “YM” unit. Can’t go higher than 30.
...

algorithm: get next year date work shift type according week number

I work in 3 shifts, each week different one. The order is morning shift (m), night one (n) and afternoon one (a). The order i fixed, i.e. it never changes, even if one won't work that week.
I created a function to get ISO week number. When I throw it a date, it returns week number.
This week (no. 48), for example, I work morning, therefore 48 % 3 = 0 → m = 0; n = 1; a = 2.
I saved this into array shifts = ["m", "n", "a"].
This is the easy part. But as the end of the year comes, I need to solve a problem. As 52 (the total number of weeks in 2017) is not divisible by 3 and there are different number of weeks in different years, modulo 0 (which for year 2017 means m), means something else in different years.
So, the actual question is what would be the fastest and simplest algorithm (rather fastest than simplest), doesn't need to be human-readable, with explanation (if necessary) why/how does it do what it does.
I thought of one (which is neither fast nor simple): to the known week no. & shift type combo add the number of weeks following that week until the end of the year, and recalculate the array shifts.
Why do you want to use ISO week numbers ?
Let's say that your weeks start on some specific day (monday, sunday, you decide). You decide of a starting date d0, also a week start, for shift 0. Then for any date d your shift is:
shift = floor(nbdays(d - d0) / 7) mod 3
Problems may arise if your system work in different locales where the starting day for a week is not the same. In that case you should have a specific d0 for each locale. If your shift is the same worldwide you have no problem.

Explain Apache SOLR boost function

I'm try to implement a logic in APACHE SOLR so that documents older than 2 years should get penalty based on the difference in number of days or months.
I am using this boost function, which I got after googling a lot.
recip(ms(NOW,publicationDate),3.16e-11,1,1) // Currently it is set to use 1 year
Can any please confirm if this penalties old documents or what ?
Thanks
A reciprocal function with recip(x,m,a,b) implementing a/(m*x+b).
m,a,b are constants, x is any numeric field or arbitrarily complex
function.
In case of your parameters, your function will look like this:
f(x) = 1 /(3.16e-11*x + 1)
Function ms returns milliseconds of difference between it's
arguments.
Dates are relative to the Unix or POSIX time epoch, midnight, January
1, 1970 UTC.
Imagine, your publication date is September 1st 2015, ms will get us NOW = 1507725936061 and publication date is 1441065600000 and the whole result will be around 0.3 which will be the score for this document.
For publication date of yesterday, we will get score of 0.99, which leads to the idea, so, this formula will apply penalty to every document not only to ones which are 2 years old. For example, for the same day 1 year ago the score will be 0.5
I could think potentially about sorting by this function (starting from Solr 6)
if(gt(ms(mydatefield,NOW-2YEARS),0),1,recip(ms(NOW,publicationDate),3.16e-11,1,1))
I didn't test it (not sure about NOW-2YEARS part), but basically, i'm doing this:
if mydatefield - NOW-2YEARS greater
than 0 => score will be 1.0
else => I'm calculating reciprocal function
One last remark: there are 3.16e10 milliseconds in a year, so one can scale dates to fractions of a year with the inverse, or 3.16e-11, so for 2 years, you may select something different.

Slight problem with day of the week calculation (base doomsday for a century)

From this online calculator: http://homer.freeshell.org/dd.cgi using its data I've successfully written a working version, however its data is limited to years 1500 to 2600. I want to modify (and make a better one) so that I can calculate for any year > 2600.
Referring to Table X, is there actually a formula to calculate the base doomsday for all base centuries (above 2600)?
I've tried working it out myself by putting centuries higher than this e.g. 2700 gave me a base doomsday of '00', 2800 gave '02;, 2900 back to '00' again...
Help appreciated.
As I understand it, that page's “Base Doomsday” is just an offset to allow for the four-hundred-year cycle of leap day calculations. So, you can extend it indefinitely into the future simply by adding blocks of four centuries.
Are there any other calculators out there that do this?
Two common methods for calculating the day of the week
given a date are Doomsday, which you are using,
and Zeller's Congruence
www.merlyn.demon.co.uk provides
some really interesting information on date/time calculations, various calendar
systems and significant dates as they relate to calendar/date calculations.
The calculator at this link http://homer.freeshell.org/dd.cgi is the best in terms of explaining doomsday algorithm cleanly and clearly for human, with one little caveat.
If you input 2/29/1900, it would say it's a Thursday. Well, there is no 2/29/1900, because it's not a leap year.
Of course if your input 1/35/2016, it would "garbage-in-garbage-out" for you as well.
Imagine there are only 364 days in a year, then the day of week for each date will never change year after year, because mod(364,7)==0.
But we have 365 days a year, so the day steps forward 1 each year, that's where the second term mod(year, 7) comes from.
In addition, every 4 year, there is a leap year, which contributes to the last term mod(year, 4).
But every 100 years, you subtract a leap year, and every 400 years, you add one leap year. That's where the first term "3,2,0,5" comes in.
You see, it's all because of this leap year, and mod(365,7)==1 business.
7/11, 5to9 helps to remember table Z greatly.

Resources