Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- class Date
- {
- public enum Month
- {
- Jan = 0,
- Feb,
- Mar,
- Apr,
- May,
- Jun,
- Jul,
- Aug,
- Sep,
- Oct,
- Nov,
- Dec
- };
- private int year;
- private int month;
- private int day;
- public Date()
- {
- year = 1980;
- month = (int)Month.Jan;
- day = 0;
- }
- public Date(int year, int month, int day)
- {
- if (year < 0)
- {
- throw new System.ArgumentOutOfRangeException("Year should be non-negative");
- }
- if (day <= 0 || day > 365)
- {
- throw new System.ArgumentOutOfRangeException("Bad day range");
- }
- this.year = year;
- this.month = month;
- this.day = day;
- }
- ~Date()
- {
- // Nothing to release
- }
- public int GetYear() { return year; }
- public int GetMonth() { return month; }
- public int GetDay() { return day; }
- private static int DaysPerMonth(int mon)
- {
- switch ((Month)mon)
- {
- case Month.Jan: return 31;
- case Month.Feb: return 28;
- case Month.Mar: return 31;
- case Month.Apr: return 30;
- case Month.May: return 31;
- case Month.Jun: return 30;
- case Month.Jul: return 31;
- case Month.Aug: return 31;
- case Month.Sep: return 30;
- case Month.Oct: return 31;
- case Month.Nov: return 30;
- case Month.Dec: return 31;
- default: throw new System.IndexOutOfRangeException();
- };
- }
- private const ulong SecondsPerDay = 86400;
- private ulong ToSeconds()
- {
- ulong res = (ulong)year * SecondsPerDay * 365;
- res += (((ulong)year / 4) * SecondsPerDay); // Include 1 day per leap year
- for (int i = 0; i < month; ++i)
- {
- res += (ulong)DaysPerMonth(i) * SecondsPerDay;
- }
- res += (ulong)day * SecondsPerDay;
- return res;
- }
- private Date FromSeconds(ulong seconds)
- {
- // We don't know how many leap years are encoded here
- // But we know that each 4 years have 1 leap year, so we can use total number of seconds _per 4 years_
- int yearBy4 = (int)(seconds / (SecondsPerDay * (365 * 4 + 1)));
- seconds -= (ulong)yearBy4 * (SecondsPerDay * (365 * 4 + 1));
- // Remaining years not divisible by 4. Non-leap by definition
- int remainingYear = (int)(seconds / (SecondsPerDay * 365));
- seconds -= (ulong)remainingYear * SecondsPerDay * 365;
- int year = yearBy4 * 4 + remainingYear;
- int month = 0;
- for (int i = 0; i < (int)Month.Dec; ++i)
- {
- ulong secondsInMonth = (ulong)DaysPerMonth(i) * SecondsPerDay;
- if (seconds >= secondsInMonth)
- {
- seconds -= secondsInMonth;
- month++;
- } else
- {
- break;
- }
- }
- int day = (int)(seconds / SecondsPerDay);
- return new Date(year, month, day);
- }
- public Date AddDays(int days)
- {
- if (days > 31)
- {
- throw new System.ArgumentOutOfRangeException();
- }
- return FromSeconds(ToSeconds() + ((ulong)days * SecondsPerDay));
- }
- public static bool operator == (Date a, Date b)
- {
- return a.ToSeconds() == b.ToSeconds();
- }
- public static bool operator != (Date a, Date b)
- {
- return !(a == b);
- }
- public static Date operator - (Date a, Date b)
- {
- ulong a_sec = a.ToSeconds();
- ulong b_sec = b.ToSeconds();
- if (a_sec < b_sec)
- {
- throw new System.ArgumentOutOfRangeException();
- }
- Date res = new Date();
- return res.FromSeconds(a_sec - b_sec);
- }
- // DD:MM:YYYY
- public static Date ReadFromConsole()
- {
- string[] elements = Console.ReadLine().Split(':');
- if (elements.Count() != 3)
- {
- Console.WriteLine("Bad date format");
- throw new System.InvalidProgramException();
- }
- int day = int.Parse(elements[0]);
- int month = int.Parse(elements[1]);
- int year = int.Parse(elements[2]);
- // Constructor will validate arguments
- return new Date(year, month, day);
- }
- public int NumberOfMatches(List<Date> dates, Date key)
- {
- int res = 0;
- foreach (Date d in dates)
- {
- if(d == key)
- {
- ++res;
- }
- }
- return res;
- }
- public void WriteToConsole()
- {
- Console.WriteLine("{0}:{1}:{2}", day, month, year);
- }
- };
- class App
- {
- static void Main(string[] args)
- {
- global::Date date = new global::Date(2018, 6, 23);
- date.WriteToConsole();
- global::Date added = date.AddDays(1);
- added.WriteToConsole();
- Debug.Assert(date != added);
- Debug.Assert(date.GetYear() == added.GetYear());
- Debug.Assert(date.GetMonth() == added.GetMonth());
- Debug.Assert(date.GetDay() == added.GetDay() - 1);
- Console.ReadKey();
- }
- }
Add Comment
Please, Sign In to add comment