forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			257 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			257 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
|  | /* | ||
|  |  * Copyright (C)2005-2019 Haxe Foundation | ||
|  |  * | ||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a | ||
|  |  * copy of this software and associated documentation files (the "Software"), | ||
|  |  * to deal in the Software without restriction, including without limitation | ||
|  |  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
|  |  * and/or sell copies of the Software, and to permit persons to whom the | ||
|  |  * Software is furnished to do so, subject to the following conditions: | ||
|  |  * | ||
|  |  * The above copyright notice and this permission notice shall be included in | ||
|  |  * all copies or substantial portions of the Software. | ||
|  |  * | ||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
|  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
|  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
|  |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
|  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
|  |  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
|  |  * DEALINGS IN THE SOFTWARE. | ||
|  |  */ | ||
|  | 
 | ||
|  | /** | ||
|  | 	The DateTools class contains some extra functionalities for handling `Date` | ||
|  | 	instances and timestamps. | ||
|  | 
 | ||
|  | 	In the context of Haxe dates, a timestamp is defined as the number of | ||
|  | 	milliseconds elapsed since 1st January 1970. | ||
|  | **/ | ||
|  | class DateTools { | ||
|  | 	#if php | ||
|  | 	#elseif (neko && !(macro || interp)) | ||
|  | 	static var date_format = neko.Lib.load("std", "date_format", 2); | ||
|  | 	#else | ||
|  | 	static var DAY_SHORT_NAMES = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; | ||
|  | 	static var DAY_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; | ||
|  | 	static var MONTH_SHORT_NAMES = [ | ||
|  | 		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" | ||
|  | 	]; | ||
|  | 	static var MONTH_NAMES = [ | ||
|  | 		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" | ||
|  | 	]; | ||
|  | 
 | ||
|  | 	private static function __format_get(d:Date, e:String):String { | ||
|  | 		return switch (e) { | ||
|  | 			case "%": | ||
|  | 				"%"; | ||
|  | 			case "a": | ||
|  | 				DAY_SHORT_NAMES[d.getDay()]; | ||
|  | 			case "A": | ||
|  | 				DAY_NAMES[d.getDay()]; | ||
|  | 			case "b", "h": | ||
|  | 				MONTH_SHORT_NAMES[d.getMonth()]; | ||
|  | 			case "B": | ||
|  | 				MONTH_NAMES[d.getMonth()]; | ||
|  | 			case "C": | ||
|  | 				StringTools.lpad(Std.string(Std.int(d.getFullYear() / 100)), "0", 2); | ||
|  | 			case "d": | ||
|  | 				StringTools.lpad(Std.string(d.getDate()), "0", 2); | ||
|  | 			case "D": | ||
|  | 				__format(d, "%m/%d/%y"); | ||
|  | 			case "e": | ||
|  | 				Std.string(d.getDate()); | ||
|  | 			case "F": | ||
|  | 				__format(d, "%Y-%m-%d"); | ||
|  | 			case "H", "k": | ||
|  | 				StringTools.lpad(Std.string(d.getHours()), if (e == "H") "0" else " ", 2); | ||
|  | 			case "I", "l": | ||
|  | 				var hour = d.getHours() % 12; | ||
|  | 				StringTools.lpad(Std.string(hour == 0 ? 12 : hour), if (e == "I") "0" else " ", 2); | ||
|  | 			case "m": | ||
|  | 				StringTools.lpad(Std.string(d.getMonth() + 1), "0", 2); | ||
|  | 			case "M": | ||
|  | 				StringTools.lpad(Std.string(d.getMinutes()), "0", 2); | ||
|  | 			case "n": | ||
|  | 				"\n"; | ||
|  | 			case "p": | ||
|  | 				if (d.getHours() > 11) "PM"; else "AM"; | ||
|  | 			case "r": | ||
|  | 				__format(d, "%I:%M:%S %p"); | ||
|  | 			case "R": | ||
|  | 				__format(d, "%H:%M"); | ||
|  | 			case "s": | ||
|  | 				Std.string(Std.int(d.getTime() / 1000)); | ||
|  | 			case "S": | ||
|  | 				StringTools.lpad(Std.string(d.getSeconds()), "0", 2); | ||
|  | 			case "t": | ||
|  | 				"\t"; | ||
|  | 			case "T": | ||
|  | 				__format(d, "%H:%M:%S"); | ||
|  | 			case "u": | ||
|  | 				var t = d.getDay(); | ||
|  | 				if (t == 0) "7" else Std.string(t); | ||
|  | 			case "w": | ||
|  | 				Std.string(d.getDay()); | ||
|  | 			case "y": | ||
|  | 				StringTools.lpad(Std.string(d.getFullYear() % 100), "0", 2); | ||
|  | 			case "Y": | ||
|  | 				Std.string(d.getFullYear()); | ||
|  | 			default: | ||
|  | 				throw new haxe.exceptions.NotImplementedException("Date.format %" + e + "- not implemented yet."); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	private static function __format(d:Date, f:String):String { | ||
|  | 		var r = new StringBuf(); | ||
|  | 		var p = 0; | ||
|  | 		while (true) { | ||
|  | 			var np = f.indexOf("%", p); | ||
|  | 			if (np < 0) | ||
|  | 				break; | ||
|  | 
 | ||
|  | 			r.addSub(f, p, np - p); | ||
|  | 			r.add(__format_get(d, f.substr(np + 1, 1))); | ||
|  | 
 | ||
|  | 			p = np + 2; | ||
|  | 		} | ||
|  | 		r.addSub(f, p, f.length - p); | ||
|  | 		return r.toString(); | ||
|  | 	} | ||
|  | 	#end | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Format the date `d` according to the format `f`. The format is | ||
|  | 		compatible with the `strftime` standard format, except that there is no | ||
|  | 		support in Flash and JS for day and months names (due to lack of proper | ||
|  | 		internationalization API). On Haxe/Neko/Windows, some formats are not | ||
|  | 		supported. | ||
|  | 
 | ||
|  | 		```haxe | ||
|  | 		var t = DateTools.format(Date.now(), "%Y-%m-%d_%H:%M:%S"); | ||
|  | 		// 2016-07-08_14:44:05 | ||
|  | 
 | ||
|  | 		var t = DateTools.format(Date.now(), "%r"); | ||
|  | 		// 02:44:05 PM | ||
|  | 
 | ||
|  | 		var t = DateTools.format(Date.now(), "%T"); | ||
|  | 		// 14:44:05 | ||
|  | 
 | ||
|  | 		var t = DateTools.format(Date.now(), "%F"); | ||
|  | 		// 2016-07-08 | ||
|  | 		``` | ||
|  | 	**/ | ||
|  | 	public static function format(d:Date, f:String):String { | ||
|  | 		#if (neko && !(macro || interp)) | ||
|  | 		return new String(untyped date_format(d.__t, f.__s)); | ||
|  | 		#elseif php | ||
|  | 		return php.Global.strftime(f, php.Syntax.int(@:privateAccess d.__t)); | ||
|  | 		#else | ||
|  | 		return __format(d, f); | ||
|  | 		#end | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Returns the result of adding timestamp `t` to Date `d`. | ||
|  | 
 | ||
|  | 		This is a convenience function for calling | ||
|  | 		`Date.fromTime(d.getTime() + t)`. | ||
|  | 	**/ | ||
|  | 	public static inline function delta(d:Date, t:Float):Date { | ||
|  | 		return Date.fromTime(d.getTime() + t); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	static var DAYS_OF_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Returns the number of days in the month of Date `d`. | ||
|  | 
 | ||
|  | 		This method handles leap years. | ||
|  | 	**/ | ||
|  | 	public static function getMonthDays(d:Date):Int { | ||
|  | 		var month = d.getMonth(); | ||
|  | 		var year = d.getFullYear(); | ||
|  | 
 | ||
|  | 		if (month != 1) | ||
|  | 			return DAYS_OF_MONTH[month]; | ||
|  | 
 | ||
|  | 		var isB = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); | ||
|  | 		return if (isB) 29 else 28; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Converts a number of seconds to a timestamp. | ||
|  | 	**/ | ||
|  | 	public static inline function seconds(n:Float):Float { | ||
|  | 		return n * 1000.0; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Converts a number of minutes to a timestamp. | ||
|  | 	**/ | ||
|  | 	public static inline function minutes(n:Float):Float { | ||
|  | 		return n * 60.0 * 1000.0; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Converts a number of hours to a timestamp. | ||
|  | 	**/ | ||
|  | 	public static inline function hours(n:Float):Float { | ||
|  | 		return n * 60.0 * 60.0 * 1000.0; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Converts a number of days to a timestamp. | ||
|  | 	**/ | ||
|  | 	public static inline function days(n:Float):Float { | ||
|  | 		return n * 24.0 * 60.0 * 60.0 * 1000.0; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Separate a date-time into several components | ||
|  | 	**/ | ||
|  | 	public static function parse(t:Float) { | ||
|  | 		var s = t / 1000; | ||
|  | 		var m = s / 60; | ||
|  | 		var h = m / 60; | ||
|  | 		return { | ||
|  | 			ms: t % 1000, | ||
|  | 			seconds: Std.int(s % 60), | ||
|  | 			minutes: Std.int(m % 60), | ||
|  | 			hours: Std.int(h % 24), | ||
|  | 			days: Std.int(h / 24), | ||
|  | 		}; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Build a date-time from several components | ||
|  | 	**/ | ||
|  | 	public static function make(o:{ | ||
|  | 		ms:Float, | ||
|  | 		seconds:Int, | ||
|  | 		minutes:Int, | ||
|  | 		hours:Int, | ||
|  | 		days:Int | ||
|  | 	}) { | ||
|  | 		return o.ms + 1000.0 * (o.seconds + 60.0 * (o.minutes + 60.0 * (o.hours + 24.0 * o.days))); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	#if (js || flash || php || cpp || python) | ||
|  | 	/** | ||
|  | 		Retrieve Unix timestamp value from Date components. Takes same argument sequence as the Date constructor. | ||
|  | 	**/ | ||
|  | 	public static #if (js || flash || php) inline #end function makeUtc(year:Int, month:Int, day:Int, hour:Int, min:Int, sec:Int):Float { | ||
|  | 		#if (js || flash || python) | ||
|  | 		return untyped Date.UTC(year, month, day, hour, min, sec); | ||
|  | 		#elseif php | ||
|  | 		return php.Global.gmmktime(hour, min, sec, month + 1, day, year) * 1000; | ||
|  | 		#elseif cpp | ||
|  | 		return untyped __global__.__hxcpp_utc_date(year, month, day, hour, min, sec) * 1000.0; | ||
|  | 		#else | ||
|  | 		// TODO | ||
|  | 		return 0.; | ||
|  | 		#end | ||
|  | 	} | ||
|  | 	#end | ||
|  | } |