tl; dr
Никогда не используйте ужасный Calendar
класс.
Используйте современные java.time классы.Эти неизменяемые объекты полностью исключают проблемы, которые вы обнаружили.
ZonedDateTime // Represent a moment using the wall-clock time used by the people of a particular region (a time zone).
.now( // Capture the current moment.
ZoneId.systemDefault() // Get the JVM’s current default time zone. Beware: This can change at any moment during runtime. If crucial, confirm with user.
) // Returns a `ZonedDateTime` object.
.withYear( // Per the immutable objects pattern, produce another object based on the original’s values but with a change.
2001 // Change the year, but copy the month, day-of-month, hour, minute, second, fractional second, and time zone all the same. If the time-of-day is not valid on that date in the other year, auto-adjust per algorithm documented in the JavaDoc.
) // Returns another `ZonedDateTime` object.
java.time
Ужасный класс Calendar
устарел, его давно вытеснили современные java.time классы.
Чтобы зафиксировать текущий момент в UTC, используйте Instant
.
Instant instant = Instant.now();
С этого Instant
вы можете получить количество миллисекунд с той же привязки эпохи, что и Calendar
:первый момент 1970 года в UTC, 1970-01-01T00: 00: 00Z.Остерегайтесь потери данных, поскольку разрешение Instant
составляет наносекунды, намного меньше, чем миллисекунды, используемые в устаревших классах даты и времени, таких как Calendar
.
long millisecondsSinceEpoch = instant.toEpochMilli() ;
Вы можете создать Instant
из этого числа.
Instant instant = Instant.ofEpochMilli( millisecondsSinceEpoch) ;
Чтобы увидеть этот момент через часы настенного времени, используемые людьми определенного региона, применитечасовой пояс (ZoneId
) для получения объекта ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" ) // Or your JVM’s current default, ZoneId.systemDefault().
ZonedDateTime zdt = instant.atZone( z ) ;
Чтобы изменить год, как вы делали это в вопросе, позвоните по номеру withYear
.
ZonedDateTime zdtOtherYear = zdt.withYear( 2001 ) ;
О java.time
Платформа java.time встроена в Java 8и позже.Эти классы вытесняют старые классные устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .
Вы можете обмениваться java.time объектами непосредственно с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти некоторые полезные классы, такие как Interval
, YearWeek
, YearQuarter
и more .