Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for easter.cs

(view source code of easter.cs as plain text)

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text.RegularExpressions;
  4.  
  5.  
  6. namespace RobvanderWoude
  7. {
  8. 	internal class Easter
  9. 	{
  10. 		static readonly string progver = "1.00";
  11. 		static readonly DateTime referencefullmoon = DateTime.Parse( "2022-01-17 23:48" );
  12. 		static readonly double mooncycleindays = 29.53;
  13.  
  14.  
  15. 		static int Main( string[] args )
  16. 		{
  17. 			int year;
  18. 			string dateformat = "yyyy-MM-dd";
  19.  
  20. 			if ( args.Length == 0 )
  21. 			{
  22. 				year= DateTime.Now.Year;
  23. 			}
  24. 			else if ( args.Length > 2 || !int.TryParse( args[0], out year ) )
  25. 			{
  26. 				return ShowHelp( );
  27. 			}
  28. 			if ( args.Length == 2 )
  29. 			{
  30. 				// date delimiters allowed: hyphen, forward slash, dot or space
  31. 				Regex regex = new Regex( "^(short|long|[dMy/ .-]{6,10})", RegexOptions.IgnoreCase );
  32. 				if ( !regex.IsMatch( args[1] ) )
  33. 				{
  34. 					return ShowHelp( "Invalid date format \"{0}\"", args[1] );
  35. 				}
  36. 				dateformat = args[1].ToLower( ).Replace( 'm', 'M' ).Replace( "/", "'/'" ).Replace( "-", "'-'" ).Replace( ".", "'.'" ).Replace( " ", "' '" );
  37. 			}
  38.  
  39.  
  40. 			// Easter is at first Sunday after the first full moon at or after the Spring equinox (21 March)
  41. 			// Calculation explained: https://www.timeanddate.com/calendar/determining-easter-date.html
  42.  
  43. 			// For Easter calculations, the Spring equinox is always assumed to be at 21 March
  44. 			DateTime springequinox = DateTime.Parse( string.Format( "{0}-03-21", year ) );
  45.  
  46. 			// Calculate full moon cycles to first full moon after Spring equinox of specified year
  47. 			int fullcycles = (int)Math.Ceiling( springequinox.Subtract( referencefullmoon ).Days / mooncycleindays );
  48.  
  49. 			// Date of first full moon after Spring equinox of specified year
  50. 			DateTime fullmoonafterequinox = referencefullmoon.AddDays( fullcycles * mooncycleindays );
  51.  
  52. 			// First Sunday following first full moon at or after Spring equinox of specified year
  53. 			DateTime eastersunday = fullmoonafterequinox.AddDays( 7 - (int)fullmoonafterequinox.DayOfWeek ).Date;
  54.  
  55. 			// Display reasult on screen
  56. 			string wasisorwillbe = "is today,";
  57. 			if ( DateTime.Compare( eastersunday, DateTime.Now.Date ) < 0 )
  58. 			{
  59. 				wasisorwillbe = "was at";
  60. 			}
  61. 			else if ( DateTime.Compare( eastersunday, DateTime.Now.Date ) > 0 )
  62. 			{
  63. 				wasisorwillbe = "will be at";
  64. 			}
  65. 			string easterdatestring;
  66. 			if ( dateformat == "short" )
  67. 			{
  68. 				easterdatestring = eastersunday.ToShortDateString( );
  69. 			}
  70. 			else if ( dateformat == "long" )
  71. 			{
  72. 				easterdatestring = eastersunday.ToLongDateString( );
  73. 			}
  74. 			else
  75. 			{
  76. 				easterdatestring = eastersunday.ToString( dateformat );
  77. 			}
  78. 			Console.WriteLine( "Easter Sunday {0} {1} {2}", year, wasisorwillbe, easterdatestring );
  79.  
  80. 			// Return code equals Easter Sunday's DayOfYear
  81. 			return eastersunday.DayOfYear;
  82. 		}
  83.  
  84.  
  85. 		static int ShowHelp( params string[] errmsg )
  86. 		{
  87. 			#region Error Message
  88.  
  89. 			if ( errmsg.Length > 0 )
  90. 			{
  91. 				List<string> errargs = new List<string>( errmsg );
  92. 				errargs.RemoveAt( 0 );
  93. 				Console.Error.WriteLine( );
  94. 				Console.ForegroundColor = ConsoleColor.Red;
  95. 				Console.Error.Write( "ERROR:\t" );
  96. 				Console.ForegroundColor = ConsoleColor.White;
  97. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  98. 				Console.ResetColor( );
  99. 			}
  100.  
  101. 			#endregion Error Message
  102.  
  103.  
  104. 			#region Help Text
  105.  
  106. 			/*
  107. 			Easter.exe,  Version 1.00
  108. 			Calculate the date of Easter Sunday for the specified year
  109.  
  110. 			Usage:    Easter.exe   [ year  [ format ] ]
  111.  
  112. 			Where:    year         is the year to calculate Easter date for
  113. 			                       (default: current year; see notes for before 100 AD)
  114. 			          format       is the output format for the returned date: either
  115. 			                       "short", "long" or a combination of 6..10 "y", "M",
  116. 			                       "d" characters, hyphens, forward slashes, dots and/or
  117. 			                       spaces (default: "yyyy-MM-dd")
  118.  
  119. 			Notes:    Easter Sunday is at the first Sunday after the first full moon at or
  120. 			          after the Spring equinox, which for Easter calculations is assumed
  121. 			          to be always at March 21.
  122. 			          Years before 100 AD will be interpreted as 2000 + specified year.
  123. 			          The program's return code equals the calculated date's DayOfYear
  124. 			          value, or -1 in case of (command line) errors.
  125.  
  126. 			Credits:  Easter calculation explained:
  127. 			          https://www.timeanddate.com/calendar/determining-easter-date.html
  128. 			          Fix to use alternative date delimiter by Jon Skeet:
  129. 			          https://stackoverflow.com/a/5641084
  130.  
  131.  
  132. 			Written by Rob van der Woude
  133. 			https://www.robvanderwoude.com
  134. 			*/
  135.  
  136. 			#endregion Help Text
  137.  
  138.  
  139. 			#region Display Help Text
  140.  
  141. 			Console.Error.WriteLine( );
  142.  
  143. 			Console.Error.WriteLine( "Easter.exe,  Version {0}", progver );
  144.  
  145. 			Console.Error.WriteLine( "Calculate the date of Easter Sunday for the specified year" );
  146.  
  147. 			Console.Error.WriteLine( );
  148.  
  149. 			Console.Error.Write( "Usage:    " );
  150. 			Console.ForegroundColor = ConsoleColor.White;
  151. 			Console.Error.WriteLine( "Easter.exe   [ year  [ format ] ]" );
  152. 			Console.ResetColor( );
  153.  
  154. 			Console.Error.WriteLine( );
  155.  
  156. 			Console.Error.Write( "Where:    " );
  157. 			Console.ForegroundColor = ConsoleColor.White;
  158. 			Console.Error.Write( "year" );
  159. 			Console.ResetColor( );
  160. 			Console.Error.WriteLine( "         is the year to calculate Easter date for" );
  161.  
  162. 			Console.Error.WriteLine( "                       (default: current year; see notes for before 100 AD)" );
  163.  
  164. 			Console.ForegroundColor = ConsoleColor.White;
  165. 			Console.Error.Write( "          format" );
  166. 			Console.ResetColor( );
  167. 			Console.Error.WriteLine( "       is the output format for the returned date: either" );
  168. 			Console.ResetColor( );
  169.  
  170. 			Console.Error.Write( "                       \"" );
  171. 			Console.ForegroundColor = ConsoleColor.White;
  172. 			Console.Error.Write( "short" );
  173. 			Console.ResetColor( );
  174. 			Console.Error.Write( "\", \"" );
  175. 			Console.ForegroundColor = ConsoleColor.White;
  176. 			Console.Error.Write( "long" );
  177. 			Console.ResetColor( );
  178. 			Console.Error.Write( "\" or a combination of 6..10 \"" );
  179. 			Console.ForegroundColor = ConsoleColor.White;
  180. 			Console.Error.Write( "y" );
  181. 			Console.ResetColor( );
  182. 			Console.Error.Write( "\", \"" );
  183. 			Console.ForegroundColor = ConsoleColor.White;
  184. 			Console.Error.Write( "M" );
  185. 			Console.ResetColor( );
  186. 			Console.Error.WriteLine( "\"," );
  187.  
  188. 			Console.Error.Write( "                       \"" );
  189. 			Console.ForegroundColor = ConsoleColor.White;
  190. 			Console.Error.Write( "d" );
  191. 			Console.ResetColor( );
  192. 			Console.Error.WriteLine( "\" characters, hyphens, forward slashes, dots and/or" );
  193.  
  194. 			Console.Error.Write( "                       spaces (default: \"" );
  195. 			Console.ForegroundColor = ConsoleColor.White;
  196. 			Console.Error.Write( "yyyy-MM-dd" );
  197. 			Console.ResetColor( );
  198. 			Console.Error.WriteLine( "\")" );
  199.  
  200. 			Console.Error.WriteLine( );
  201.  
  202. 			Console.Error.WriteLine( "Notes:    Easter Sunday is at the first Sunday after the first full moon at or" );
  203.  
  204. 			Console.Error.WriteLine( "          after the Spring equinox, which for Easter calculations is assumed" );
  205.  
  206. 			Console.Error.WriteLine( "          to be always at March 21." );
  207.  
  208. 			Console.Error.WriteLine( "          Years before 100 AD will be interpreted as 2000 + specified year." );
  209.  
  210. 			Console.Error.WriteLine( "          The program's return code equals the calculated date's DayOfYear" );
  211.  
  212. 			Console.Error.WriteLine( "          value, or -1 in case of (command line) errors." );
  213.  
  214. 			Console.Error.WriteLine( );
  215.  
  216. 			Console.Error.WriteLine( "Credits:  Easter calculation explained:" );
  217.  
  218. 			Console.ForegroundColor = ConsoleColor.DarkGray;
  219. 			Console.Error.WriteLine( "          https://www.timeanddate.com/calendar/determining-easter-date.html" );
  220. 			Console.ResetColor( );
  221.  
  222. 			Console.Error.WriteLine( );
  223.  
  224. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  225.  
  226. 			Console.Error.WriteLine( "https://www.robvanderwoude.com" );
  227.  
  228. 			#endregion Display Help Text
  229.  
  230.  
  231. 			return -1;
  232. 		}
  233. 	}
  234. }
  235.  

page last modified: 2024-04-16; loaded in 0.0090 seconds