diff --git a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/AdventureTime.csproj b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/AdventureTime.csproj index dba2bee8..054b0d0e 100644 --- a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/AdventureTime.csproj +++ b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/AdventureTime.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.0 + net5.0 diff --git a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Program.cs b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Program.cs index af4efcae..b984c998 100644 --- a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Program.cs +++ b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Program.cs @@ -1,9 +1,81 @@ -namespace AdventureTime +using System; + +namespace AdventureTime { internal class Program { private static void Main() { + var now = Time.WhatTimeIsIt(); + var nowUtc = Time.WhatTimeIsItInUtc(); + + Console.WriteLine($"WhatTimeIsIt: {now}"); + Console.WriteLine($"WhatTimeIsItInUtc: {nowUtc}"); + + Console.WriteLine(); + + foreach (DateTimeKind kind in Enum.GetValues(typeof(DateTimeKind))) + { + Console.WriteLine($"SpecifyKind {kind}: {Time.SpecifyKind(now, kind)}"); + } + + Console.WriteLine(); + + foreach (DateTimeKind kind in Enum.GetValues(typeof(DateTimeKind))) + { + Console.WriteLine($"{kind}:"); + var time = Time.SpecifyKind(now, kind); + var strTime = Time.ToRoundTripFormatString(time); + var parsedTime = Time.ParseFromRoundTripFormat(strTime); + Console.WriteLine($"\tToRoundTripFormatString: {strTime}"); + Console.WriteLine($"\tParseFromRoundTripFormat: {parsedTime}"); + Console.WriteLine($"\tT == ParseFromRoundTripFormat(ToRoundTripFormatString(T)): {Time.ToUtc(time) == Time.ToUtc(parsedTime)}"); + } + + Console.WriteLine(); + + foreach (DateTimeKind kind in Enum.GetValues(typeof(DateTimeKind))) + { + Console.WriteLine($"ToUtc {kind}: {Time.ToUtc(now)}"); + } + + Console.WriteLine(); + + Console.WriteLine($"AddTenSeconds: {Time.AddTenSeconds(now)}"); + Console.WriteLine($"AddTenSecondsV2: {Time.AddTenSecondsV2(now)}"); + + Console.WriteLine(); + + foreach (DateTimeKind kind1 in Enum.GetValues(typeof(DateTimeKind))) + { + foreach (DateTimeKind kind2 in Enum.GetValues(typeof(DateTimeKind))) + { + var dt1 = Time.SpecifyKind(now, kind1); + var dt2 = Time.SpecifyKind(now.AddHours(3), kind2); + Console.WriteLine($"GetHoursBetween {kind1} {kind2}: {Time.GetHoursBetween(dt1, dt2)}"); + } + } + + Console.WriteLine(); + + Console.WriteLine($"GetTotalMinutesInThreeMonths: {Time.GetTotalMinutesInThreeMonths()}"); + + Console.WriteLine(); + + Console.WriteLine($"GetAdventureTimeDurationInMinutes_ver0_Dumb: {Time.GetAdventureTimeDurationInMinutes_ver0_Dumb()}"); + Console.WriteLine($"GetGenderSwappedAdventureTimeDurationInMinutes_ver0_Dumb: {Time.GetGenderSwappedAdventureTimeDurationInMinutes_ver0_Dumb()}"); + Console.WriteLine($"GetAdventureTimeDurationInMinutes_ver1_FeelsSmarter: {Time.GetAdventureTimeDurationInMinutes_ver1_FeelsSmarter()}"); + Console.WriteLine($"GetAdventureTimeDurationInMinutes_ver2_FeelsLikeRocketScience: {Time.GetAdventureTimeDurationInMinutes_ver2_FeelsLikeRocketScience()}"); + Console.WriteLine($"GetGenderSwappedAdventureTimeDurationInMinutes_ver2_FeelsLikeRocketScience: {Time.GetGenderSwappedAdventureTimeDurationInMinutes_ver2_FeelsLikeRocketScience()}"); + Console.WriteLine($"GetAdventureTimeDurationInMinutes_ver3_NodaTime: {Time.GetAdventureTimeDurationInMinutes_ver3_NodaTime()}"); + + Console.WriteLine(); + + var bd1 = Time.ToUtc(now); + var bd2 = Time.ToUtc(now.AddYears(3)); + var bd3 = Time.ToUtc(now.AddMonths(3)); + Console.WriteLine($"AreEqualBirthdays {bd1:d} == {bd2:d}: {Time.AreEqualBirthdays(bd1, bd2)}"); + Console.WriteLine($"AreEqualBirthdays {bd2:d} == {bd3:d}: {Time.AreEqualBirthdays(bd2, bd3)}"); } } } diff --git a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Time.cs b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Time.cs index 45de70d1..8dcb8065 100644 --- a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Time.cs +++ b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Time.cs @@ -14,7 +14,7 @@ internal static class Time /// public static DateTime WhatTimeIsIt() { - throw new NotImplementedException(); + return DateTime.Now; } /// @@ -22,7 +22,7 @@ public static DateTime WhatTimeIsIt() /// public static DateTime WhatTimeIsItInUtc() { - throw new NotImplementedException(); + return DateTime.UtcNow; } /// @@ -36,7 +36,7 @@ public static DateTime SpecifyKind(DateTime dt, DateTimeKind kind) /* Подсказка: поищи в статических методах DateTime. */ - throw new NotImplementedException(); + return DateTime.SpecifyKind(dt, kind); } /// @@ -51,7 +51,7 @@ public static string ToRoundTripFormatString(DateTime dt) Ну и на будущее запомни этот прекрасный строковый формат представления времени - он твой бро! Название запоминать не нужно, просто помни, что для передачи значения в виде строки, выбирать лучше инвариантные относительно сериализации/десериализации форматы. */ - throw new NotImplementedException(); + return dt.ToString("O"); } /// @@ -65,7 +65,7 @@ public static DateTime ParseFromRoundTripFormat(string dtStr) Поиграйся и проверь, что round-trip действительно round-trip, т.е. туда-обратно равно оригиналу (для туда воспользуйся предыдущим методом). Проверь для всех значений DateTime.Kind. */ - throw new NotImplementedException(); + return DateTime.ParseExact(dtStr, "O", null); } /// @@ -77,7 +77,7 @@ public static DateTime ToUtc(DateTime dt) Eсли воспользуешься нужным методом, то напоминаю, что результат его работы зависит от dt.Kind. В случае dt.Kind == Unspecified предполагается, что время локальное, т.е. результат работы в случае Local и Unspecified совпадают. Такие дела */ - throw new NotImplementedException(); + return dt.ToUniversalTime(); } /// @@ -88,7 +88,7 @@ public static DateTime ToUtc(DateTime dt) public static DateTime AddTenSeconds(DateTime dt) { // здесь воспользуйся методами самого объекта и заодно посмотри какие еще похожие есть - throw new NotImplementedException(); + return dt.AddSeconds(10.0); } /// @@ -102,7 +102,7 @@ public static DateTime AddTenSecondsV2(DateTime dt) Ну а здесь воспользуйся сложением с TimeSpan. Обрати внимание, что помимо конструктора, у класса есть набор полезных статических методов-фабрик. Обрати внимание, что у TimeSpan нет статических методов FromMonth, FromYear. Как думаешь, почему? */ - throw new NotImplementedException(); + return dt + TimeSpan.FromSeconds(10.0); } /// @@ -118,7 +118,7 @@ public static int GetHoursBetween(DateTime dt1, DateTime dt2) 2) Проверь, учитывается ли Kind объектов при арифметических операциях. 3) Подумай, почему возвращаемое значение может отличаться от действительности. */ - throw new NotImplementedException(); + return (int) (dt2 - dt1).TotalHours; } /// @@ -127,7 +127,8 @@ public static int GetHoursBetween(DateTime dt1, DateTime dt2) public static int GetTotalMinutesInThreeMonths() { // ну тут все просто и очевидно, если сделал остальные и подумал над вопросами в комментах. - throw new NotImplementedException(); + var now = DateTime.UtcNow; + return (int) (now.AddMonths(3) - now).TotalMinutes; } #region Adventure time saga @@ -147,7 +148,10 @@ public static int GetAdventureTimeDurationInMinutes_ver0_Dumb() Держи, заготовочку для копипасты: - 2010, 3, 28, 2, 15, 0 */ - throw new NotImplementedException(); + var begin = new DateTimeOffset(2010, 3, 28, 2, 15, 0, TimeSpan.FromHours(3)); + var end = new DateTimeOffset(2010, 3, 28, 2, 15, 0, TimeSpan.FromHours(0)); + + return (int) end.Subtract(begin).TotalMinutes; } /// @@ -165,7 +169,10 @@ public static int GetGenderSwappedAdventureTimeDurationInMinutes_ver0_Dumb() - 2010, 3, 28, 3, 15, 0 - 2010, 3, 28, 1, 15, 0 */ - throw new NotImplementedException(); + var begin = new DateTimeOffset(2010, 3, 28, 3, 15, 0, TimeSpan.FromHours(3)); + var end = new DateTimeOffset(2010, 3, 28, 1, 15, 0, TimeSpan.FromHours(0)); + + return (int) end.Subtract(begin).TotalMinutes; } /// @@ -180,7 +187,10 @@ public static int GetAdventureTimeDurationInMinutes_ver1_FeelsSmarter() На самом деле смещения таковы: Лондон +1 (BST - British Summer Time), Москва +4 (MSD - Moscow Daylight Time). Давай теперь учтем правильное смещение. Я понимаю, что это очевидно, что результат не изменится, но тебе же не сложно скопипастить и просто поменять смещения? */ - throw new NotImplementedException(); + var begin = new DateTimeOffset(2010, 3, 28, 2, 15, 0, TimeSpan.FromHours(4)); + var end = new DateTimeOffset(2010, 3, 28, 2, 15, 0, TimeSpan.FromHours(1)); + + return (int) end.Subtract(begin).TotalMinutes; } // GetGenderSwappedAdventureTimeDurationInMinutes_ver1_FeelsSmarter опустим, там то же самое @@ -202,10 +212,13 @@ public static int GetAdventureTimeDurationInMinutes_ver2_FeelsLikeRocketScience( ниже ты найдешь готовый метод GetZonedTime. Просто посмотри на него (можешь даже посмотреть методы и свойства типа TimeZoneInfo, если интересно) и воспользуйся им для вычисления правильного времени "отбытия" и "прибытия" наших героев. Затем посчитай длительность путешествия. Также даны правильные идентификаторы зон. */ - const string moscowZoneId = "Russian Standard Time"; - const string londonZoneId = "GMT Standard Time"; + const string moscowZoneId = "Europe/Moscow"; + const string londonZoneId = "Europe/London"; - throw new NotImplementedException(); + var begin = GetZonedTime(new DateTime(2010, 3, 28, 2, 15, 0), moscowZoneId); + var end = GetZonedTime(new DateTime(2010, 3, 28, 2, 15, 0), londonZoneId);; + + return (int) end.Subtract(begin).TotalMinutes; } /// @@ -216,9 +229,13 @@ public static int GetGenderSwappedAdventureTimeDurationInMinutes_ver2_FeelsLikeR /* Реши по аналогии с предыдущим методом и проверь, что оба метода действительно возвращают одно и то же время (и что оно правильное). */ - const string moscowZoneId = "Russian Standard Time"; - const string londonZoneId = "GMT Standard Time"; - throw new NotImplementedException(); + const string moscowZoneId = "Europe/Moscow"; + const string londonZoneId = "Europe/London"; + + var begin = GetZonedTime(new DateTime(2010, 3, 28, 3, 15, 0), moscowZoneId); + var end = GetZonedTime(new DateTime(2010, 3, 28, 1, 15, 0), londonZoneId);; + + return (int) end.Subtract(begin).TotalMinutes; } private static DateTimeOffset GetZonedTime(DateTime localTime, string timeZoneId) @@ -277,7 +294,12 @@ private static ZonedDateTime GetZonedTime(LocalDateTime localTime, string timeZo /// True - если родились в один день, иначе - false. internal static bool AreEqualBirthdays(DateTime person1Birthday, DateTime person2Birthday) { - throw new NotImplementedException(); + if (person1Birthday.Kind != DateTimeKind.Utc || person2Birthday.Kind != DateTimeKind.Utc) + { + throw new ArgumentException("person1Birthday.Kind and person2Birthday.Kind must be DateTimeKind.Utc"); + } + + return person1Birthday.Month == person2Birthday.Month && person1Birthday.Day == person2Birthday.Day; } } }