123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- /*
- * 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":
- untyped StringTools.lpad(Std.string(Std.int(d.getFullYear() / 100)), "0", 2);
- case "d":
- untyped StringTools.lpad(Std.string(d.getDate()), "0", 2);
- case "D":
- __format(d, "%m/%d/%y");
- case "e":
- untyped Std.string(d.getDate());
- case "F":
- __format(d, "%Y-%m-%d");
- case "H", "k":
- untyped StringTools.lpad(Std.string(d.getHours()), if (e == "H") "0" else " ", 2);
- case "I", "l":
- var hour = d.getHours() % 12;
- untyped StringTools.lpad(Std.string(hour == 0 ? 12 : hour), if (e == "I") "0" else " ", 2);
- case "m":
- untyped StringTools.lpad(Std.string(d.getMonth() + 1), "0", 2);
- case "M":
- untyped StringTools.lpad(Std.string(d.getMinutes()), "0", 2);
- case "n":
- "\n";
- case "p":
- untyped 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":
- untyped StringTools.lpad(Std.string(d.getSeconds()), "0", 2);
- case "t":
- "\t";
- case "T":
- __format(d, "%H:%M:%S");
- case "u":
- untyped {
- var t = d.getDay();
- if (t == 0)
- "7";
- else
- Std.string(t);
- }
- case "w":
- untyped Std.string(d.getDay());
- case "y":
- untyped StringTools.lpad(Std.string(d.getFullYear() % 100), "0", 2);
- case "Y":
- untyped Std.string(d.getFullYear());
- default:
- throw "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
- }
|