Reputation: 38140
Google is using an unique DateKeys for each days in the GoogleCalendar HTML e.g.
<div
data-datekey="129"
role="gridcell"
tabindex="-1"
jsname="RjPD4e"
aria-labelledby="tsc-0"
data-column-index="0"
data-principal-ids="amFuLm5pY2tsYXNAbmFtaWNzLmNvbQ"
class="YvjgZe Qbfsob">
Is there any formular to calculate the date for a given datekey?
Upvotes: 6
Views: 302
Reputation: 787
In response to @jantimon's answer: I guess they had to do a lot of calculations with dates and wanted it to be efficient.
The odd thing is that if you look at the little calendar in the sidebar, rather than using a data-datekey
attribute, it uses data-date
with a YYYYMMDD
format.
Anyway, I rewrote your conversion function using bitwise operations, since it's easier to read this way.
function datekeyToDate(key) {
/* # BITS: [year_rel(6)][month(4)][day(5)] */
const day = key & 0b11111;
const month = (key>>5) & 0b1111;
const year_rel = (key>>9);
const year = 1970 + year_rel;
return new Date(year, month, day);
}
function dateToDatekey(date) {
const y = date.getFullYear() - 1970;
const m = date.getMonth()+1; /* getMonth() returns 0-based index */
const d = date.getDate();
return (y<<9) + (m<<5) + d;
}
Upvotes: 8
Reputation: 38140
It looks like the dateKey
represents the days since 1.1.1970
in a format optimised for byte shifting.
One year has 2^9
(512
) days.
One month has 2^5
(32
) days.
To calculate the datekey
for 01.01.1970
you would calculate:
0
years (since 1970)* 512
+ 1
month* 32
+ 1
day
= 33
To calculate the datekey
for 01.01.2000
you would calculate:
30
years (since 1970)* 512
+ 1
month* 32
+ 1
day
= 15393
To calculate the date for a given date key you can do the opposite. A modulo calculation could look like the following:
function getDate(dateKey) {
const yearOffset = (dateKey - 32) % 512;
const year = (dateKey - 32 - yearOffset) / 512;
const day = yearOffset % 32;
const month = (yearOffset - day) / 32;
return new Date(year + 1970, month, day);
}
Does anyone know why they came up with such a logic?
Upvotes: 8