PeriodicRollingCalendar.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using System;
  2. // ReSharper disable InconsistentNaming
  3. namespace winsw
  4. {
  5. /**
  6. * This is largely borrowed from the logback Rolling Calendar.
  7. **/
  8. public class PeriodicRollingCalendar
  9. {
  10. private readonly string _format;
  11. private readonly long _period;
  12. private DateTime _currentRoll;
  13. private DateTime _nextRoll;
  14. public PeriodicRollingCalendar(string format, long period)
  15. {
  16. _format = format;
  17. _period = period;
  18. _currentRoll = DateTime.Now;
  19. }
  20. public void init()
  21. {
  22. periodicityType = determinePeriodicityType();
  23. _nextRoll = nextTriggeringTime(_currentRoll, _period);
  24. }
  25. public enum PeriodicityType
  26. {
  27. ERRONEOUS, TOP_OF_MILLISECOND, TOP_OF_SECOND, TOP_OF_MINUTE, TOP_OF_HOUR, TOP_OF_DAY
  28. }
  29. private static readonly PeriodicityType[] VALID_ORDERED_LIST = {
  30. PeriodicityType.TOP_OF_MILLISECOND, PeriodicityType.TOP_OF_SECOND, PeriodicityType.TOP_OF_MINUTE, PeriodicityType.TOP_OF_HOUR, PeriodicityType.TOP_OF_DAY
  31. };
  32. private PeriodicityType determinePeriodicityType()
  33. {
  34. PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(_format, _period);
  35. DateTime epoch = new DateTime(1970, 1, 1);
  36. foreach (PeriodicityType i in VALID_ORDERED_LIST)
  37. {
  38. string r0 = epoch.ToString(_format);
  39. periodicRollingCalendar.periodicityType = i;
  40. DateTime next = periodicRollingCalendar.nextTriggeringTime(epoch, 1);
  41. string r1 = next.ToString(_format);
  42. if (r0 != null && r1 != null && !r0.Equals(r1))
  43. {
  44. return i;
  45. }
  46. }
  47. return PeriodicityType.ERRONEOUS;
  48. }
  49. private DateTime nextTriggeringTime(DateTime input, long increment)
  50. {
  51. DateTime output;
  52. switch (periodicityType)
  53. {
  54. case PeriodicityType.TOP_OF_MILLISECOND:
  55. output = new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second, input.Millisecond);
  56. output = output.AddMilliseconds(increment);
  57. return output;
  58. case PeriodicityType.TOP_OF_SECOND:
  59. output = new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second);
  60. output = output.AddSeconds(increment);
  61. return output;
  62. case PeriodicityType.TOP_OF_MINUTE:
  63. output = new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, 0);
  64. output = output.AddMinutes(increment);
  65. return output;
  66. case PeriodicityType.TOP_OF_HOUR:
  67. output = new DateTime(input.Year, input.Month, input.Day, input.Hour, 0, 0);
  68. output = output.AddHours(increment);
  69. return output;
  70. case PeriodicityType.TOP_OF_DAY:
  71. output = new DateTime(input.Year, input.Month, input.Day);
  72. output = output.AddDays(increment);
  73. return output;
  74. default:
  75. throw new Exception("invalid periodicity type: " + periodicityType);
  76. }
  77. }
  78. public PeriodicityType periodicityType { get; set; }
  79. public Boolean shouldRoll
  80. {
  81. get
  82. {
  83. DateTime now = DateTime.Now;
  84. if (now > _nextRoll)
  85. {
  86. _currentRoll = now;
  87. _nextRoll = nextTriggeringTime(now, _period);
  88. return true;
  89. }
  90. return false;
  91. }
  92. }
  93. public string format
  94. {
  95. get
  96. {
  97. return _currentRoll.ToString(_format);
  98. }
  99. }
  100. }
  101. }