numero - C#- ¿Cuál es la mejor manera de obtener una lista de las semanas en un mes, dado un día de semana que comienza?
obtener numero de semanas de un mes c# (10)
¿Qué tal esto?
public IEnumerable<DateTime> GetWeeks(DateTime date, DayOfWeek startDay)
{
var list = new List<DateTime>();
DateTime first = new DateTime(date.Year, date.Month, 1);
for (var i = first; i < first.AddMonths(1); i = i.AddDays(1))
{
if (i.DayOfWeek == startDay)
list.Add(i);
}
return list;
}
Necesito obtener una lista de semanas para un mes determinado, con el lunes como el día de inicio.
Entonces, por ejemplo, para el mes de febrero de 2009, este método regresaría:
2/2/2009
2/9/2009
2/16/2009
2/23/2009
Algo así como el siguiente pseudo-código debería funcionar:
- Determine la fecha de inicio del mes (use mes y año a partir de una fecha y configure el día en 1
- Determine la fecha de finalización del mes (fecha de inicio + 1 mes)
- Determine la primera fecha que es un lunes (este es su primer elemento en la lista)
- Agregue 7 días para encontrar la próxima fecha y repita hasta que lea o pase el final del mes
Aquí hay una solución (de hecho, una línea) usando C # 3.0 / LINQ, en caso de que esté interesado:
var month = new DateTime(2009, 2, 1);
var weeks = Enumerable.Range(0, 4).Select(n => month.AddDays(n * 7 - (int)month.DayOfWeek + 1)).TakeWhile(monday => monday.Month == month.Month);
Simplemente cambie la línea de respuesta a lo que necesite hacer con eso
protected void PrintDay(int year, int month, DayOfWeek dayName)
{
CultureInfo ci = new CultureInfo("en-US");
for (int i = 1 ; i <= ci.Calendar.GetDaysInMonth (year, month); i++)
{
if (new DateTime (year, month, i).DayOfWeek == dayName)
Response.Write (i.ToString() + "<br/>");
}
}
Solución rápida: no creo que haya una función incorporada para ello ....
int year = 2009;
int month = 2;
DateTime startDate = new DateTime(year, month, 1);
DateTime endDate = startDate.AddMonths(1);
while (startDate.DayOfWeek != DayOfWeek.Monday)
startDate = startDate.AddDays(1);
for (DateTime result = startDate; result < endDate; result = result.AddDays(7))
DoWhatYouWant(result);
public static List<DateTime> GetWeeks(
this DateTime month, DayOfWeek startOfWeek)
{
var firstOfMonth = new DateTime(month.Year, month.Month, 1);
var daysToAdd = ((Int32)startOfWeek - (Int32)month.DayOfWeek) % 7;
var firstStartOfWeek = firstOfMonth.AddDays(daysToAdd);
var current = firstStartOfWeek;
var weeks = new List<DateTime>();
while (current.Month == month.Month)
{
weeks.Add(current);
current = current.AddDays(7);
}
return weeks;
}
Veo que obtuvo su respuesta, pero quería compartir con ustedes una clase de ayuda que creé para uno de mis proyectos. Está lejos de ser una clase comprensiva, pero podría ayudar ...
public static class WeekHelper {
#region Public Methods
public static DateTime GetWeekStart(DateTime date) {
DateTime weekStart;
int monday = 1;
int crtDay = (int)date.DayOfWeek;
if (date.DayOfWeek == DayOfWeek.Sunday)
crtDay = 7;
int difference = crtDay - monday;
weekStart = date.AddDays(-difference);
return weekStart;
}
public static DateTime GetWeekStop(DateTime date) {
DateTime weekStart;
int sunday = 7;
int crtDay = (int)date.DayOfWeek;
if (date.DayOfWeek == DayOfWeek.Sunday)
crtDay = 7;
int difference = sunday - crtDay;
weekStart = date.AddDays(difference);
return weekStart;
}
public static void GetWeekInterval(int year, int weekNo,
out DateTime weekStart, out DateTime weekStop) {
GetFirstWeekOfYear(year, out weekStart, out weekStop);
if (weekNo == 1)
return;
weekNo--;
int daysToAdd = weekNo * 7;
DateTime dt = weekStart.AddDays(daysToAdd);
GetWeekInterval(dt, out weekStart, out weekStop);
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime toDate) {
//gets week series from beginning of the year
DateTime dtStartYear = new DateTime(toDate.Year, 1, 1);
List<KeyValuePair<DateTime, DateTime>> list = GetWeekSeries(dtStartYear, toDate);
if (list.Count > 0) {
KeyValuePair<DateTime, DateTime> week = list[0];
list[0] = new KeyValuePair<DateTime, DateTime>(dtStartYear, week.Value);
}
return list;
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime fromDate, DateTime toDate) {
if (fromDate > toDate)
return null;
List<KeyValuePair<DateTime, DateTime>> list = new List<KeyValuePair<DateTime, DateTime>>(100);
DateTime weekStart, weekStop;
toDate = GetWeekStop(toDate);
while (fromDate <= toDate) {
GetWeekInterval(fromDate, out weekStart, out weekStop);
list.Add(new KeyValuePair<DateTime, DateTime>(weekStart, weekStop));
fromDate = fromDate.AddDays(7);
}
return list;
}
public static void GetFirstWeekOfYear(int year, out DateTime weekStart, out DateTime weekStop) {
DateTime date = new DateTime(year, 1, 1);
GetWeekInterval(date, out weekStart, out weekStop);
}
public static void GetWeekInterval(DateTime date,
out DateTime dtWeekStart, out DateTime dtWeekStop) {
dtWeekStart = GetWeekStart(date);
dtWeekStop = GetWeekStop(date);
}
#endregion Public Methods
}
Esto funciona maravillosamente! Todo lo que tiene que hacer es obtener el primer día del mes para el que desea obtener las semanas y luego esto le dará el primer día de cada semana. Debes obtener 5 semanas (no 4), por lo que Enumerable.Range cuenta 5 en lugar de 4.
var date = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
var weeks = from n in Enumerable.Range(0, 5)
select date.AddDays(7 * n + (-1 * (int)date.DayOfWeek));
// Get the weeks in a month
DateTime date = DateTime.Today;
// first generate all dates in the month of ''date''
var dates = Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month)).Select(n => new DateTime(date.Year, date.Month, n));
// then filter the only the start of weeks
var weekends = from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select d;
Esto es lo que hice, usando el código de Chaowlert como base de partida. Básicamente modifiqué que necesita verificar si agrega los días en los desbordamientos para el próximo mes, por lo que no agrego 4 días (de lunes a viernes), pero en realidad el mínimo entre 4 y el número de días restantes en el mes . Además, verifico si el día actual es un fin de semana, de lo contrario agregar días hasta que sea un día de la semana. Mi propósito es imprimir las semanas en un mes, de lunes a viernes
DateTime fechaInicio = new DateTime(año, mes, 1);
DateTime fechaFin = fechaInicio.AddMonths(1);
int diasHastaFinMes = 0;
while (esFinDeSemana(fechaInicio))
fechaInicio = fechaInicio.AddDays(1);
for (DateTime fecha = fechaInicio; fecha < fechaFin; fecha = fecha.AddDays(7))
{
diasHastaFinMes = DateTime.DaysInMonth(fecha.Year, fecha.Month) - fecha.Day;
printWeeks(fecha, fecha.AddDays(Math.Min(4, diasHastaFinMes)));
}