Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Генерация дат 
:(
    Опции темы
zss
Дата 13.1.2005, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: нет
Всего: 2



В зависимости от начальной и конечной даты необходимо сгенерить значения с заданным периодом. Можно ли это реализовать универсально ?

Схематично:
Код

public void GetData (StartData, EndData, Period) {
...
}


Тоесть весь прикол в том, что я могу запросить генерацию :
1. По часам
2. По дням
3. По неделям
4. По месяцам
5. По годам

Спасибо
PM MAIL ICQ   Вверх
Nobody
Дата 14.1.2005, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 25.8.2003
Где: Россия, Москва

Репутация: 4
Всего: 16



Представить дату в виде миллисекунд с начала эпохи и вычесть?


--------------------
Алгоритм помещения вопросов на форуме
Выражаем спасибо вот ТАК
Use the Source, Luke!
PM MAIL WWW ICQ   Вверх
LSD
Дата 14.1.2005, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15719
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Как я понял надо что-то вроде:
Код

public Date[] getData(Date startDate, Date endDate, long period)
{
 long start = startDate.getTime();
 long stop = endDate.getTime();
 ArrayList list = new ArrayList();
 while(start <= stop)
 {
   list.add(new Date(start));
   start += period;
 }
 return(Date[]) list.toArray(new Date[0]);
}


Это сообщение отредактировал(а) LSD - 14.1.2005, 00:50


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
zss
Дата 14.1.2005, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: нет
Всего: 2



1. А где Date и ArrayList находятся ?

2. Что-то вроде этого, но немного не так

Я задаю начало, конец и период. К примеру - 1 января 1990 по 1 января 2000

а) период - год. Значит должо получиться
1990, 1991, ..., 2000
б) период - месяц.
январь 1990, февраль 1990, ... декабрь 2000
в) период - день.
1 января 1990, 2 января 1990, ... 1 января 2000
г) период - час.
1 января 1990 00.00, ..., 31 декабря 1999 24.00

и т.д. Можно ли это реализовать с помощью одной функции ?

Это сообщение отредактировал(а) zss - 14.1.2005, 10:07
PM MAIL ICQ   Вверх
Nobody
Дата 14.1.2005, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 25.8.2003
Где: Россия, Москва

Репутация: 4
Всего: 16



LSD всё написал. Посчитай просто сколько миллисекунд в дне/месяце/году и вперёд.


--------------------
Алгоритм помещения вопросов на форуме
Выражаем спасибо вот ТАК
Use the Source, Luke!
PM MAIL WWW ICQ   Вверх
LSD
Дата 14.1.2005, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15719
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(zss @ 14.1.2005, 10:06)
1. А где Date и ArrayList находятся ?

Не понял вопроса.

Цитата(zss @ 14.1.2005, 10:06)
Я задаю начало, конец и период. К примеру - 1 января 1990 по 1 января 2000

а) период - год. Значит должо получиться
1990, 1991, ..., 2000
б) период - месяц.
январь 1990, февраль 1990, ... декабрь 2000
в) период - день.
1 января 1990, 2 января 1990, ... 1 января 2000
г) период - час.
1 января 1990 00.00, ..., 31 декабря 1999 24.00

и т.д. Можно ли это реализовать с помощью одной функции ?

Пункты а и б не совсем интервал, т.к. их длительность варьируется. Но можно и такую штуку сделать. Есть правда парочка тонких моментов, что делать например если начальная дата 31.01.2000 а интервал 1 месяц? Как напишу запостю.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
LSD
Дата 14.1.2005, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15719
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Вот приблизительный код:
Код

public static Date[] getDate(Date startDate, Date endDate, int[] fields, int[] amounts)
{
 if(fields.length != amounts.length)
   throw new IllegalArgumentException("Size of fields and amounts must be equal");
 Calendar calendar = Calendar.getInstance();
 calendar.setTime(startDate);
 ArrayList list = new ArrayList();
 while(calendar.before(endDate))
 {
   list.add(calendar.getTime());
   for(int i = 0; i < fields.length; i++)
   {
     calendar.add(fields[i], amounts[i]);
     //or
     calendar.roll(fields[i], amounts[i]);
   }
 }
 return(Date[]) list.toArray(new Date[0]);
}

В массиве fields передаются константы обозначающие поля которые надо увеличивать (см java.util.Calendar), а в массиве fields, то на сколько их надо увеличивать. Т.е. для: период - год и 2 месяца. Делаем так:
Код

getDate(startDate, endDate, new int[] {Calendar.YEAR, Calendar.MONTH}, new int[] {1, 2});



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
igon
Дата 14.1.2005, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 30.10.2004

Репутация: 1
Всего: 21



Уппс, немного опоздал, и все же...
Цитата
LSD всё написал. Посчитай просто сколько миллисекунд в дне/месяце/году и вперёд.


Не так все просто - в феврале меньше миллисекунд, чем в январе, а в високосном 2000 - больше, чем в обычном 2001 smile
Я бы предложил модифицировать вариант LSD (первоначальный!!!)
1. В цикле к начальной дате прибавлять не period, а минимальный интервал, в данном случае количество миллисекунд в часе.
2. Из полученной даты извлекать подстроку, соответствующую period и добавлять ее в структуру типа список, ДОПУСКАЮЩУЮ ТОЛЬКО УНИКАЛЬНЫЕ значения (Set, SortedSet?).
3. Список возвратить

Т.к. количество миллисекунд варьирует только для годов и месяцев, приращение в цикле, для ускорения, можно делать по дням и даже по неделям smile


--------------------
Хотите поговорить об этом?
PM   Вверх
zss
Дата 14.1.2005, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: нет
Всего: 2



Цитата(igon @ 14.1.2005, 22:34)
можно делать по дням и даже по неделям


надо даже часам и минутам smile - а с этим сложнее

LSD, спасибо, твой код попробую обкатать - может что и придумаю
PM MAIL ICQ   Вверх
LSD
Дата 14.1.2005, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15719
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Я не пояснил, внутри цикла надо оставить или calendar.add(fields[i], amounts[i]); или calendar.roll(fields[i], amounts[i]);.
Если оставить calendar.add(fields[i], amounts[i]);, то в том примере следующая дата будет не в феврале а в марте, а если оставить calendar.roll(fields[i], amounts[i]);, то следующая дата будет 28 февраля.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
igon
Дата 15.1.2005, 02:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 30.10.2004

Репутация: 1
Всего: 21



Вот пример РАБОТАЮЩЕГО (отнюдь не оптимального!!!) кода на основе первоначального варианта LSD.
Реализовано только для "По дням" и "По месяцам", выдает в алфавитном порядке, но все дни (месяцы) и в нужном (ИМХО) формате, начиная с текущей даты+3 месяца. Иная сортировка - это уже детали smile

Для минут и часов нужно просто другую маску в formatter

Код

import java.text.SimpleDateFormat;

import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

public class B
{  

 public static void main(String[] args)    
   {
      Calendar calendar = Calendar.getInstance();
      Date dateBegin = calendar.getTime();
      calendar.add(Calendar.MONTH,3);
      Date dateEnd   = calendar.getTime();
      SortedSet result = getData(dateBegin, dateEnd, "Day");

       Iterator iterator = result.iterator();
       while (iterator.hasNext())
         {
           System.out.println(iterator.next().toString());  
         }
      result = getData(dateBegin, dateEnd, "Month");
      System.out.println("");  
       iterator = result.iterator();
       while (iterator.hasNext())
         {
           System.out.println(iterator.next().toString());  
         }
  }

public static SortedSet getData(Date startDate, Date endDate, String period)
 {
   long  start  = startDate.getTime();
   long  stop   = endDate.getTime();
   long  add    = 1000*60; //приращение - по МИНУТЕ!
   SortedSet result=new TreeSet();
   SimpleDateFormat formatter=null;
   if (period.equalsIgnoreCase("Day"))
     {
       formatter = new SimpleDateFormat("dd MMMMM yyyy");
     }
   if (period.equalsIgnoreCase("Month"))
     {
       formatter = new SimpleDateFormat("MMMMM yyyy");
     }
   while(start <= stop)
     {
       result.add(formatter.format(new Date(start)));
       start += add;
     }
   return(result);
 }
}


Это сообщение отредактировал(а) igon - 15.1.2005, 02:36


--------------------
Хотите поговорить об этом?
PM   Вверх
zss
Дата 28.1.2005, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: нет
Всего: 2



Спасибо - помогло

А в каком формате их лучше хранить ?
Я храню в файле в виде строки, но много недостатков:
1. Частые преобразования String->long->Date и Date->long->String
2. Если просто читать файл, то дата непонятна smile

Это сообщение отредактировал(а) zss - 28.1.2005, 12:13
PM MAIL ICQ   Вверх
AntonSaburov
Дата 28.1.2005, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: 51
Всего: 118



Оставь строкой - затраты на чтение файла гораздо выше,чем затраты на преобразование.
Для скорости можешь сделать класс, который будет хранить дату во всех трех представлениях. А записывая/считывай только строку.
PM MAIL WWW ICQ   Вверх
zss
Дата 28.1.2005, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: нет
Всего: 2



Так строка у меня примерно такая

61062670800000

не очень то понятно что это за дата smile

А если использовать Date.toString, то обратно не перевести
PM MAIL ICQ   Вверх
Domestic Cat
Дата 28.1.2005, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



А может лучше хранить в виде лонг (миллисекунды). Оттуда легко созать объект Date. А если часто работаешь с одной и той же датой, то тогда быстрее всего сделать как Антон предложил; памяти немного больше съешь но зато эффективнее.


--------------------

PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1037 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.