Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Календарные исчисления (http://www.flasher.ru/forum/showthread.php?t=207833)

dark256 11.05.2014 08:41

Календарные исчисления
 
Друзья, коллеги, багородный сенат.
Ищу несколько алгоритмов, относящихся к вычислениям с календарными датами, ибо смутно ощущаю, что изобретаю какие-то дикие велосипеды, а все уже придумано до нас.

А именно. Есть две даты:

Код:

datIn = {D:day1, M:month1, Y:year1}
datOut = {D:day2, M:month2, Y:year2}

Надо:

1. Получить _ВСЕ_ наборы от dayIn до dayOut в виде день-месяц-год...
Сйчас реализовано в виде аж трех вложенных циклов, что, на мой взгляд, омерзительно:
Код AS1/AS2:

var allBronCelles = []
 
for ( var Y=StartYear; Y<=FinYear; Y++ ){                                                // Перебираю годы
 
        if ( StartYear == Y ){ A = StartMnt } else { A = 0 }
        if ( FinYear == Y ){ B = FinMnt } else { B = 11 }       
        for (var MN = A; MN<= B; MN++ ){                                                        // Перебираю месяцы
 
                if ( StartMnt == MN ) { SD = StartDay } else { SD = 1 }
                if ( FinMnt == MN ) { FD = FinDay } else { FD = getDaysInMonth( Y )[ MN ] }
                for ( var DAY = SD; DAY<=FD; DAY++ ){                                        // Перебираю дни
                        allBronCelles.push( { D:DAY, M:MN, Y:Y } )
                }
        }
}

Имхо громоздко и коряво... Работает, да, но...

2. Надо получить кол-во дней, прошедших от одной даты до другой.
У меня решение сейчас сводится к предыдущему динозавру + счетчик этих дней.

3. Определить, сколько дней относится к каждому из месяцев, входящих в диапазон....
По идее снова берем ужас из п.1. и при смене месяца (корявость) счетчики пихаем в массив...

Подразумевается, что year1 - year2 может занимать лет 10-20.... Високостности, разные длины месяцев и прочее учитывается....
За неконвенционность - сорри.

iNils 11.05.2014 15:07

Делаем две даты, вычитаем time, делим на ms * s * m * h, и получаем количество дней + 1 в данном диапазоне.
Дальше нужен только один цикл.

dark256 11.05.2014 16:49

В целом - логично. Но... у меня предполагается генерить 100-200-... подобных выборок длиной до 150-300 "дней".
Соответственно вопрос: не будет ли Date тормозить данный процесс в особо крупных размерах...
И не будет ли все это менее энергоемко на циклах или еще каких вариантах высокопроизводительных алгоритмах?
Дело не в том, что я не знаю КАК.... Мне кажется, что я не знаю как это сделать эстетично :)

Эксперименты с секундомером пока не производил, ибо подозреваю, что опять-таки я велосипед изобретать стану.

silin 12.05.2014 23:48

типа эстетично
Код AS1/AS2:

package
{
        import flash.display.Sprite;
 
        public class Main extends Sprite
        {
 
                public function Main():void
                {
                        var d1:Date = new Date(2014, 3, 29);
                        var d2:Date = new Date(2014, 4, 11);
 
                        var dateCounter:DateCounter = new DateCounter(d1, d2);
 
                        trace("список : " + dateCounter.list);
                        trace("всего: " + dateCounter.list.length);
                        trace(" в апреле 2014: " + dateCounter[2014][3]);
                        trace(" в мае 2014: " + dateCounter[2014][4]);
                        trace(" в июне 2014: " + dateCounter[2014][5]);
 
                }
 
        }
 
}
 
dynamic class DateCounter
{
        public const list:Array = [];
        public const dayTime:int = 24 * 60 * 60 * 1e3;
 
        public function DateCounter(d1:Date, d2:Date):void
        {
 
                for (var j:int = d1.getFullYear(); j <= d2.getFullYear(); j++)
                {
                        this[j] = [];
                        for (var k:int = 0; k < 12; k++)
                        {
                                this[j][k] = 0;
                        }
                }
 
                var days:int = (d2.time - d1.time) / dayTime + 1;
                var date:Date = new Date();
 
                for (var i:int = 0, t:Number = d1.time; i < days; i++)
                {
                        date.setTime(t + i * dayTime);
                        var y:int = date.getFullYear();
                        var m:int = date.getMonth();
                        var d:int = date.getDate();
                        list.push(new Day(d, m, y));
                        this[y][m]++;
 
                }
 
        }
 
}
 
class Day
{
        public var d:int;
        public var m:int;
        public var y:int;
 
        public function Day(d:int, m:int, y:int)
        {
                this.y = y;
                this.m = m;
                this.d = d;
 
        }
 
        public function toString():String
        {
                return d + "-" + m + "-" + y;
        }
}

при обращении к 'неучтенному' году получим RTE, поэтому совсем эстетично было бы наследоваться от Proxy, чтоб эти нюансы учесть\обработать, но это уже совсем уже будет, можно и по-простому не обращаться к ним или инициализировать сразу какой-нить диапазонище 1980..2080
насчет 'тормозить в особо крупных размерах..' имхо напрасные опасения, нечему тут особо тормозить-то

ZackMercury 13.05.2014 01:29

dark256, когда вы сказали, что регулярно забиваете на концепции, я подумал, что вы пошутили...

Rzer 13.05.2014 03:06

Код AS3:

var d1:Date = new Date(2014, 3, 29);
var d2:Date = new Date(2014, 4, 11);
 
while (d1.time <= d2.time) {
  trace(d1.toDateString());
  d1.time += 60 * 60 * 24*1000;
}


silin 14.05.2014 10:44

а вот еще эстетические вариации: один раз генерим список дат и из него потом дергаем что потребуется
Код AS3:

package
{
        import flash.display.Sprite;
 
        public class Main extends Sprite
        {
 
                public function Main():void
                {
 
                        var d1:Date = new Date(2014, 3, 29);
                        var d2:Date = new Date(2014, 4, 11);
 
                        DateList.init(2000, 2030);
 
                        trace("список : " + DateList.getRange(d1, d2));
                        trace("всего: " + DateList.getRange(d1, d2).length);
                        trace(" в апреле 2014: " + DateList.getMonthRange(d1, d2, 2014, 3).length);
                        trace(" в мае 2014: " + DateList.getMonthRange(d1, d2, 2014, 4).length);
                        trace(" в июне 2014: " + DateList.getMonthRange(d1, d2, 2014, 5).length);
 
                }
 
        }
 
}
 
//===============//
class DateList
{
        public static const list:Array = [];
        public static const day:int = 24 * 60 * 60 * 1000;
 
        public static function init(y1:int, y2:int):void
        {
                var d1:Date = new Date(y1);
                var d2:Date = new Date(y2, 11, 31);
 
                while (d1.time <= d2.time)
                {
                        list.push(dateToString(d1));
                        d1.time += day;
                }
        }
        public static function dateToString(d:Date):String
        {
                return d.getDate() + "-" + d.getMonth() + "-" + d.getFullYear()
        }
        // список дней диапазона d1..d2
        public static function getRange(d1:Date, d2:Date):Array
        {
                var i1:int = list.indexOf(dateToString(d1));
                var i2:int = list.indexOf(dateToString(d2)) + 1;
                return list.slice(i1, i2);
        }
        // список дней диапазона d1..d2, попадающих в year.month
        public static function getMonthRange(d1:Date, d2:Date, year:int, month:int):Array
        {
 
                var r1:Date = new Date(year, month);
                var r2:Date = new Date(year, month + 1, 0);
                if (r1 < d1) r1 = d1;
                if (r2 > d2) r2 = d2;
 
                return getRange(r1, r2);
        }
 
}



Часовой пояс GMT +4, время: 18:05.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.