Почему Timestamp печатает разницу между моделью прогона и моделью отладки в модульном тесте?

    java.sql.Date date = java.sql.Date.valueOf("1900-01-01");
    //-2209017600000
    System.out.println(date.getTime());
    java.sql.Timestamp timestamp = new Timestamp(date.getTime());
    System.out.println(timestamp); 

если непосредственно работает в модульном тесте, результат будет 1900-01-01 00:00:00.0

если запустить с отладкой в ​​модульном тесте, результат будет 1970-01-01 07:30:00.0

Как это вывести 1900-01-01 00:00:00.0? Где это хранится?

Почему не выводится 1970-01-01 00:00:00.0? потому что я видел комментарий конструктора Timestamp говорит, что миллисекунды с 1 января 1970 года, 00:00:00 по Гринвичу. Отрицательное число - это количество миллисекунд до 1 января 1970 года, 00:00:00 по Гринвичу.

1 ответ

Решение

ТЛ; др

Избегайте ужасных старых классов даты и времени. Используйте java.time. Пуф, все странное поведение, которое ты видишь, ушло, и твой вопрос спорен.

LocalDate                 // A class to represent a date-only value, without time-of-day, without time zone. Replaces `java.sql.Date` which only pretends to be date-only but actually has both a time-of-day and a time zone.
.parse( "1900-01-01" )    // Standard ISO 8601 formatted strings are parsed directly by the *java.time* classes. 
.atStartOfDay(            // Let java.time determine the first moment of a day.
    ZoneId.of( "Pacific/Auckland" ) 
)                         // Returns a `ZonedDateTime` object.
.toString()               // Generates a `String` with text in standard ISO 8601 format, wisely extended by appending the name of the time zone in square brackets.

1900-01-01T00: 00 + 11: 30 [Pacific / Auckland]

Вы мучаете себя этими Вопросами о старых классах даты и времени. Sun, Oracle и сообщество JCP отказались от этих занятий много лет назад, приняв JSR 310. Я предлагаю вам сделать то же самое.

Никогда не используйте java.sql.Date

Этот класс является частью ужасных старых классов даты и времени, которые были вытеснены несколько лет назад классами java.time. это java.sql.Date особенно плохо продуман. Расширяется java.util.Date в то время как документация говорит нам игнорировать факт этого наследования. Как подкласс, он претендует на значение только для даты, но на самом деле имеет время суток, унаследованное от другого Date который, в свою очередь, неправильно назван, имея дату и время суток. Кроме того, часовой пояс скрывается глубоко внутри этих классов, хотя недоступен без какого-либо метода получения или установки. Смешение? Да, ужасный беспорядок. Никогда не используйте java.sql.Date,

Вместо этого используйте java.time.LocalDate,

LocalDate ld = LocalDate.parse( "1900-01-01" ) ;

ld.toString(): 1900-01-01

Никогда не используйте java.sql.Timestamp

Как с java.sql.Date, java.sql.Timestamp класс был заменен несколько лет назад. использование java.time.Instant, Если передал Timestamp, немедленно конвертировать, используя новые методы конвертации, добавленные к старым классам.

Если вы хотите первый момент дня для конкретной даты, пусть LocalDate определить это. Первый момент не всегда 00:00:00, поэтому никогда не предполагайте это. Укажите часовой пояс региона, в котором люди используют часы, которые вам нужны.

Укажите правильное название часового пояса в формате continent/region, такие как America/Montreal, Africa/Casablanca, или же Pacific/Auckland, Никогда не используйте 3-4 буквенное сокращение, такое как EST или же IST поскольку они не являются истинными часовыми поясами, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;

Чтобы увидеть тот же момент в UTC, извлеките Instant, Instant класс представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).

Instant instant = zdt.toInstant() ;

Если вы хотели первый момент дня в UTC, используйте OffsetDateTime,

OffsetDateTime odt = ld.atOffset( ZoneOffset.UTC ) ;

преобразование

Если вам необходимо взаимодействовать со старым кодом, который еще не обновлен до классов java.time, вы можете конвертировать туда и обратно. Вызовите новые методы, добавленные к старым классам.

java.sql.Timestamp ts = Timestamp.from( instant ) ;

…а также…

Instant instant = ts.toInstant() ;

То же самое для свидания.

java.sql.Date d = java.sql.Date.valueOf( ld ) ;

…а также…

LocalDate ld = d.toLocalDate() ;

О 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 и многое другое.

Другие вопросы по тегам