【问题标题】:ActionScript 3.0 + Calculate timespan between two dates?ActionScript 3.0 + 计算两个日期之间的时间跨度?
【发布时间】:2010-09-15 05:08:53
【问题描述】:

在 ActionScript 3.0 中,是否有自动计算两个指定日期之间的天数、小时数、分钟数和秒数的方法?

基本上,我需要的是 .NET Timespan 类的 ActionScript 等效项。

有什么想法吗?

【问题讨论】:

    标签: actionscript timespan


    【解决方案1】:

    我创建了一个 ActionScript TimeSpan 类,它使用与 System.TimeSpan 类似的 API 来填补这一空白,但由于缺少运算符重载,因此存在差异。你可以这样使用它:

    TimeSpan.fromDates(later, earlier).totalDays;
    

    下面是该类的代码(抱歉,这篇大文章 - 我不会包含单元测试;)

    /**
     * Represents an interval of time 
     */ 
    public class TimeSpan
    {
        private var _totalMilliseconds : Number;
    
        public function TimeSpan(milliseconds : Number)
        {
            _totalMilliseconds = Math.floor(milliseconds);
        }
    
        /**
         * Gets the number of whole days
         * 
         * @example In a TimeSpan created from TimeSpan.fromHours(25), 
         *          totalHours will be 1.04, but hours will be 1 
         * @return A number representing the number of whole days in the TimeSpan
         */
        public function get days() : int
        {
             return int(_totalMilliseconds / MILLISECONDS_IN_DAY);
        }
    
        /**
         * Gets the number of whole hours (excluding entire days)
         * 
         * @example In a TimeSpan created from TimeSpan.fromMinutes(1500), 
         *          totalHours will be 25, but hours will be 1 
         * @return A number representing the number of whole hours in the TimeSpan
         */
        public function get hours() : int
        {
             return int(_totalMilliseconds / MILLISECONDS_IN_HOUR) % 24;
        }
    
        /**
         * Gets the number of whole minutes (excluding entire hours)
         * 
         * @example In a TimeSpan created from TimeSpan.fromMilliseconds(65500), 
         *          totalSeconds will be 65.5, but seconds will be 5 
         * @return A number representing the number of whole minutes in the TimeSpan
         */
        public function get minutes() : int
        {
            return int(_totalMilliseconds / MILLISECONDS_IN_MINUTE) % 60; 
        }
    
        /**
         * Gets the number of whole seconds (excluding entire minutes)
         * 
         * @example In a TimeSpan created from TimeSpan.fromMilliseconds(65500), 
         *          totalSeconds will be 65.5, but seconds will be 5 
         * @return A number representing the number of whole seconds in the TimeSpan
         */
        public function get seconds() : int
        {
            return int(_totalMilliseconds / MILLISECONDS_IN_SECOND) % 60;
        }
    
        /**
         * Gets the number of whole milliseconds (excluding entire seconds)
         * 
         * @example In a TimeSpan created from TimeSpan.fromMilliseconds(2123), 
         *          totalMilliseconds will be 2001, but milliseconds will be 123 
         * @return A number representing the number of whole milliseconds in the TimeSpan
         */
        public function get milliseconds() : int
        {
            return int(_totalMilliseconds) % 1000;
        }
    
        /**
         * Gets the total number of days.
         * 
         * @example In a TimeSpan created from TimeSpan.fromHours(25), 
         *          totalHours will be 1.04, but hours will be 1 
         * @return A number representing the total number of days in the TimeSpan
         */
        public function get totalDays() : Number
        {
            return _totalMilliseconds / MILLISECONDS_IN_DAY;
        }
    
        /**
         * Gets the total number of hours.
         * 
         * @example In a TimeSpan created from TimeSpan.fromMinutes(1500), 
         *          totalHours will be 25, but hours will be 1 
         * @return A number representing the total number of hours in the TimeSpan
         */
        public function get totalHours() : Number
        {
            return _totalMilliseconds / MILLISECONDS_IN_HOUR;
        }
    
        /**
         * Gets the total number of minutes.
         * 
         * @example In a TimeSpan created from TimeSpan.fromMilliseconds(65500), 
         *          totalSeconds will be 65.5, but seconds will be 5 
         * @return A number representing the total number of minutes in the TimeSpan
         */
        public function get totalMinutes() : Number
        {
            return _totalMilliseconds / MILLISECONDS_IN_MINUTE;
        }
    
        /**
         * Gets the total number of seconds.
         * 
         * @example In a TimeSpan created from TimeSpan.fromMilliseconds(65500), 
         *          totalSeconds will be 65.5, but seconds will be 5 
         * @return A number representing the total number of seconds in the TimeSpan
         */
        public function get totalSeconds() : Number
        {
            return _totalMilliseconds / MILLISECONDS_IN_SECOND;
        }
    
        /**
         * Gets the total number of milliseconds.
         * 
         * @example In a TimeSpan created from TimeSpan.fromMilliseconds(2123), 
         *          totalMilliseconds will be 2001, but milliseconds will be 123 
         * @return A number representing the total number of milliseconds in the TimeSpan
         */
        public function get totalMilliseconds() : Number
        {
            return _totalMilliseconds;
        }
    
        /**
         * Adds the timespan represented by this instance to the date provided and returns a new date object.
         * @param date The date to add the timespan to
         * @return A new Date with the offseted time
         */     
        public function add(date : Date) : Date
        {
            var ret : Date = new Date(date.time);
            ret.milliseconds += totalMilliseconds;
    
            return ret;
        }
    
        /**
         * Creates a TimeSpan from the different between two dates
         * 
         * Note that start can be after end, but it will result in negative values. 
         *  
         * @param start The start date of the timespan
         * @param end The end date of the timespan
         * @return A TimeSpan that represents the difference between the dates
         * 
         */     
        public static function fromDates(start : Date, end : Date) : TimeSpan
        {
            return new TimeSpan(end.time - start.time);
        }
    
        /**
         * Creates a TimeSpan from the specified number of milliseconds
         * @param milliseconds The number of milliseconds in the timespan
         * @return A TimeSpan that represents the specified value
         */     
        public static function fromMilliseconds(milliseconds : Number) : TimeSpan
        {
            return new TimeSpan(milliseconds);
        }
    
        /**
         * Creates a TimeSpan from the specified number of seconds
         * @param seconds The number of seconds in the timespan
         * @return A TimeSpan that represents the specified value
         */ 
        public static function fromSeconds(seconds : Number) : TimeSpan
        {
            return new TimeSpan(seconds * MILLISECONDS_IN_SECOND);
        }
    
        /**
         * Creates a TimeSpan from the specified number of minutes
         * @param minutes The number of minutes in the timespan
         * @return A TimeSpan that represents the specified value
         */ 
        public static function fromMinutes(minutes : Number) : TimeSpan
        {
            return new TimeSpan(minutes * MILLISECONDS_IN_MINUTE);
        }
    
        /**
         * Creates a TimeSpan from the specified number of hours
         * @param hours The number of hours in the timespan
         * @return A TimeSpan that represents the specified value
         */ 
        public static function fromHours(hours : Number) : TimeSpan
        {
            return new TimeSpan(hours * MILLISECONDS_IN_HOUR);
        }
    
        /**
         * Creates a TimeSpan from the specified number of days
         * @param days The number of days in the timespan
         * @return A TimeSpan that represents the specified value
         */ 
        public static function fromDays(days : Number) : TimeSpan
        {
            return new TimeSpan(days * MILLISECONDS_IN_DAY);
        }
    
        /**
         * The number of milliseconds in one day
         */ 
        public static const MILLISECONDS_IN_DAY : Number = 86400000;
    
        /**
         * The number of milliseconds in one hour
         */ 
        public static const MILLISECONDS_IN_HOUR : Number = 3600000;
    
        /**
         * The number of milliseconds in one minute
         */ 
        public static const MILLISECONDS_IN_MINUTE : Number = 60000;
    
        /**
         * The number of milliseconds in one second
         */ 
        public static const MILLISECONDS_IN_SECOND : Number = 1000;
    }
    

    【讨论】:

    • @nchrysler - 我不建议向其他人的示例代码添加功能。不过,您可以随意使用新功能添加您自己的答案。
    • @Erwinus - 有趣,你能给我一份复制声明吗?
    • 您可以为其添加许可证吗?最好是 Apache 或 BSD?不幸的是,有些人在没有许可的情况下不能使用它。
    • 此要点是上述代码的副本,附有 Apache 许可证:gist.github.com/richardszalay/8d5b7b3410c3730b213f
    • 太棒了!谢谢理查德
    【解决方案2】:

    您可以将两个日期时间转换为自纪元以来的毫秒数,执行数学运算,然后使用得到的毫秒数来计算这些更高的时间跨度数。

    var someDate:Date = new Date(...);
    var anotherDate:Date = new Date(...);
    var millisecondDifference:int = anotherDate.valueOf() - someDate.valueOf();
    var seconds:int = millisecondDifference / 1000;
    ....
    

    LiveDocs 对这类事情也很有用。抱歉,ActionScript 有点不对劲,但已经有一段时间了。

    如果您要进行大量此类数学运算,我还建议您创建一组可以执行这些操作的静态类方法。遗憾的是,标准 API 中并不存在这种基本功能。

    【讨论】:

      【解决方案3】:

      对于一些像这样的单一功能我更可取... [浓缩自 Richard Szalay 的代码]

      public function timeDifference(startTime:Date, endTime:Date) : String
      {
      if (startTime == null) { return "startTime empty."; }
      if (endTime   == null) { return "endTime empty."; }
      var aTms = Math.floor(endTime.valueOf() - startTime.valueOf());
      return "Time taken:  "  
          + String( int(aTms/(24*60*+60*1000))     ) + " days, "
          + String( int(aTms/(    60*60*1000)) %24 ) + " hours, "
          + String( int(aTms/(       60*1000)) %60 ) + " minutes, "
          + String( int(aTms/(        1*1000)) %60 ) + " seconds.";
      }
      

      【讨论】:

      • 不准确。不考虑闰年或有 29 天的 2 月。
      【解决方案4】:

      没有自动执行此操作的方法。使用提供的类可以实现的最佳效果是获取 date1.time 和 date2.time,以给出两个数字自 1970 年 1 月 1 日以来的毫秒数。然后,您可以计算出它们之间的毫秒数。通过一些基本的数学运算,您可以推导出秒、小时、天等。

      【讨论】:

        【解决方案5】:

        为了准确起见,Russell 的上述帖子是正确的,直到您达到 25 天的差异,然后这个数字对于 int 变量来说变得太大了。 因此声明millisecondDifference:Number;

        记录的 getTime() 和 valueOf() 之间可能存在一些差异,但实际上我看不到它

        【讨论】:

          【解决方案6】:
          var timeDiff:Number = endDate - startDate;
          var days:Number     = timeDiff / (24*60*60*1000);
          var rem:Number      = int(timeDiff % (24*60*60*1000));
          var hours:Number    = int(rem / (60*60*1000));
          rem                 = int(rem % (60*60*1000));
          var minutes:Number  = int(rem / (60*1000));
          rem                 = int(rem % (60*1000));
          var seconds:Number  = int(rem / 1000);
          
          trace(days + " << >> " +hours+ " << >> " +minutes+ " << >> " +seconds);
          

          var time:Number = targetDate - currentDate;
          var secs:Number = time/1000;
          var mins:Number = secs/60;  
          var hrs:Number  = mins/60;
          var days:Number = int(hrs/24);
          
          secs = int(secs % 60);
          mins = int(mins % 60);
          hrs  = int(hrs % 24);
          
          trace(secs + "  << >> " + mins + " << >> " + hrs + " << >> " + days);
          

          【讨论】:

            【解决方案7】:

            ArgumentValidation 是 Szalays 先生的另一类,它进行一些检查以确保每个方法都有正确的值来执行其任务,而不会引发无法识别的错误。它们对于使 TimeSpan 类正常工作不是必需的,因此您只需将它们注释掉,该类就会正常工作。

            Rich 可能会在这里发布 Argument 验证类,它非常方便,但我会把它留给他;P

            【讨论】:

            • James 是对的,它只是一个实用类来保持消费代码干净
            • ...虽然这个答案和 sideDoors 答案都应该是 cmets ;)
            猜你喜欢
            • 1970-01-01
            • 2012-01-31
            • 1970-01-01
            • 1970-01-01
            • 2010-09-17
            • 2012-02-13
            • 2021-11-25
            • 2011-08-01
            • 1970-01-01
            相关资源
            最近更新 更多