Files
FHC-Core/public/js/composables/CalendarDate.js
T
2023-02-06 08:43:43 +01:00

161 lines
5.6 KiB
JavaScript

class CalendarDate {
constructor(y, m, d) {
this.weekStart = CalendarDate.getWeekStart();
this.set(y, m, d);
this._clean();
}
get y() { return this._y }
set y(v) { this._y = v; this._clean() }
get m() { return this._m }
set m(v) { this._m = v; this._clean() }
get d() { return this._d }
set d(v) { this._d = v; this._clean() }
/**
* @see https://www.smart-rechner.de/kalenderwochen/rechner.php
*/
get w() {
if (this._w === null) {
if (this.weekStart == 1 && this._m == 11 && this._d > 28 && this.wd <= this._d-29) {
this._w = 1;
} else if (this.weekStart == 1 && this._m == 0 && this._d < 4 && 3-this.wd <= -this._d) {
let weekStartOfTheYear = new Date(this.y-1, 0, this.weekStart == 1 ? 4 : 1);
weekStartOfTheYear.setDate(weekStartOfTheYear.getDate() - (weekStartOfTheYear.getDay() + 7 - this.weekStart)%7);
this._w = Math.ceil((Math.floor((new Date(this.y, this.m, this.d) - weekStartOfTheYear) / 86400000) + 1) / 7);
} else {
let weekStartOfTheYear = new Date(this.y, 0, this.weekStart == 1 ? 4 : 1);
weekStartOfTheYear.setDate(weekStartOfTheYear.getDate() - (weekStartOfTheYear.getDay() + 7 - this.weekStart)%7);
this._w = Math.ceil((Math.floor((new Date(this.y, this.m, this.d) - weekStartOfTheYear) / 86400000) + 1) / 7);
}
}
return this._w;
}
set w(v) {
if (this.w != v) {
let lw = this.numWeeks;
this.d += (v - this.w) * 7;
if (v > 0 && v <= lw && this.w != v) {
if (this.weekStart != 1) {
if (this.w == 1) {
this.set(this.firstDayOfWeek);
} else {
this.set(this.lastDayOfWeek);
}
}
if (this.w != v) {
console.error('couldn\'t set the week', this, v);
}
}
}
}
get wd() {
if (this._wd === null) {
this._wd = ((new Date(this.y, this.m, this.d)).getDay()+7-this.weekStart)%7;
}
return this._wd;
}
get firstDayOfWeek() {
let firstDayOfWeek = new Date(this.y, this.m, this.d);
firstDayOfWeek.setDate(this.d -(firstDayOfWeek.getDay()+7-this.weekStart)%7);
return firstDayOfWeek;
}
get cdFirstDayOfWeek() {
return new CalendarDate(this.firstDayOfWeek);
}
get lastDayOfWeek() {
let lastDayOfWeek = new Date(this.y, this.m, this.d);
lastDayOfWeek.setDate(this.d -(lastDayOfWeek.getDay()+7-this.weekStart)%7 +6);
return lastDayOfWeek;
}
get cdLastDayOfWeek() {
return new CalendarDate(this.lastDayOfWeek);
}
get firstDayOfCalendarMonth() {
let firstDayOfMonth = new Date(this.y, this.m, 1);
return new Date(this.y, this.m, 1-(firstDayOfMonth.getDay() + 7 - this.weekStart)%7);
}
get cdFirstDayOfCalendarMonth() {
let firstDayOfMonth = new Date(this.y, this.m, 1);
return new CalendarDate(this.y, this.m, 1-(firstDayOfMonth.getDay() + 7 - this.weekStart)%7);
}
get lastDayOfCalendarMonth() {
let lastDayOfMonth = new Date(this.y, this.m+1, 0);
return new Date(lastDayOfMonth.getFullYear(), lastDayOfMonth.getMonth(), lastDayOfMonth.getDate()+6-(lastDayOfMonth.getDay() + 7 - this.weekStart)%7);
}
get cdLastDayOfCalendarMonth() {
let lastDayOfMonth = new Date(this.y, this.m+1, 0);
return new CalendarDate(lastDayOfMonth.getFullYear(), lastDayOfMonth.getMonth(), lastDayOfMonth.getDate()+6-(lastDayOfMonth.getDay() + 7 - this.weekStart)%7);
}
get numWeeks() {
return (new CalendarDate(this.y+1,0,this.weekStart == 1 ? -3 : 0)).w;
}
set(y,m,d,noClean) {
if (y !== undefined && (m === undefined || m === true) && d === undefined) {
if (Object.prototype.toString.call(y) === '[object Date]')
return this.set(y.getFullYear(), y.getMonth(), y.getDate(), m);
if (y.y !== undefined && y.m !== undefined && y.d !== undefined)
return this.set(y.y, y.m, y.d, m);
}
[this._y,this._m,this._d] = [y || 0, m || 0, d || 0];
if (!noClean)
this._clean();
}
_clean() {
this.set(new Date(this._y, this._m, this._d), true);
this._w = null;
this._wd = null;
}
format(options) {
return (new Date(this._y, this._m, this._d)).toLocaleString(undefined, options);
}
compare(d) {
if (Object.prototype.toString.call(d) === '[object Date]')
return (this.y === d.getFullYear() && this.m === d.getMonth() && this.d === d.getDate());
return (this.y === d.y && this.m === d.m && this.d === d.d);
}
isInWeek(w, y) {
if (this.y == y && this.w == w)
return true;
if (this.weekStart == 1)
return false;
let edgeDay = this.cdFirstDayOfWeek;console.log(edgeDay);
if (edgeDay.y == y && edgeDay.w == w)
return true;
edgeDay = this.cdLastDayOfWeek;
if (edgeDay.y == y && edgeDay.w == w)
return true;
return false;
}
setLocale(locale) {
this.weekStart = CalendarDate.getWeekStart(locale);
}
}
/**
* Returns the weekday number (Date.getDay()) on which the week starts depending on the locale.
* This can be Saturday(6), Sunday(0) or Monday(1)
*
* @see https://stackoverflow.com/questions/53382465/how-can-i-determine-if-week-starts-on-monday-or-sunday-based-on-locale-in-pure-j
*
* @param string locale
*
* @return integer
*/
CalendarDate.getWeekStart = function(locale) {
locale = locale || navigator.language;
const parts = locale.match(/^([a-z]{2,3})(?:-([a-z]{3})(?=$|-))?(?:-([a-z]{4})(?=$|-))?(?:-([a-z]{2}|\d{3})(?=$|-))?/i);
const regionSat = 'AEAFBHDJDZEGIQIRJOKWLYOMQASDSY'.match(/../g);
const regionSun = 'AGARASAUBDBRBSBTBWBZCACNCODMDOETGTGUHKHNIDILINJMJPKEKHKRLAMHMMMOMTMXMZNINPPAPEPHPKPRPTPYSASGSVTHTTTWUMUSVEVIWSYEZAZW'.match(/../g);
const languageSat = ['ar','arq','arz','fa'];
const languageSun = 'amasbndzengnguhehiidjajvkmknkolomhmlmrmtmyneomorpapssdsmsnsutatethtnurzhzu'.match(/../g);
return (
parts[4] ? (
regionSun.includes(parts[4]) ? 0 :
regionSat.includes(parts[4]) ? 6 : 1) : (
languageSun.includes(parts[1]) ? 0 :
languageSat.includes(parts[1]) ? 6 : 1));
}
export default CalendarDate