const int EPOCH_YEAR = 1970
const int EPOCH_MONTH = 1
const int DAYS_YEAR = 365
const int DAYS_LEAP_YEAR = 366
const int SECONDS_PER_DAY = 86400
const int SECONDS_PER_HOUR = 3600
const int SECONDS_PER_MINUTE = 60
component provides TimeUnix requires io.Output out, data.IntUtil iu {
int month_days[] = new int[](31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
int leap_month_days[] = new int[](31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
bool isLeapYear(int year)
{
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)
}
int daysInYear(int year)
{
if (isLeapYear(year))
return DAYS_LEAP_YEAR
else
return DAYS_YEAR
}
int TimeUnix:toUnixTime(DateTime dt)
{
int year = dt.year
int month = dt.month
if (year < 1970) throw new Exception("Unix time cannot represent years before 1970")
int seconds = 0
int mdays[] = month_days
if (isLeapYear(year)) mdays = leap_month_days
int xdays = 0
while (month > EPOCH_MONTH)
{
seconds += (mdays[month] * SECONDS_PER_DAY)
xdays += mdays[month]
month --
}
while (year > EPOCH_YEAR)
{
seconds += (daysInYear(year) * SECONDS_PER_DAY)
year --
}
seconds += ((dt.day-1) * SECONDS_PER_DAY)
seconds += dt.hour * SECONDS_PER_HOUR
seconds += dt.minute * SECONDS_PER_MINUTE
seconds += dt.second
return seconds
}
//Unix time is the number of seconds which have elapsed since 01/01/1970
DateTime TimeUnix:fromUnixTime(int time)
{
//we first separate out the days from the seconds
int days = time / 86400
int rsecs = time % 86400
//we now need to convert the days into years, months, and days; because Unix time is relative to a fixed point, this calculation is complicated by leap years
int year = EPOCH_YEAR
while (days > daysInYear(year))
{
days -= daysInYear(year)
year ++
}
int mdays[] = month_days
if (isLeapYear(year)) mdays = leap_month_days
int month = EPOCH_MONTH
while (days > mdays[month])
{
days -= mdays[month]
month ++
}
days ++
DateTime result = new DateTime()
result.year = year
result.month = month
result.day = days
result.hour = rsecs / 3600
result.minute = rsecs / 60 % 60
result.second = rsecs % 60
return result
}
}To propose a new revision to this entity, use dana source put -uc your/new/version.dn -n time.TimeUnix -m "reason for update" -u yourUsername
Version 2 (this version) by barry
Notes for this version: Fixes to calculations, and general clarity improvements.