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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработка дат в языке Java 
:(
    Опции темы
Wowa
Дата 8.12.2005, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

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



В Java дата и время представлены одним классом java.util.Date. Разработчики языка старались снабдить его средствами обработки дат, не зависящими от локализации (locale). Осуществление таких идей, в свою очередь, связано с некоторыми проблемами. Во-первых, порядок и способ записи числа, месяца и других составляющих даты и времени отличается в различных странах. Во-вторых, существуют календари, для которых привычное для нас разбиение даты на месяцы и дни неприемлемо. Это видимо и привело разработчиков к мысли о том, что класс Date должен быть как можно более независимым от локализации. Если в ранних версиях Java класс Date содержал методы getDay(), getMonth() и т.д., то использование этих методов сейчас очень не приветствуется. Это фактически означает, что в классе Date остается единственный полезный метод - getTime(). Он возвращает количество миллисекунд с момента 1970 г., 1 января, 00:00 по GMT и указывает именно на конкретный момент времени, инвариантный относительно страны.
Для того, чтобы представить дату/время в текстовом виде, необходимо знать часовой пояс, страну и язык, так как один и тот же момент времени в разных языках, странах или часовых поясах пишется по-разному. За часовой пояс отвечает класс TimeZone, а за страну и язык - Locale. Функции "вычленения" компонент (таких как часы, минуты) из даты и времен берет на себя класс Calendar и его подклассы. Например, GregorianCalendar представляет привычный календарь, с отсчетом времени от Рождества Христова. При создании класса GregorianCalendar необходимо указать TimeZone и Locale.

На первый взгляд задумано неплохо. Другое дело, что вышеизложенные идеи интернационализации даты и времени часто реализованы не в полной мере. Например, не советую использовать поля типа "даты" или "времени" в JDBC-ODBC. При записи в базу данных полей Date иногда возникает ошибка "datetime overflow" (Java 1.1). Вместо даты или времени в базе данных можно держать поля типа "целое" (32 бита) и хранить количество секунд с 1970 года (java.util.Date.getTime()/1000). Не рассчитывайте, что TimeZone будет работать без изменений в любой версии Java. Например, не всегда виртуальная машина Java корректно определяет текущий часовой пояс, что приводит к ошибке на 3 часа (или даже больше, в зависимости от вашего часового пояса). Кроме того, необходимо учесть, что поле "год" календаря вычисляется как полный год-1900, то есть год 2000 будет обозначаться как 100. Кроме того, номера месяцев начинаются не с 1, как принято в цивилизованном обществе, а с 0, хотя номера дней в месяце начинаются с 1.

Наличие большого количества ошибок в реализации программного интерфейса работы с датой делает и без того сложный интерфейс (Date, Timestamp, Calendar, GregorianCalendar, SimpleDateFormat, TimeZone) еще более запутанным. Приведу наглядный пример. Допустим, мы захотели вывести текущую дату и время на дисплей. Вот фрагмент приложения, которое это делает: 
Код

    Date d = new Date();
    DateFormat df = new SimpleDateFormat("HH:mm:ss yyyy/MM/dd");
    System.out.println(df.format(d));


Под Java 1.2 оно работает нормально. Однако под Java 1.1.6, оно выдает время, на час меньше текущего. Тогда я попробовал явно задать TimeZone: 
Код

    DateFormat df = new SimpleDateFormat("HH:mm:ss yyyy/MM/dd");
    TimeZone tz = TimeZone.getTimeZone("GMT+03");
    System.out.println(tz.toString());
    df.setTimeZone(tz);
    System.out.println(df.format(d));


Но это не прошло, так как "GMT+03" правильно воспринимает только Java 1.2. Под Java 1.1.6 на экране появилось текущее время по GMT, что соответствует GMT+00. Тогда я решил уточнить, что же все-таки можно передавать в качестве аргумента методу getTimeZone: 
Код

    String [] ids = TimeZone.getAvailableIDs();
    for(int i=0; i<ids.length; i++) System.out.println(ids[i]);


Этот фрагмент выводит все известные Javе названия всех часовых поясов. Причем вывод Java 1.2 и Java 1.1.6 различается. Из списка трехбуквенных названий часовых поясов мне пришлось угадать своё ("EAT", московское время). Таким образом, приложение, всего лишь навсего выводящее текущую дату, превращается вот в такого монстра: 
Код

    Date d = new Date();
    DateFormat df = new SimpleDateFormat("HH:mm:ss yyyy/MM/dd");
    df.setTimeZone(TimeZone.getTimeZone("EAT"));
    System.out.println(df.format(d));


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

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

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


 




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


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

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