1. C# / Говнокод #8439

    +124

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    public static DateTime Sec2Date( UInt32 time )
    {
    	UInt32[] days_per_month = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    	int[] days_per_year = { 366, 365, 365, 365 };
    	UInt32 hour = (UInt32)((time / 3600) % 24);
    	UInt32 min = (UInt32)((time / 60) % 60);
    	UInt32 sec = (UInt32)(time % 60);
    	// в 4-х годах 1461 день, значит в 1 годе 1461/4=365.25 дней в среднем в году
    	//UInt32 year = (UInt32)(time / (24f * 3600f * 365.25));
    
    	int time_temp = (int)time;
    	int year_temp = 0;
    	do
    	{
    		time_temp -= 24 * 3600 * days_per_year[year_temp % 4];
    		year_temp++;
    	}
    	while ( time_temp > 0 );
    	int year = year_temp - 1;
    
    	// кол-во_секунд_с_начала_года = общее_кол-во_секунд - кол-во_секунд_до_начала_года_с_0_года
    	UInt32 sec_after_curr_year = time - Date2Sec( (int)year, 1, 1, 0, 0, 0 );
    	// кол-во дней, прошедших с начала года
    	UInt32 day = (UInt32)(sec_after_curr_year / (3600 * 24) + 1);
    	// день недели
    	UInt32 week = day % 7;
    	// в феврале високосного года делаем 29 дней
    	if ( 0 == (year % 4) )
    		days_per_month[1] = 29;
    	// из общего кол-во дней будем вычитать дни месяцев, получим месяц и день в месяце
    	UInt32 month = 0;
    	while ( day > days_per_month[month] ) day -= days_per_month[month++];
    	month++;
    	DateTime date = new DateTime( (int)(year + 2000), (int)month, (int)day, (int)hour, (int)min, (int)sec );
    	return date;
    }
    
    public static UInt32 Date2Sec( int Y, int M, int D, int hh, int mm, int ss )
    {
    	DateTime date = new DateTime( Y + 2000, M, D, hh, mm, ss );
    	return Date2Sec( date );
    }
    
    public static UInt32 Date2Sec( DateTime date )
    {
    	int[] days_per_month = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    	int[] days_per_year = { 366, 365, 365, 365 };
    
    	UInt32 sec_monthes = 0;
    	for ( int i = 0; i < (date.Month - 1); i++ )
    		sec_monthes += (UInt32)(days_per_month[i] * 24 * 3600);
    	if ( (2 < date.Month) && (0 == (date.Year % 4)) )
    		sec_monthes += 24 * 3600;		// 29 февраля
    	UInt32 sec_days = (UInt32)((date.Day - 1) * 24 * 3600);
    	UInt32 sec_hours = (UInt32)(date.Hour * 3600);
    	UInt32 sec_minutes = (UInt32)(date.Minute * 60);
    	UInt32 sec_years = 0;
    	for ( int i = 0; i < (date.Year - 2000); i++ )
    		sec_years += (UInt32)(days_per_year[i % 4] * 24 * 3600);
    	UInt32 total_sec = (UInt32)(sec_years + sec_monthes + sec_days + sec_hours + sec_minutes + date.Second);
    	return total_sec;
    }

    Время измеряется в секундах, прошедших с 00:00:00 01.01.2000.

    Запостил: ivan-petrov, 07 Ноября 2011

    Комментарии (27) RSS

    • Чаще, конечно выполняется, Sec2Date и, ЧСХ, работает! Но при 0 <= time <= (2.147.483.647 + 31.622.400), потом эксепшен (15 и 22 строчка)!
      Ответить
    • афигеть вечный календарь
      Ответить
    • private static const DateTime y2k = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
      
      public static DateTime Sec2Date(UInt32 time)
      {
          return new DateTime(y2k.Ticks + (time * 10000000L), DateTimeKind.Utc);
      }
      
      public static UInt32 Date2Sec(DateTime date)
      {
          return (uint) ((date.Ticks - y2k.Ticks) / 10000000L);
      }
      Ответить
    • умершие племена майа смотрят на вас с завистью...
      Ответить
    • Вот это путь. PHP->Java,C#
      Ответить
    • Время измеряется в секундах, прошедших с 00:00:00 01.01.2000.

      О эта чудная новая эпоха!

      Как насчёт проблемы-2136?
      Ответить
      • Для решения прикладной задачи такого календаря вполне хватает. А то что программа через сотню с хвостиком лет перестанет правильно работать - это не баг, это фича­­(с).
        Ответить
        • А стандартных функций для работы с Unix time (время в секундах с начала эпохи — 1 января 1970 года) для прикладной задачи не хватает? Или в C# их нет? Что, и стандартных функций/классов для работы с григорианским календарём нет?
          Ответить
      • J2000.0 code monkey edition
        Ответить
    • Проверка на високосность неправильная. Забыли про кратность 100 и не кратность 400.
      Ответить

    Добавить комментарий