![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
AntonSaburov |
|
||||||||||||||||||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 51 Всего: 118 |
Спасибо LSD за отличную статью
Работа с датами в Java. Календарь - система времясчисления. Основанием К. служат астрономические явления: обращение земли вокруг солнца (солнечный К.), луны вокруг земли (лунный К.) и земли вокруг своей оси. Малый энциклопедический словарь Брокгауза и Ефрона В Древнем Риме К. сначала называли книги, в которые кредиторы записывали проценты, вносившиеся ежемесячно в дни календ (отсюда название), позднее К. стали именовать книги, расписывающие культовые празднества, дни рождения императоров, дни собраний сената. Большая советская энциклопедия Базовым классом для хранения даты в Java, является java.util.Date. От него унаследовано несколько классов java.sql.Date, java.sql.Time, java.sql.Timestamp, которые предназначены для работы с базами данных. Для манипулирования датами предназначен класс java.util.Calendar, он позволяет для любой даты узнать такие вещи как: день недели, месяц, номер недели в году и месяце, номер дня в году и т.п. Еще одним важным классом для работы с датой является java.util.TimeZone. Класс TimeZone представляет собой временную зону. Временная зона характеризует насколько время в данном регионе, смещено относительно некой нулевой точки. В качестве нулевой точки выбрано время на гринвичском меридиане GMT (Greenwich Mean Time), иначе его называют - UTC (Universal Coordinated Time - всеобщее скоординированное время). Все остальные пояса указывают как смещение от GMT, например Москва это GMT+03:00, что означает, что для получения московского времени, надо к времени по Гринвичу прибавить 3 часа 0 минут. Временная зона это не одно и то же, что и часовой пояс: не везде временная зона совпадает с часовым поясом, в часовом поясе нет понятия зимнего/летнего времени. Часовой пояс характеризует только географическое положение территории, но не используемое на ней время. Существует несколько стандартных имен временных зон:
Класс Calendar предназначен для манипулирования датами. Сам класс Calendar абстрактный, и служит базовым классом для реализации других календарей. Получить умолчальный календарь можно с помощью Calendar.getInstance(), можно получить календарь для указанного часового пояса и региона (Locale). У Calendar есть список полей, которые характеризуют дату, это:
Теперь собственно о том, как происходит работа с датой, установить дату можно двумя способами. Первый методами setTime(<дата>) и setTimeInMillis(<миллисекунды>), можно просто установить время, при этом будут вычислены и установлены все поля. Потом можно будет получить или изменить любое поле. Другой способ состоит в том, чтобы устанавливать значения полей и затем на основе этих данных получить дату. Поля могут принимать взаимоисключающие значения, тогда во внимание принимается последнее изменение, например можно установить месяц, а затем установить день в году, тогда даты будет считаться исходя из номера дня в году, независимо от того какой месяц мы до этого установили. А вот если попробовать наоборот, то тут посложнее, когда мы установим день года, то автоматом будут вычислены месяц и день месяца, изменив месяц, день месяца останется неизменным. Если какое то поле не было установлено, явно или опосредованно, то оно принимает значение по умолчанию, как правило это первое число, первый месяц и т.д. Теперь рассмотрим один тонкий момент, при установки одного значения значение другого поля может стать не корректным. Например, был дата 31 января, мы установили месяц в февраль, 31 число месяца стало не действительным. Что при этом произойдет от того, какое значение имеет свойство lenient, если оно установлено в true, то лишние дни будут "перенесены" на следующий месяц (в нашем примере мы получим 3 марта, для не високосного года), если оно установлено в false, то будет вызвано исключение IllegalArgumentException. По умолчанию lenient установлено в true. Есть еще несколько вспомогательных методов по работе с полями. Метод clear(<поле>) устанавливает поле в умолчальное значение, clear() устанавливает все поля в умолчальные значения (в результате мы получим 00:00:00.000 31 Январь 2005 н.э. GMT). Узнать было ли поле установлено явно или не явно, можно с помощью isSet(<поле>), false возвращается для полей, которые вообще не были установлены явно или не явно. Функция add(<поле>,<значение>) добавляет к указанному полю, указанную величину (прибавлять можно и отрицательные величины), при этом могут измениться и другие поля, например если для 31 января вызвать add(Calendar.DAY_OF_MONTH, 2), то получим 2 февраля. Есть функция roll(<поле>,<значение>), схожая с add, но отличающаяся тем что при изменении поля "старшие" поля меняться не будут, в нашем примере roll(Calendar.DAY_OF_MONTH, 2) поменяет дату с 31 января на 2 января. Несмотря на то что старшие поля не меняются, младшие будут меняться если для 31 января выполнить roll(Calendar.MONTH, 1), то получим 28 февраля (или 29 для високостного года). Это основные понятия по работе с датой, осталось рассмотреть временные интервалы. В Java нет особого класса для работы с временными интервалами. Если нужно вычислить время прошедшее между двумя датами, то это делается достаточно просто: (dateTill.getTime() - dateFrom.getTime()) и получим количество миллисекунд прошедших с первого момента времени до второго. Чтобы получить например количество часов, надо полученную величину разделить на 3 600 000. Если же надо вычислить количество календарных суток, прошедших с первого момента до второго, то надо использовать Calendar и его функции по работе с полями. Примеры использования: Посчитать дату на N дней вперед/назад от указанной
Установить временную составляющую в начало суток:
Получить день недели:
Получить день недели в текстовом виде, на французком языке:
Получить дату по году, месяцу и дню месяца:
Получить максимальный день месяца:
Ну и на последок простенькая TableModel отображающая календарь на указанный месяц:
При работе с датой/временем возникает задача перевода оной в текстовый вид и обратно. Для облегчения работы с текстом сущесвует пакет java.text, для нашего случая это классы данного пакета: java.text.DateFormat, java.text.SimpleDateFormat Кроме того, в JDK 5.0 появился класс java.util.Formatter, который также можно использовать для представления даты в нужном текстовом виде. Пример 1:
Пример 2:
|
||||||||||||||||||
|
|||||||||||||||||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
На практике часто возникает задача получить количество дней между указанными датами. Тут есть одна тонкость, предположим у нас есть две даты: 18 дек 2007 23:59:59.999 и 20 дек 2007 00:00:00.000. Между этими двумя датами 86400001 милисекунд, или ~1 сутки. С другой стороны между этими датами 2 календарных дня. Количество суток между датами легко посчитать получив время в милилсекундах и разделив его на количество милисекунд в сутках. Получить календарные дни чуть сложнее, один из вариантов это сбросить временную составляющую в дате к началу суток, и посчитать полное количество суток между датами. Пример:
небольшое замечание по коду: из-за того, что в некоторых странах используется переход на зимнее/летнее время, то между двумя днями может быть не целое количество суток, если один из них "в летнем времени", а другой в "в зимнем". Именно для этого и вычисляется значение переменной adjustment, котороая вносит соответсвующие корективы. -------------------- 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. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |