Laden...

Funktion für Lezter Sonntag im Monat

Letzter Beitrag vor 15 Jahren 24 Posts 6.868 Views
Funktion für Lezter Sonntag im Monat

Hallo hat jemand eine Funktion oder eine Super idee wie ich in C# den letzten Sonntag im Monat bestimmen kann?

private static DateTime lastSundayOfMonth(int year,int month)
{
	DateTime dateTime = new DateTime(year,month,1).AddMonths(1).AddDays(-1);
	while (dateTime.DayOfWeek!= DayOfWeek.Sunday)
		dateTime = dateTime.AddDays(-1);
	return dateTime;
}

Gruß,
dN!3L

Hallo dN!3L,

statt der Schleife wäre es schicker, wenn du die Differenz zum Sonntag direkt ausrechnest und abziehst.

herbivore

Hallo

Scheint zu funktionieren:

      static void Main(string[] args)
      {
         //CultureInfo ci = CultureInfo.CurrentCulture;
         DateTime startDate = DateTime.Today;
         for (int i = 0; i < 20; i++)
         {
            DateTime date = startDate.AddMonths(i);
            int year = date.Year;
            int month = date.Month;

            date = GetLastSunday(year, month);

            Console.WriteLine("{0}-{1}: {2} {3}", year, month, date.ToString("yyyy-MM-dd"), date.DayOfWeek);
         }

         Console.WriteLine();
         Console.WriteLine("Press any key");
         Console.ReadKey();
      }

      private static DateTime GetLastSunday(int year, int month)
      {
         DateTime day = new DateTime(year, month, 01);
         if (day.DayOfWeek != DayOfWeek.Sunday)
            day = day.AddDays(7 - (int)day.DayOfWeek);

         int weeksOffset = (int)Math.Floor((float)(DateTime.DaysInMonth(day.Year, day.Month) - day.Day) / 7F);
         day = day.AddDays(weeksOffset * 7);

         return day;
      }

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

Hallo Florian Reischl,

mit floats zu rechnen halte ich für ungünstig und unnötig.

herbivore

Hallo,

mein Beispiel schau so aus:

using System;

namespace ConsoleApplication1
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine(LastSundayInMonth(DateTime.Now));
			Console.ReadKey();
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Ermittelt den letzten Tag im Monat.
		/// </summary>
		private static DateTime LastDayOfMonth(DateTime date)
		{
			return new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Ermittelt den letzten Sonntag im Monat.
		/// </summary>
		private static DateTime LastSundayInMonth(DateTime date)
		{
			// Letzter Tag im Monat:
			DateTime lastDayOfMonth = LastDayOfMonth(date);

			// Je nachdem welcher Wochentag das ist soviele Tage abziehen bis
			// der Sonntag erreicht ist:
			int offset = -(int)lastDayOfMonth.DayOfWeek;

			return lastDayOfMonth.AddDays(-(int)lastDayOfMonth.DayOfWeek);
		}
	}
}

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Hallo ihr drei Coder,

und jetzt das Ganze noch für einen beliebigen Wochentag. 😃 Und die beste Lösung dann ab in die .NET-Komponenten und C#-Snippets.

herbivore

Hallo herbivore

mit floats zu rechnen halte ich für ungünstig und unnötig.

Floats waren natürlich Schmarrn, hast Recht. Korrekt wäre decimal. Int geht meiner Meinung nach nicht wegen der Bit-weisen Rundung, außer ich steht gerade auf dem Schlauch (Montag...).

Eigentlich finde ich Gü's Methode aber eh schicker 😉.

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

Aus der Reihe "wie geht's kürzer" heute:


DateTime GetLastSunday(int year, int month)
{
  DateTime result = new DateTime(year, month+1, 1);
  int a = (int)result.DayOfWeek; //nur für die Übersicht :)
  return result.AddDays(7 * (Math.Sign(a) - 1) - a);
}


LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

Hallo LaTino,

das haut schon mal im Dezember nicht hin:

new DateTime(year, month+1, 1);

herbivore

Hallo ihr drei Coder,

und jetzt das Ganze noch für einen beliebigen Wochentag. 😃 Und die beste Lösung dann ab in die
>
.

herbivore

Habe mal Gü's Ansatz etwas aufgebohrt:

      static void Main(string[] args)
      {
         //CultureInfo ci = CultureInfo.CurrentCulture;
         DateTime startDate = DateTime.Today;

         foreach (DayOfWeek dow in Enum.GetValues(typeof(DayOfWeek)))
         {
            Console.WriteLine("---=============================================");
            Console.WriteLine("-- {0}", dow);

            for (int i = 0; i < 20; i++)
            {
               DateTime date = startDate.AddMonths(i);
               int year = date.Year;
               int month = date.Month;

               date = GetLastWeekdayOfMonth(year, month, dow);

               Console.WriteLine("{0}-{1}: {2} {3}", year, month, date.ToString("yyyy-MM-dd"), date.DayOfWeek);
            }
         }


         Console.WriteLine();
         Console.WriteLine("Press any key");
         Console.ReadKey();
      }

      private static DateTime GetLastWeekdayOfMonth(int year, int month, DayOfWeek dow)
      {
         // Get last day of month
         DateTime day = new DateTime(year, month, 01).AddDays(DateTime.DaysInMonth(year, month) - 1);

         // Required day of week
         int reqDay = (int)dow;
         // Last day of week
         int lastDay = (int)day.DayOfWeek;
         int offset;

         // If requested DOW is less than or equal to last DOW we can use this offset
         if (reqDay <= lastDay)
            offset = -(lastDay - reqDay);
         else // Otherwise we have to go to the previous week and move back until the required DOW
            offset = -lastDay - (7 - reqDay);

         // Add the (negative) offset to the last day of month
         day = day.AddDays(offset);

         return day;
      }

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

das haut schon mal im Dezember nicht hin:

Hatte noch im Hinterkopf, dass C# damit klarkommt. Aber nun gut:


DateTime GetLastSunday(int year, int month)
{
  DateTime result = new DateTime(year, month, 1).AddMonth(1);
  int a = (int)result.DayOfWeek; //nur für die Übersicht :)
  return result.AddDays(7 * (Math.Sign(a) - 1) - a);
}

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

und jetzt das Ganze noch für einen beliebigen Wochentag.


private static DateTime lastDayOfWeekOfMonth(int year,int month,DayOfWeek dayOfWeek)
{
	DateTime dateTime = new DateTime(year,month,1).AddMonths(1).AddDays(-1);
	return dateTime.AddDays((dayOfWeek-dateTime.DayOfWeek-7)%7);
}

Gruß,
dN!3L

  
private static DateTime lastDayOfWeekOfMonth(int year,int month,DayOfWeek dayOfWeek)  
{  
  DateTime dateTime = new DateTime(year,month,1).AddMonths(1).AddDays(-1);  
  return dateTime.AddDays((dayOfWeek-dateTime.DayOfWeek-7)%7);  
}  
  

Sehr geil 😃 Jetzt muss ich mir nur noch überlegen, wieso ich mod mit Sign() simuliert hab^^

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

Hallo dN!3L,

sieht doch schön kurz aus. Allerdings graust es mich, wenn Modulo auf negative Werte angewendet wird. Das ist auch potenziell nicht (auf andere Programmiersprachen) portabel. Besser ist es, sicherzustellen, dass die Werte immer positiv (oder Null) sind. Wenn du das noch änderst, wäre das mein Favorit für die Snippets.

herbivore

Besser ist es, sicherzustellen, dass die Werte immer positiv (oder Null) sind.

Math.Abs(-1)

@dN!3L: Dann geht das Snippet wohl an dich 😃

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

Hallo,

wenn ich darf:


private static DateTime lastDayOfWeekOfMonth(int year, int month, DayOfWeek dayOfWeek)
{
	DateTime dateTime = new DateTime(year, month, 1).AddMonths(1);
        return dateTime.AddDays(((dayOfWeek - dateTime.DayOfWeek + 7) % 7) - 7);
}

So wird nur bezüglich positiver Zahlen Modulo genommen.
(Das AddDays(-1) fällt hierbei weg, weil die Differenz nun von -7 bis -1 geht und nicht mehr von -6 bis 0)

Aber wirklich ein sehr nettes Snippet @ dN!3L.
muss schon sagen, gefällt mir 😃

beste Grüße
zommi

Hallo Florian Reischl,

ich meinte, dass die Operanden des Modulo-Operators positiv sein sollen. Dazu braucht man aber kein Math.Abs (bzw. Math.Abs würde sogar potenziell falsch funktionieren) sondern es reicht, wenn man zu dem linken Operanden sieben oder ein Vielfaches von sieben dazuaddiert. Im Prinzip wie zommi das gemacht hat.

Hallo zommi,

ich hatte auch schon daran gedacht, dass man das AddDays(-1) einsparen kann. 😃

herbivore

Hallo zommi,

ich hab's auch gerade nochmal ohne negative Modulo probiert, das bricht mir aber im Moment das Hirn... 😜 Schöne elegante Lösung von dir. 👍

Ach und herbivore: [Hinweis] Wie poste ich richtig? Punkt 4abc 😁 8)

Gruß,
dN!3L

EDIT: Also wie ich die Meinungen so sehe, geht das Snippet an mich (mit zommis Hilfe). Also soll ich?

Hallo zusammen,

dann würde ich vorschlagen, dass du, zommi, das "Ergebnis-Snippet" in .NET-Komponenten und C#-Snippets einstellst.

[EDIT]Jetzt erst dein Edit gesehen, dN!3L. Mir ist es egal. Schlagt euch! 😃[/EDIT]

herbivore

Mir ist es egal. Schlagt euch! 🙂

Schnellster! 😁

Bestimmung des Datums des letzen Wochentages eines Monats

Beste Grüße und nochmal Dank an zommi,
dN!3L


>

Und nach nicht mal einer Woche kontaktiert mich schon der Erste (via IM), dessen Freund das Codesnippet in Delphi übersetzt hat, und möchte verstehen können, wie/warum der Code funktioniert. 8)

Beste Grüße,
dN!3L

Ich bekenne mich "schuldig": In der Delphi-Praxis gab es genau die gleiche Frage; also habe ich auf deine Lösung hingewiesen. Der Fragesteller konnte mit C# nichts anfangen, und mein Delphi ist eingerostet. Aber die DP ist so aktiv, dass daraus schnell eine komplette Lösung wurde. Die habe ich heute wenigstens erläutert. Jürgen

Hallo juetho,

Ich fand's nur herrlich: Nicht mal eine Woche rum, schon wurde der Code nach Delphi portiert.
Schöne Erklärung des Algorithmus' hast du da aber verfasst.

Beste Grüße,
dN!3L

P.S.:

Ich hatte schon vermutet, daß so ein Zweizeiler nur aus guter Teamarbeit entstanden sein kann. Ich habe jetzt die von Dir angegebene Quelle aufmerksam studiert und nachvollzogen, wie funktionierender Code perfekt optimiert wird. Diskutieren könnte man nur noch über Namensgebung der Funktion. 😁