307 votes

Obtenir le numéro de semaine correct d'une date donnée

J'ai beaucoup cherché sur Google et trouvé de nombreuses solutions, mais aucune d'entre elles ne me donne le numéro de semaine correct pour le 2012-12-31. Même l'exemple sur MSDN ( lien ) échoue.

2012-12-31 est un lundi, donc ce devrait être la semaine 1, mais toutes les méthodes que j'ai essayées me donnent 53. Voici quelques-unes des méthodes que j'ai essayées :

De la bibliothèque du MDSN :

DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;

return cal.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);

Solution 2 :

return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

Solution 3 :

CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;

Mise à jour

La méthode suivante renvoie en fait 1 lorsque la date est 2012-12-31. En d'autres termes, mon problème était que mes méthodes ne respectaient pas la norme ISO-8601.

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

10 votes

Comment est la semaine 1 à la fin de l'année ? Je veux dire, je vois où tu veux en venir. Mais 53 a du sens pour moi.

1 votes

Dans mes extraits de code, j'obtiens les CultureInfo et autres. Je pensais que mon programme savait déjà quel calendrier j'utilisais. (Ici, en Allemagne, le 31 décembre 2012 est la première semaine de 2013).

0 votes

Ce code ne fonctionne pas tout à fait comme il devrait essayer les dates 31-dec-2016 par exemple ou 1-jan-2016

394voto

il_guru Points 3123

Comme indiqué dans ce Page MSDN il existe une légère différence entre la numérotation des semaines ISO8601 et celle des semaines .Net.

Vous pouvez vous référer à cet article dans MSDN Blog pour une meilleure explication : " Format de la semaine de l'année ISO 8601 dans Microsoft .Net "

En termes simples, .Net permet de répartir les semaines sur plusieurs années, ce qui n'est pas le cas de la norme ISO. L'article contient également une fonction simple permettant d'obtenir le numéro de semaine ISO 8601 correct pour la dernière semaine de l'année.

Mise à jour La méthode suivante renvoie en fait 1 pour 2012-12-31 ce qui est correct dans la norme ISO 8601 (par exemple en Allemagne).

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

0 votes

Merci ! Le code figurant dans l'article du blog a finalement résolu mon problème. J'ai inclus le code correspondant dans ma question au cas où quelqu'un aurait le même problème. Ou vous pouvez simplement le copier dans votre réponse.

3 votes

@il_guru Et si je souhaite que la semaine commence par le dimanche ? ? Dois-je remplacer tous les "lundi" par des "dimanche" ? ?

0 votes

Je pense que vous devriez remplacer lundi par dimanche et mercredi par mardi dans la partie triche.

38voto

Christophe Geers Points 4595

Il peut y avoir plus de 52 semaines dans une année. Chaque année compte 52 semaines complètes + 1 ou +2 (année bissextile) jours supplémentaires. Ils forment une 53e semaine.

  • 52 semaines * 7 jours = 364 jours.

Ainsi, pour chaque année, vous avez au moins un jour supplémentaire. Deux pour les années bissextiles. Ces jours supplémentaires sont-ils comptés comme des semaines à part entière ?

Le nombre de semaines dépend en fait du jour de départ de votre semaine. Prenons l'exemple de 2012.

  • US (dimanche -> samedi) : 52 semaines + une petite semaine de 2 jours pour 2012-12-30 & 2012-12-31. Cela donne un total de 53 semaines. Les deux derniers jours de cette année (dimanche + lundi) constituent leur propre semaine courte.

Vérifiez les paramètres de votre culture actuelle pour voir ce qu'elle utilise comme premier jour de la semaine.

Comme vous le voyez, il est normal d'en obtenir 53.

  • Europe (lundi -> dimanche) : Le 2 janvier (2012-1-2) est le premier lundi, c'est donc le premier jour de la première semaine. Demandez le numéro de semaine pour le 1er janvier et vous obtiendrez 52 car il est considéré comme faisant partie de la semaine de 2011 dernier.

Il est même possible d'avoir une 54e semaine. Cela se produit tous les 28 ans lorsque le 1er janvier et le 31 décembre sont traités comme des semaines distinctes. Ce doit aussi être une année bissextile.

Par exemple, l'année 2000 comptait 54 semaines. Le 1er janvier (sam) était le premier jour d'une semaine, et le 31 décembre (soleil) était le deuxième jour d'une semaine.

var d = new DateTime(2012, 12, 31);
CultureInfo cul = CultureInfo.CurrentCulture;

var firstDayWeek = cul.Calendar.GetWeekOfYear(
    d,
    CalendarWeekRule.FirstDay,
    DayOfWeek.Monday);

int weekNum = cul.Calendar.GetWeekOfYear(
    d,
    CalendarWeekRule.FirstDay,
    DayOfWeek.Monday);

int year = weekNum == 52 && d.Month == 1 ? d.Year - 1 : d.Year;
Console.WriteLine("Year: {0} Week: {1}", year, weekNum);

Imprimé : Année : 2012 Semaine : 54

Changez CalendarWeekRule dans l'exemple ci-dessus en FirstFullWeek ou FirstFourDayWeek et vous obtiendrez 53. Gardons le jour de départ le lundi puisque nous avons affaire à l'Allemagne.

La semaine 53 commence donc le lundi 2012-12-31, dure un jour et s'arrête ensuite.

53 est la bonne réponse. Changez la culture en Allemagne si vous voulez l'essayer.

CultureInfo cul = CultureInfo.GetCultureInfo("de-DE");

0 votes

Je sais qu'il est possible qu'il y ait 53 semaines. Mais lorsque vous avez le dimanche (30/12) et le lundi (31/12), ne comptez-vous pas également le mardi (01/01) comme faisant partie de la 53e semaine aux États-Unis ?

1 votes

Je n'ai jamais vu une 54e semaine !

0 votes

Certains logiciels fiscaux en disposent.

2voto

var cultureInfo = CultureInfo.CurrentCulture;
var calendar = cultureInfo.Calendar;

var calendarWeekRule = cultureInfo.DateTimeFormat.CalendarWeekRule;
var firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
var lastDayOfWeek = cultureInfo.LCID == 1033 //En-us
                    ? DayOfWeek.Saturday
                    : DayOfWeek.Sunday;

var lastDayOfYear = new DateTime(date.Year, 12, 31);

var weekNumber = calendar.GetWeekOfYear(date, calendarWeekRule, firstDayOfWeek);

 //Check if this is the last week in the year and it doesn`t occupy the whole week
return weekNumber == 53 && lastDayOfYear.DayOfWeek != lastDayOfWeek 
       ? 1  
       : weekNumber;

Il fonctionne aussi bien pour les cultures américaines que russes. La norme ISO 8601 sera également correcte, car la semaine russe commence le lundi.

0voto

Samy Arous Points 5294

La question est la suivante : comment définir si une semaine est en 2012 ou en 2013 ? Votre hypothèse, je suppose, est que puisque 6 jours de la semaine sont en 2013, cette semaine devrait être marquée comme la première semaine de 2013.

Je ne suis pas sûr que ce soit la bonne façon de procéder. Cette semaine a commencé en 2012 (le lundi 31 décembre), elle devrait donc être marquée comme la dernière semaine de 2012, donc la 53e de 2012. La première semaine de 2013 devrait commencer le lundi 7.

Maintenant, vous pouvez traiter le cas particulier des semaines de bordure (première et dernière semaine de l'année) en utilisant l'information du jour de la semaine. Tout dépend de votre logique.

0 votes

Ok, je vois ce que tu veux dire. Le problème, c'est que lorsque j'utilise le 2013/01/07 dans une de mes méthodes, cela indique la semaine 2. Donc, le 31 décembre 2012 est la semaine 53 et le 7 janvier 2013 est la semaine 2. Vous pourriez penser qu'il n'y a pas de semaine 1 de 2013. Mais lorsque j'essaie le 2013/01/01, il indique la semaine 1.

-1voto

CarlosJ Points 191

Une année compte 52 semaines et 1 jour ou 2 dans le cas d'une année de tour (52 x 7 = 364). Le 31 décembre 2012 serait la semaine 53, une semaine qui ne compterait que 2 jours puisque 2012 est une année lap.

1 votes

Ceci est incorrect. Le premier jour de la semaine de l'année peut tomber n'importe quel jour de la semaine, selon la façon dont vous comptez les semaines, l'année peut avoir une 54e semaine.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X