Techno-magis

Javascript, le numéro de semaine et numéro du jour de l'année

2014年3月1日(土曜日)

Pour un petit projet en JavaScript, j'ai eu besoin du numéro de semaine. Par flemme, je suis allé sur Stack Overflow dans l'espoir d'avoir une réponse. Il y en a, en nombre avec des solutions plus ou moins complexe... complexe, mais visiblement pas testé. Je me suis donc mis à écrire ma propre solution... où j'ai eu besoin du numéro de jour dans l'année. Et j'ai eu le même problème, des solutions non testées.

Voyant que mes recherches ne mènent à rien de réellement fonctionnel, n'ayant pas envie de passer par une API juste pour une unique méthode, j'ai posé le problème sur le papier, j'ai regardé comment ça fonctionne et j'ai commencé à écrire ma solution avec quelques cases tests qui ne fonctionnaient pas sur les solutions trouvées. Je me suis d'ailleurs rendu compte qu'il était préférable de ne partir de rien. Le nombre de tests a grandement augmenté quand j'ai eu besoin du numéro de jour de l'année, à cause d'une incohérence dans les calculs quand j'ai testé une année entière... Eh oui, ce foutu changement d'heure d'été, heure d'hiver...

Après avoir résolu tous mes problèmes, voici ma solution... parfaitement fonctionnelle sur mon projet. Je pense ne pas être à l’abri d'un bug. Désolé, je ne mets pas les tests unitaires.

コード:

/**
 * donne le jour de l'année en prenant en compte le changement d'heure (hiver/été)
 * @return jour de l'année (0 à 365~366)
 */
Date.prototype.getDayOfYear = function () {
	var date = (new Date(this.getFullYear(), 0, 0));
	return Math.floor((this - date - (this.getUTCHours() - date.getUTCHours()) * 3.6e+6) / 8.64e+7);
};
/**
 * donne le numéro de semaine
 * @param premier premier jour de la semaine (0 = dimanche, 1 = lundi, etc. / défaut = 1)
 * @param base numéro de journée maxium pour la première semaine (défaut = 4 : jeudi)
 * @return numéro de semaine (1 à 52~53)
 */
Date.prototype.getWeek = function (premier = 1, base = 4) {
	premier = typeof(premier) == 'int' ? premier : 1;
	base = typeof(base) == 'int' ? base : 4;
 
	var premierAnPre = new Date(this.getFullYear(),0,0);
	var dernierAn    = new Date(this.getFullYear() +1,0,0);
	var jourSemaine  = (premierAnPre.getDay() + 7 + premier ) % 7; 
 
	var num = Math.ceil( (this.getDayOfYear() + jourSemaine) / 7)  + (jourSemaine <= base ? 0 : -1);
 
	if (num == 0) {
		num = premierAnPre.getWeek(premier, base);	
	} 
	else if (num >= 52 && (dernierAn.getDayOfYear() - this.getDayOfYear())  <=  base 
			&& (dernierAn.getDay() + 7 + premier ) % 7 <= base) {
		num = 1;
	}
 
	return num;
};
 

Édit 11/1/2016 : Vous pouvez maintenant retrouver ce code sur ce repository avec une licence GPL :
https://git.ikilote.net/zaide/BakuJS/blob/gh-pages/baku.date.js

カテゴリ:
Zéflingによって、 2014/03/01 04:26:28
2626回を読んだ。6件のコメントが投稿されています。

全6コメント

Zéflingによって、 2014/05/10 11:09:42
アバター
ウェブマスター

Attention, j'ai mis des paramètres par défaut aux fonctions. Comme je m'en servais que dans Firefox ça passe sans problème, mais visiblement Chrome n'aime pas trop ça (cela n'est pas encore supporté).

Compared to French grammar, nothing is hard. (Rasmus Lerdorf)
philgoodgoodによって、 2015/01/08 16:32:16
訪問者

bonjour
et bien grand merci pour ces tests de longues durées ^^
je les ai portés sur tasker javascriptlet (android 4.4.2) et ca fonctionne du tonnerre

++

philgoodgoodによって、 2015/01/08 16:40:57
訪問者

en complément de mon message précédent, ce lien qui donne plein de bons exemples de formattage de date :
formattage de date en javascript

++

Zéflingによって、 2015/01/08 20:44:45
アバター
ウェブマスター

Petit erreur dans le lien, j'ai corrigé ton message. En effet, ça peut être utile.

働いたら負け。
Y Melchiorによって、 2016/01/13 07:58:44
訪問者

Bonjour, comment executer ce script dans une page html.

D'avance MERCI pour votre réponse.

Yannick

Zéflingによって、 2016/01/15 14:26:32
アバター
ウェブマスター

Il suffit d'ajouter le code et de faire :

コード:

var date = new Date();
console.log(date.getWeek());  // affiche le numéro de semaine dans la console

Par contre, merci de passer par le fichier donner dans GitHub. J'ai fais ça pour résoudre les problèmes de licence. 😉


La plus grande consolation de la médiocrité, c'est que le génie n'est pas immortel.

コメントを書き込む