Skip to content

Instantly share code, notes, and snippets.

@fero23
Last active November 2, 2015 03:42
Show Gist options
  • Save fero23/8b103b5d4bff5aed14bd to your computer and use it in GitHub Desktop.
Save fero23/8b103b5d4bff5aed14bd to your computer and use it in GitHub Desktop.
A simple Unix DateTime implementation
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