Клас Date

Java Syntax Zero
Рівень 17 , Лекція 2
Відкрита

1. Клас Date і Unix-час

З самого появи мови Java в ній був спеціальний клас для роботи з часом і датою — Date. З часом з'явилося ще кілька класів для роботи з датою, але клас Date досі використовується програмістами.

Уся справа в тому, що він дуже простий і зручний. І ти як програміст обов'язково зіткнешся з ним у будь-якому реальному проєкті. Використовувати його чи ні — вибір за тобою, але знати його ти зобов'язаний. Тому приділи йому кілька хвилин свого дорогоцінного часу.

Чим же такий гарний клас Date? Своєю простотою.

Клас Date зберігає інформацію про дату і час у вигляді кількості мілісекунд, що пройшли з 1 січня 1970 року. Це дуже багато мілісекунд, тому для їх зберігання використовується тип long.

Цікаво

Чому саме з 1970 року? Це так званий Unix-time: саме так зберігає час операційна система Unix, яка є бабусею всіх сучасних операційних систем.

А ще можна дуже легко дізнатися, скільки часу пройшло між двома датами: достатньо відняти одну дату від іншої, і отримаєш різницю в часі між датами з точністю до мілісекунд.

Ось кілька корисних прикладів роботи з класом Date.


2. Отримання поточної дати

Щоб отримати поточний час і дату, достатньо просто створити об'єкт типу Date. Кожен новий об'єкт зберігає час (момент) його створення. Виглядає це дуже просто:

Date current = new Date();

Після виконання цієї команди змінна current буде зберігати посилання на створений об'єкт Date, який всередині себе буде зберігати час його створення — кількість мілісекунд, що минули з 1 січня 1970 року.

Вивід поточної дати на екран

Щоб вивести на екран поточну дату, просто: а) створіть новий об'єкт Date, б) виведіть його на екран за допомогою методу System.out.println().

Приклад:

Код Вивід на екран
Date current = new Date();
System.out.println(current);
Thu Feb 21 14:01:34 EET 2019

Вивід на екран розшифровується так:

Текст Розшифровка
Thursday Четвер
February 21 21 Лютого
14:01:34 години : хвилини : секунди
EET Часовий пояс: East European Time (східноєвропейський час)
2019 Рік

3. Завдання певної дати

Як отримати поточний час, ми розібралися, а як створити об'єкт Date, який би містив іншу дату або час?

Тут теж усе просто. Щоб задати певний день, потрібно написати код такого виду:

Date birthday = new Date(рік, місяць, день);

Усе просто й очевидно, але є два нюанси:

  1. Рік потрібно задавати від 1900.
  2. Місяці нумеруються з нуля.
Цікаво

Це теж спадщина операційної системи Unix: там програмісти позначали рік двома цифрами. Замість 1977 писали просто 77. Тому 77 стане правильним роком, якщо ми рахуємо від 1900 року.

Наприклад, я народився 21 березня 1989 року. Березень — третій місяць, значить мені потрібно написати

Код Вивід на екран
Date current = new Date(89, 2, 21);
System.out.println(current);
Tue Mar 21 00:00:00 EET 1989

Місяці нумеруються з нуля, а дні — ні. Трішки дивно, так?

Гадаємо, справжні програмісти мали б пересилити себе і дні місяця теж нумерувати з нуля. Ох ці конформісти 🙂

Завдання певного часу

Задати певний час теж досить просто: для цього потрібно написати команду такого виду:

Date birthday = new Date(рік, місяць, день, години, хвилини, секунди);

Години, хвилини і секунди нумеруються з нуля: програміст у вас повинен зітхнути спокійно.

Приклад:

Код Вивід на екран
Date current = new Date(105, 5, 4, 12, 15, 0);
System.out.println(current);
Sat Jun 04 12:15:00 EEST 2005

Ми задали час 12:15 і дату 4 червня 2005 року. Читається трохи складнувато для непрофесіонала, зате працює як треба.


4. Робота з фрагментами дати

Об’єкт Date можна не просто виводити на екран. У нього є методи, які дозволяють отримати окремі фрагменти його дати:

Метод Опис
int getYear()
Повертає рік дати відносно 1900 року.
int getMonth()
Повертає місяць дати, місяці нумеруються з нуля
int getDate()
Повертає день місяця
int getDay()
Повертає день тижня
int getHours()
Повертає години
int getMinutes()
Повертає хвилини
int getSeconds()
Повертає секунди

Приклад:

Код Вивід на екран Примітка
Date current = new Date(105, 5, 4, 12, 15, 0);
System.out.println(current.getYear());
System.out.println(current.getMonth());
System.out.println(current.getDate());
System.out.println(current.getDay());

105
5
4
6

2005 рік
червень
день місяця
субота

До речі, у об'єкта Date окремі фрагменти дати можна не тільки отримувати, але й змінювати:

Метод Опис
void setYear(int year) Змінює рік дати. Рік задається відносно 1900 року.
void setMonth(int month) Змінює місяць дати, місяці нумеруються з нуля
void setDate(int date) Змінює день місяця
void setHours(int hours) Змінює години
void setMinutes(int minutes) Змінює хвилини
void setSeconds(int seconds) Змінює секунди

5. Мілісекунди

Як ми вже говорили, всередині об'єкта Date зберігається кількість мілісекунд, що пройшли з 1 січня 1970 року.

Якщо вони нам потрібні, ми можемо отримати їх у об'єкта Date:

long time = date.getTime();

Метод getTime() повертає кількість мілісекунд, яке зберігається всередині об'єкта Date.

Ви можете не просто отримати кількість мілісекунд, але й змінити їх у існуючому об'єкті:

Date date = new Date();
date.setTime(1117876500000L);

До речі, можна записати цю конструкцію коротше, передавши час в об'єкт Date прямо під час його створення:

Date date = new Date(1117876500000L);

6. Порівняння дат

Якщо ти хочеш порівняти дві дати і дізнатися, яка з них була раніше, для цього є три способи

Спосіб перший — просто порівняти кількість мілісекунд, яке в них зберігається:

if (date1.getTime() < date2.getTime())

Спосіб другий — використовувати метод before() об'єкта Date:

if (date1.before(date2))

Читається це так: якщо date1 перед date2, то...

Спосіб третій — використовувати метод after() об'єкта Date:

if (date2.after(date1))

Читається це так: якщо date2 після date1, то...


7. Клас DateFormat

Пам’ятаєш, коли ми виводили дату на екран, відображалося щось типу Thu Feb 21 14:01:34 EET 2019. Наче все правильно, але це скоріше відображення дати для програміста. А для користувача хотілося б відображати дату зрозуміліше. Щось на кшталт Вівторок, 21 Лютого.

І без року. Ну або з роком, якщо треба. Загалом, хотілося б відображати дату різними способами.

Для цього є спеціальний клас — SimpleDateFormat.

Приклад:

Код
Date current = new Date(105, 5, 4, 12, 15, 0);
SimpleDateFormat formatter = new SimpleDateFormat("MMM-dd-YYYY");
String message = formatter.format(current);
System.out.println(message);
Вивід на екран
Jun-04-2005

Бачиш, що програма вивела на екран: Jun-04-2005. Це зовсім не те, що було раніше.

А вся справа у тому, що ми відображали не сам об'єкт Date, а спеціальний рядок, отриманий викликом методу format() у об'єкта типу SimpleDateFormat. Але ключове тут навіть не це.

Коли об’єкт SimpleDateFormat створюється, у нього як параметри ми передаємо рядок "MMM-dd-YYYY". Ось в цьому рядку і зашифровано формат дати, який ти побачив у результаті на екрані.

  • MMM означає вивести назву місяця, скорочену до трьох літер
  • dd — вивести день місяця
  • YYYY — вивести рік, що складається з чотирьох цифр

Якщо ми хочемо вивести місяць у вигляді цифр, потрібно замість MMM написати MM: отримаємо рядок "MM-dd-YYYY". На екран буде виведено 06-04-2005

Більш детально ми розберемо цей клас пізніше.


8. Метод Date.parse

Клас Date вміє робити ще одну цікаву і корисну штуку: отримувати дату з текстового рядка. Або як кажуть програмісти, парсити рядок.

Для цього в нього є спеціальний метод — parse(). Процес парсингу виглядає ось так:

Date date = new Date();
date.setTime( Date.parse("Jul 06 12:15:00 2019") );

До речі, цей же код можна записати більш компактно:

Date date = new Date("Jul 06 12:15:00 2019");

Детальніше парсинг рядків ми розберемо в інших лекціях.


Коментарі (23)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
22 вересня 2025
Дійсно, де логіка? В матеріалі перед першою задачею є клас SimpleDateFormat а в задачці слід використовувати switch :(
Natalya Рівень 27
24 липня 2025
Шкода, що в першій задачі не дають скористатися тим же SimpleDateFormat та Locale. Код скоротився б до трьох рядків без громіздкого switch
Andrew Burkut Рівень 17
4 грудня 2023
This way looks bettter :)) for me

    static void fixDate(List<Date> brokenDates) {
        Date currentDate = new Date();

        for (var dates : brokenDates) {
            if (dates.after(currentDate)){
                dates.setYear(currentDate.getYear());
                dates.setMonth(currentDate.getMonth());
            }
        }
    }
}

Sava_crosava Рівень 23
26 жовтня 2023
Написав другу задачу через for(так знаю знаю довго, громіздко та не доречно і код криво написано) Але чому компілятор не прийняв мій код? Результат ж правильний(


    static void fixDate(List<Date> brokenDates) {
        Date now = new Date();
        for (int i = 0; i < brokenDates.size(); i++){
            if (brokenDates.get(i).after(now)){
                Date date = brokenDates.get(i);
                date.setYear(date.getYear()-1900);
                date.setMonth(date.getMonth()-1);
                brokenDates.set(i, date);
            }
        }
    }

Olexandr Рівень 47
28 січня 2024
теж саме було. Тільки FOR ICH валідатор прийняв. Але, я думаю - не проходе тестування тому що є якась різниця в кількості ітерацій. В for ich вона чітко по кількості елементів, а в for - i < brokenDates.size() - десь вже не "грає". Причина саме в цьому, тому що якщо написати i <= brokenDates.size() - все працює, а валідатор видає вже не 1 помилку а 3...
Viacheslav B. Рівень 1
9 квітня 2024
мабуть із за цього що - перша дата - new Date(2015, 12, 25, 20, 40) у виводу у консоль має Tue Jan 25 20:40:00 UTC 3916. тобто місяць вже (JAN) що дорівнює - 0, а у тебе у коді

"date.setMonth(date.getMonth()-1)"
тобто (0 - 1 ) = (-1)
IronMan57 Рівень 28
10 січня 2025
Мені здається, що остання команда лишня. Змінна date - це посилання на елемент в ArrayList. В цих командах:

            date.setYear(date.getYear()-1900);
            date.setMonth(date.getMonth()-1);
вже внесено потрібні зміни, і остання команда

brokenDates.set(i, date);
вже зайва, значення елементу масиву переписується ще раз тим же самим значенням. "Масло масляне".
RMykola Рівень 20
14 березня 2025
@IronMan57, саме Ваш коментар виявився вирішальним у моєму випадку. Дякую!
Ігор Рівень 41 Expert
27 липня 2023
не можу зрозуміти навіщо вивчати клас Date, якщо він застарілий і його не використовують?
Sava_crosava Рівень 23
26 жовтня 2023
Нюанс: Із плином часу з'явилося ще кілька класів для роботи з датою, але клас Date програмісти використовують досі. Тому і вчимо бо інші його використовують досі)
Наталья Рівень 69 Expert
6 квітня 2023
день тижня рахується з неділі . Неділя - 1
Sava_crosava Рівень 23
26 жовтня 2023
Так рахується з неділі але неділя 0)
FAUST_ua Рівень 29
16 вересня 2022
Першу задачу яка наче "Easy" - а вирішити її зовсім не easy з матеріалу лекції. Знову лекція про одне, задача про інше. Друга задача: логіка вирішення зрозуміла, але не вистачає синтаксичних знань. Третю наугад вирішив але хочаб сам )
Grimnir Рівень 18
10 січня 2023
В третій, як підказка, Ідея підсвічує сумнівний елемент коду)
oleh ronin Рівень 47
9 листопада 2023
На те вони і задачки, щоб подумати і пошукати дод. матеріал і інеті, а не пройти матеріал цей в лекції, перейти до задачки і одразу ж її рішити. В реальності в коді такого не буде
Niko Рівень 36
1 серпня 2022
Цікаво як це потрібно зрозуміти що дата вважаеться некоректною. dateList.add(new Date(1989, 11, 9)); Рік, добре, не вірно зазначено але місяць входить в діапазон від 0 до 11.
Anonymous #696530 Рівень 19
14 листопада 2022
Умова завдання якось поганенько сформульована...
boaster Рівень 51
14 червня 2022
Спочатку: -Дивіться, є клас SimpleDateFormat. Потім: -Ні, ні, ні! Не можна його використовувати. Треба через switch. Серйозно?
14 листопада 2022
я цього теж не зрозумів. Зробив через SimpleDateFormat в 2 рядки, а воно хоче switch
Pavlo Kezin Рівень 23
24 вересня 2023
теж здивувався. потім спробував через світч, але хто ж знав, що тижні нумеруються з неділі...
Сергій Ситюк Рівень 21
25 травня 2022
Вопрос к авторам? Накой черт подавать к изучению неактуальный материал? Неужели нельзя подать в формате - вот так делать правильно, а если хотите посмотрите как делали раньше? Сидеть ломать голову над вашей второй задачей которую для начала нужно тридцать раз прочитать что бы понять что вы вообще хотите. Зачем мне это? Просто скипнул лекцию.
Pavlo Kezin Рівень 23
24 вересня 2023
досвід (не у програмуванні) підказує, що іноді треба вивчити, щось неактуальне, щоб зрозуміти природу актуального. Сподіваюсь, що це використовується і тут. І це полегшить сприйняття майбутнього матеріалу.