Last active
November 2, 2015 03:42
-
-
Save fero23/8b103b5d4bff5aed14bd to your computer and use it in GitHub Desktop.
A simple Unix DateTime implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace fero23.DateTime | |
{ | |
public class UnixDateTime | |
{ | |
public enum WeekDays | |
{ | |
Monday = 4, | |
Tuesday = 5, | |
Wednesday = 6, | |
Thursday = 0, | |
Friday = 1, | |
Saturday = 2, | |
Sunday = 3 | |
}; | |
private int[] DaysMonth => | |
new int[] { 31, tsInfo.IsLeapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | |
private uint timestamp; | |
private TimestampInfo tsInfo; | |
public UnixDateTime(uint timestamp) | |
{ | |
this.timestamp = timestamp; | |
tsInfo = new TimestampInfo(timestamp); | |
double days = tsInfo.DaysSinceYearStart + 1; | |
for (int month = 0; ; days -= DaysMonth[month], month++) | |
{ | |
if (days <= DaysMonth[month]) | |
{ | |
Day = (int)days; | |
Month = month + 1; | |
break; | |
} | |
} | |
} | |
public UnixDateTime(DateTime dt) : this((uint)(dt - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds) { } | |
public int Year => 1970 + tsInfo.YearSinceEpoch; | |
public int Day { get; private set; } | |
public int Month { get; private set; } | |
public int Hour => (int)(tsInfo.DaysSinceYearStart % 1 * 24); | |
public int Minutes => (int)(tsInfo.DaysSinceYearStart % 1 * 1440 - Hour * 60); | |
public int Seconds => (int)(tsInfo.DaysSinceYearStart % 1 * 86400 - Hour * 3600 - Minutes * 60); | |
public WeekDays WeekDay => (WeekDays)(tsInfo.DaysSinceEpoch % 7); | |
public override string ToString() => | |
String.Format("{0} {1:D2}-{2:D2}-{3:D2} {4:D2}:{5:D2}:{6:D2}", | |
WeekDay, Year, Month, Day, Hour, Minutes, Seconds); | |
} | |
public class TimestampInfo | |
{ | |
private const int daysPerFourYears = 1461; | |
private const double fourYearsTotalSeconds = 126230400; | |
private const int normalYearTotalSeconds = 31536000; | |
private const int leapYearTotalSeconds = 31622400; | |
private const double dayTotalSeconds = 86400; | |
public TimestampInfo(uint timestamp) | |
{ | |
int timestampWithinInterval = (int)(timestamp % fourYearsTotalSeconds); | |
int yearStartTimestamp = (int)timestamp - timestampWithinInterval; | |
int intervalCount = (int)(timestamp / fourYearsTotalSeconds); | |
for (int i = 0, yearStart = 0, daysFromIntervalStartToYearStart = 0; ; i++) | |
{ | |
int yearTotalSeconds = i == 2 ? leapYearTotalSeconds : normalYearTotalSeconds; | |
if (timestampWithinInterval >= yearStart && timestampWithinInterval < yearStart + yearTotalSeconds) | |
{ | |
IsLeapYear = i == 2; | |
YearSinceEpoch = intervalCount * 4 + i; | |
SecondsSinceYearStart = timestampWithinInterval - yearStart; | |
DaysSinceYearStart = SecondsSinceYearStart / dayTotalSeconds; | |
DaysSinceEpoch = daysPerFourYears * intervalCount + | |
daysFromIntervalStartToYearStart + (int)DaysSinceYearStart; | |
break; | |
} | |
daysFromIntervalStartToYearStart += i == 2 ? 366 : 365; | |
yearStart += yearTotalSeconds; | |
} | |
} | |
public bool IsLeapYear { get; private set; } | |
public int YearSinceEpoch { get; private set; } | |
public int SecondsSinceYearStart { get; private set; } | |
public int DaysSinceEpoch { get; private set; } | |
public double DaysSinceYearStart { get; private set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment