Как получить текущую дату и время в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС.миллисекунды в Java?
Проблема в вашем коде
Вы допустили несколько типичных ошибок в шаблоне SimpleDateFormat:
- YYYY — это "week year" (год по неделям), а не календарный год. Для обычного года используйте yyyy.
- DD — это день в году (от 1 до 365/366), а не день месяца. Для дня месяца используйте dd.
- MI — такой паттерн не существует. Минуты обозначаются как mm.
- SS — секунды, правильно: ss.
- mmm — миллисекунды, правильно: SSS (заглавные).
Решение №1: Исправленный SimpleDateFormat (старый способ)
Вот корректный код с использованием старого API java.util.Date:
import java.util.Date;
import java.text.SimpleDateFormat;
public class Main {
public static void main(String[] args) {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String formattedDate = sdf.format(now);
System.out.println(formattedDate); // Вывод: 2023-11-15 14:30:25.123
}
}
Решение №2: Современный способ (Java 8+)
Начиная с Java 8, рекомендуется использовать пакет java.time. Он гораздо удобнее и потокобезопасен:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
String formattedDate = now.format(formatter);
System.out.println(formattedDate); // Вывод: 2023-11-15 14:30:25.123
}
}
Подробное объяснение паттернов
Вот таблица самых часто используемых символов форматирования:
- yyyy — год из 4 цифр (2023)
- MM — месяц из 2 цифр (01-12)
- dd — день месяца из 2 цифр (01-31)
- HH — часы в 24-часовом формате (00-23)
- mm — минуты (00-59)
- ss — секунды (00-59)
- SSS — миллисекунды (000-999)
Важные замечания
1. SimpleDateFormat не потокобезопасен — если вы используете его в многопоточной среде, создавайте новый экземпляр для каждого потока или используйте ThreadLocal.
2. В Java 8+ старый Date и Calendar считаются устаревшими. Новая библиотека java.time решает все проблемы старого API: неизменяемость объектов, потокобезопасность, правильная работа с часовыми поясами.
3. Если вам нужно время с учётом часового пояса, используйте ZonedDateTime:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
ZonedDateTime now = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS z");
System.out.println(now.format(formatter)); // Вывод: 2023-11-15 14:30:25.123 MSK
Надеюсь, теперь стало понятно! Удачи в изучении Java.
<<Альтернативный подход: использование java.util.Calendar
Если по каким-то причинам вы не можете использовать Java 8+, а старый SimpleDateFormat кажется ненадёжным, можно собрать строку вручную через Calendar:
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
String formattedDate = String.format("%04d-%02d-%02d %02d:%02d:%02d.%03d",
cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH) + 1, // Месяцы в Calendar считаются с 0
cal.get(Calendar.DAY_OF_MONTH),
cal.get(Calendar.HOUR_OF_DAY),
cal.get(Calendar.MINUTE),
cal.get(Calendar.SECOND),
cal.get(Calendar.MILLISECOND));
System.out.println(formattedDate);
}
}
Дополнительный совет: используйте библиотеку Joda-Time
Если вы работаете с Java 7 или более ранней версией, отличной альтернативой является библиотека Joda-Time (она была предшественником java.time):
import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(fmt.print(now));
Joda-Time также потокобезопасна и имеет более чистый API по сравнению со старыми классами Java. Однако для новых проектов на Java 8+ лучше использовать встроенный java.time.