HomeForumSourceResearchGuide
Sign in to contribute to source. how it works
Component time.DateUtil by barry
expand copy to clipboardexpand
// DateUtil.dn
// Roberto Rodrigues Filho
// September, 2015

component provides time.DateUtil requires io.Output out, data.IntUtil iu, data.StringUtil stringUtil {
	byte	MAX_DAY_LEAP[] 	= new byte[](31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
	byte	MAX_DAY[]	= new byte[](31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)

	char formatDefault[] = "YYYY/MM/DD HH:MN:SS.MIL"

	bool DateUtil:before(DateTime first, DateTime second) {
		if (equal(first, second)) {
			return false
		}

		if (first.year < second.year) {
			return true
		} else if (first.year > second.year) {
			return false
		}

		if (first.month < second.month) {
			return true
		} else if (first.month > second.month) {
			return false
		}

		if (first.day < second.day) {
			return true
		} else if (first.day > second.day) {
			return false
		}

		if (first.hour < second.hour) {
			return true
		} else if (first.hour > second.hour) {
			return false
		}

		if (first.minute < second.minute) {
			return true
		} else if (first.minute > second.minute) {
			return false
		}

		if (first.second < second.second) {
			return true
		} else if (first.second > second.second) {
			return false
		}

		if (first.millisecond < second.millisecond) {
			return true
		}

		return false
	}

	bool DateUtil:equal(DateTime first, DateTime second) {
		if (first.millisecond != second.millisecond) {
			return false
		}

		if (first.second != second.second) {
			return false
		}

		if (first.minute != second.minute) {
			return false
		}

		if (first.hour != second.hour) {
			return false
		}

		if (first.day != second.day) {
			return false
		}

 		if (first.month != second.month) {
 			return false
 		}

 		if (first.year != second.year) {
 			return false
 		}

		return true
	}

	bool DateUtil:after(DateTime first, DateTime second) {
		if (!equal(first, second)) {
			if (!before(first, second)) {
				return true
			}
		}
		
		return false
	}

	bool isLeap(int16 year) {
		if ((year % 4) == 0) {
			if ((year % 100) == 0) {
				if ((year % 400) == 0) {
					return true
				}
			} else {
				return true
			}
		}

		return false
	}

	DateTime normaliseMSEC(DateTime second) {
		if (second.second == 0) {
			second = normaliseSEC(second)
		}

		second.second 		= second.second      - 1
		second.millisecond 	= second.millisecond + DateUtil.MAX_MSEC

		return second
	}

	DateTime normaliseSEC(DateTime second) {
		if (second.minute == 0) {
			second = normaliseMIN(second)
		}

		second.minute = second.minute - 1
		second.second = second.second + DateUtil.MAX_SEC

		return second
	}

	DateTime normaliseMIN(DateTime second) {
		if (second.hour == 0 ) {
			second = normaliseDAY(second)
		}

		second.hour   = second.hour    - 1
		second.minute = second.minute  + DateUtil.MAX_MIN

		return second
	}

	DateTime normaliseHOUR(DateTime second) {
		second.day = second.day - 1
		
		if (second.day == 0) {
			second = normaliseDAY(second)
		}

		second.hour = second.hour + DateUtil.MAX_HOUR

		return second
	}

	DateTime normaliseDAY(DateTime second) {
		second.month = second.month - 1
		
		if (second.month == 0) {
			second = normaliseMONTH(second)
		}

		if (isLeap(second.year)) {
			second.day = second.day + MAX_DAY_LEAP[second.month]
		} else {
			second.day = second.day + MAX_DAY[second.month]
		}

		return second
	}

	DateTime normaliseMONTH(DateTime second) {
		second.year  = second.year  - 1
		second.month = second.month + DateUtil.MAX_MONTH

		return second
	}

	DateTime calcDiff(DateTime first, DateTime second) {
		DateTime diff = new DateTime()

		if (second.millisecond < first.millisecond) {
			second = normaliseMSEC(second)
		}

		if (second.second < first.second) {
			second = normaliseSEC(second)
		}

		if (second.minute < first.minute) {
			second = normaliseMIN(second)
		}

		if (second.hour < first.hour) {
			second = normaliseHOUR(second)
		}

		if (second.day < first.day) {
			second = normaliseDAY(second)
		}

		if (second.month < first.month) {
			second = normaliseMONTH(second)
		}

		diff.year 		 = second.year        - first.year
		diff.month 		 = second.month       - first.month
		diff.day 		 = second.day         - first.day
		diff.hour		 = second.hour        - first.hour
		diff.minute  	 = second.minute      - first.minute
		diff.second		 = second.second      - first.second
		diff.millisecond  = second.millisecond - first.millisecond

		return diff
	}

	DateTime DateUtil:diff(DateTime f, DateTime s) {
		DateTime first  = clone f
		DateTime second = clone s

		if (equal(first, second)) {
			return new DateTime()
		}

		if (after(first, second)) {
			return calcDiff(second, first)
		}

		return calcDiff(first, second)
	}

	int DateUtil:toMilliseconds(DateTime date) {
		int result = 0

		result = date.millisecond
		result = result + (date.second  * 1000	 )
		result = result + (date.minute  * 60000  )
		result = result + (date.hour	* 3600000)

		return result
	}

	char[] makeFixedWidthIntString(int v, int len)
		{
		char result[] = v.makeString()
		while (result.arrayLength < len) result = "0$result"
		return result
		}

	char[] DateUtil:makeString(DateTime d, opt char format[])
		{
		char result[]

		if (format != null)
			result = clone format
			else
			result = clone formatDefault

		int pos = 0

		if ((pos = result.find("YYYY")) != StringUtil.NOT_FOUND)
			{
			char str[] = d.year.makeString()

			result[pos] = str[0]
			result[pos+1] = str[1]
			result[pos+2] = str[2]
			result[pos+3] = str[3]
			}
		
		if ((pos = result.find("MM")) != StringUtil.NOT_FOUND)
			{
			char str[] = makeFixedWidthIntString(d.month, 2)

			result[pos] = str[0]
			result[pos+1] = str[1]
			}
		
		if ((pos = result.find("DD")) != StringUtil.NOT_FOUND)
			{
			char str[] = makeFixedWidthIntString(d.day, 2)

			result[pos] = str[0]
			result[pos+1] = str[1]
			}
		
		if ((pos = result.find("HH")) != StringUtil.NOT_FOUND)
			{
			char str[] = makeFixedWidthIntString(d.hour, 2)

			result[pos] = str[0]
			result[pos+1] = str[1]
			}
		
		if ((pos = result.find("MN")) != StringUtil.NOT_FOUND)
			{
			char str[] = makeFixedWidthIntString(d.minute, 2)

			result[pos] = str[0]
			result[pos+1] = str[1]
			}
		
		if ((pos = result.find("SS")) != StringUtil.NOT_FOUND)
			{
			char str[] = makeFixedWidthIntString(d.second, 2)

			result[pos] = str[0]
			result[pos+1] = str[1]
			}
		
		if ((pos = result.find("MIL")) != StringUtil.NOT_FOUND)
			{
			char str[] = makeFixedWidthIntString(d.millisecond, 3)

			result[pos] = str[0]
			result[pos+1] = str[1]
			result[pos+2] = str[2]
			}

		return result
		}
}
Revision history
To propose a new revision to this entity, use dana source put -uc your/new/version.dn -n time.DateUtil -m "reason for update" -u yourUsername
Version 1 (this version) by barry
Notes for this version: Standard Library Initialisation