HomeForumSourceResearchGuide
Sign in to contribute to source. how it works
Component time.TimeUnix by barry
expand copy to clipboardexpand
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
		}
	
	}
Revision history
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.
Version 1 by barry