Busqué en Google mucho y encontré muchas soluciones, pero ninguna de ellas me dio el número de semana correcto para el 2012-12-31. Incluso el ejemplo en MSDN ( enlace ) falla.
2012-12-31 es lunes, por lo tanto, debería ser la semana 1, pero cada método que probé me da 53. Estos son algunos de los métodos que he probado:
De la Biblioteca MDSN:
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;
return cal.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
Solución 2:
return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
Solución 3:
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;
Actualizar
El siguiente método en realidad devuelve 1 cuando la fecha es 2012-12-31. En otras palabras, mi problema era que mis métodos no seguían el estándar 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);
}
Respuestas:
Como se señaló en esta página de MSDN, hay una ligera diferencia entre la numeración de la semana ISO8601 y .Net.
Puede consultar este artículo en el blog de MSDN para obtener una mejor explicación: " Formato ISO 8601 Semana del año en Microsoft .Net "
En pocas palabras, .Net permite que las semanas se dividan en años, mientras que el estándar ISO no. En el artículo también hay una función simple para obtener el número de semana ISO 8601 correcto para la última semana del año.
Actualización El siguiente método en realidad devuelve 1 para el
2012-12-31
cual es correcto en ISO 8601 (por ejemplo, Alemania).fuente
Puede haber más de 52 semanas en un año. Cada año tiene 52 semanas completas + 1 o +2 (año bisiesto) días adicionales. Componen una semana 53.
Entonces, por cada año, tiene al menos uno por día adicional. Dos por años bisiestos. ¿Se cuentan estos días adicionales como semanas separadas?
Cuántas semanas hay realmente depende del día de inicio de su semana. Consideremos esto para el 2012.
Verifique la configuración actual de su Cultura para ver qué usa como primer día de la semana.
Como puede ver, es normal obtener 53 como resultado.
Incluso es posible tener una semana 54. Ocurre cada 28 años cuando el 1 de enero y el 31 de diciembre se tratan como semanas separadas. Debe ser un año bisiesto también.
Por ejemplo, el año 2000 tuvo 54 semanas. El 1 de enero (sábado) fue el primer día de una semana, y el 31 de diciembre (sol) fue el segundo día de una semana.
Imprime: Año: 2012 Semana: 54
Cambie CalendarWeekRule en el ejemplo anterior a FirstFullWeek o FirstFourDayWeek y obtendrá 53. Guardemos el día de inicio el lunes ya que estamos tratando con Alemania.
Entonces, la semana 53 comienza el lunes 31/12/2012, dura un día y luego se detiene.
53 es la respuesta correcta. Cambia la Cultura a Alemania si quieres probarlo.
fuente
Esta es la forma:
Lo más importante para es el
CalendarWeekRule
parámetro.Ver aquí: https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=IT-IT&k=k(System.Globalization.CalendarWeekRule);k(TargetFrameworkMoniker-.NETFramework
fuente
¡Buenas noticias! Se acaba de fusionar una solicitud de extracción que se agrega
System.Globalization.ISOWeek
a .NET Core y actualmente está programada para la versión 3.0. Con suerte, se propagará a las otras plataformas .NET en un futuro no muy lejano.El tipo tiene la siguiente firma, que debería cubrir la mayoría de las necesidades de la semana ISO :
Puedes encontrar el código fuente aquí .
ACTUALIZACIÓN : Estas API también se han incluido en la versión 2.1 de .NET Standard .
fuente
Como no parece haber una cultura .Net que produzca el número de semana ISO-8601 correcto, prefiero omitir por completo la determinación de semana incorporada y hacer el cálculo manualmente, en lugar de intentar corregir una corrección parcialmente correcta resultado.
Lo que terminé con es el siguiente método de extensión:
En primer lugar,
((int)date.DayOfWeek + 6) % 7)
determina el número del día de la semana, 0 = lunes, 6 = domingo.date.AddDays(-((int)date.DayOfWeek + 6) % 7)
determina la fecha del lunes anterior al número de semana solicitado.Tres días después es el jueves objetivo, que determina en qué año está la semana.
Si divide el número de día (basado en cero) dentro del año por siete (redondeando hacia abajo), obtendrá el número de semana (basado en cero) en el año.
En c #, los resultados de cálculo de enteros se redondean hacia abajo implícitamente.
fuente
Ticks
es el número de incrementos de 100 nanosegundos desde el 1 de enero de 0001. Dado que hay 86,400 segundos en un día, podemos escribir:var thursday = date.AddDays(3 - date.Ticks / 86400 / 10_000_000 % 7); return (thursday.DayOfYear - 1) / 7 + 1;
En .NET 3.0 y versiones posteriores, puede usar el
ISOWeek.GetWeekOfDate
método .Tenga en cuenta que el año en el formato de número de año + semana puede diferir del año
DateTime
debido a las semanas que cruzan el límite del año.fuente
C # al puerto Powershell desde el código anterior de il_guru :
fuente
La forma más fácil de determinar el estilo de número de semana ISO 8601 usando c # y la clase DateTime.
Pregunte esto: el jueves cuántos años es el jueves de esta semana. La respuesta es igual al número de semana deseado.
fuente
Funciona bien tanto para las culturas estadounidense como rusa. ISO 8601 también será correcta, porque la semana rusa comienza el lunes.
fuente
Aquí hay una versión de extensión y una versión anulable de la respuesta de il_guru .
Extensión:
Anulable:
Usos:
fuente
La pregunta es: ¿Cómo define si una semana es en 2012 o en 2013? Supongo que su suposición es que, dado que 6 días de la semana son en 2013, esta semana debe marcarse como la primera semana de 2013.
No estoy seguro si este es el camino correcto. Esa semana comenzó en 2012 (el lunes 31 de diciembre), por lo que debe marcarse como la última semana de 2012, por lo tanto, debe ser el 53 de 2012. La primera semana de 2013 debe comenzar el lunes 7.
Ahora, puede manejar el caso particular de semanas límite (primera y última semana del año) utilizando la información del día de la semana. Todo depende de tu lógica.
fuente
fuente
Basado en la respuesta de il_guru, creé esta versión para mis propias necesidades que también devuelve el componente del año.
fuente
Estos dos métodos ayudarán, suponiendo que nuestra semana comience el lunes
fuente
Un año tiene 52 semanas y 1 día o 2 en caso de un año de vuelta (52 x 7 = 364). 2012-12-31 sería la semana 53, una semana que solo tendría 2 días porque 2012 es un año de vuelta.
fuente
fuente