Почему форматирование сегодняшней даты в Android Studio дает 19700101?

Вот мой код:

import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.Calendar;

public class MainActivity extends AppCompatActivity {

public static void main(String[] args) {
    Calendar cal = new GregorianCalendar();
    Date date = new Date(System.currentTimeMillis());
    cal.setTime( date );
    if (Calendar.MINUTE < 40) {
        if (Calendar.HOUR_OF_DAY == 0) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
            cal.set(Calendar.HOUR_OF_DAY, 23);
        }
        else
        cal.add(Calendar.HOUR_OF_DAY, -1);
    }
    int z = cal.get(Calendar.DAY_OF_MONTH);
    int w = cal.get(Calendar.HOUR_OF_DAY);
    SimpleDateFormat sdf_nowbasedate = new SimpleDateFormat("yyyyMMdd");
    SimpleDateFormat sdf_nowbasetime = new SimpleDateFormat("HH");

    String baseDate_now = sdf_nowbasedate.format(z);
    String baseTime_now = sdf_nowbasetime.format(w)+ "00";

System.out.println(baseDate_now + " " + baseTime_now);

Результатом, которого я ожидал, будет «20180606 1200» (поскольку сейчас время написания этой статьи - 6 июня 2018 г., 13:12 (корейское время) (корейское время - я живу в Корее)

Но результат "19700101 0900"

Почему возникает эта ошибка?

Вы отладили условие if else?

Jaymin 06.06.2018 06:26

Я рекомендую вам избегать класса SimpleDateFormat. Это не только давно устарело, но и доставит много хлопот. Date и Calendar тоже устарели. Сегодня у нас намного лучше в java.time, современный API даты и времени Java. Кстати, всегда опасно предполагать, что с вашим кодом все в порядке.

Ole V.V. 06.06.2018 09:14
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
117
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

int z = cal.get(Calendar.DAY_OF_MONTH);
int w = cal.get(Calendar.HOUR_OF_DAY);
SimpleDateFormat sdf_nowbasedate = new SimpleDateFormat("yyyyMMdd");
String baseDate_now = sdf_nowbasedate.format(z);    

Во-первых, этот код даже не компилируется. Не существует функции форматирования, которая принимает в качестве параметра целое число. Требуется свидание. Но если предположить, что вы на самом деле каким-то образом делаете дату из этого числа - это сделало бы вашу дату в основном на несколько десятков миллисекунд от времени эпохи, то есть 1 января 1970 года.

Вместо этого передайте дату напрямую в формат.

FWIW, он может компилировать и выдает этот результат, поскольку в суперклассах format(Object) / java.text.DateFormat есть java.text.Format, который принимает любой Number как значение, прошедшее с начала эпохи.

laalto 06.06.2018 07:24
Ответ принят как подходящий

вы должны передать Date в sdf_nowbasedate.format(Date) вместо int ("z" или "w") поскольку вы используете Календарь, вы должны получить дату

String baseDate_now = sdf_nowbasedate.format(cal.getTime());
String baseTime_now = sdf_nowbasetime.format(cal.getTime())+ "00";

java.time

Другие ответы правильно объяснили, почему ваш код дал вам дату 1 января 1970 года. Я хотел бы внести современную правильную версию кода. Думаю, вам нужно что-то вроде этого:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMdd HHmm");
    ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
    if (zdt.getMinute() < 40) {
        zdt = zdt.minusHours(1);
    }
    ZonedDateTime wholeHours = zdt.truncatedTo(ChronoUnit.HOURS);
    String baseNow = wholeHours.format(formatter);
    System.out.println(baseNow);

Выполнив это только что (00:52 в Южной Корее), он напечатал:

20180607 0000

Я использую java.time, современный API даты и времени Java, потому что Calendar, GregorianCalendar, Date и SimpleDateFormat давно устарели и плохо спроектированы, а с java.time гораздо приятнее работать.

Похоже, в вашем коде есть еще одна ошибка. Calendar.MINUTE и Calendar.HOUR_OF_DAY - константы со значениями 12 и 11, поэтому Calendar.MINUTE < 40 всегда будет истинным, а Calendar.HOUR_OF_DAY == 0 - никогда. Вместо этого вы, вероятно, рассчитали cal.get(Calendar.MINUTE) и аналогично для часа дня. Урок, который нужно усвоить: в старых классах очень легко делать ошибки, причем некоторые из них остаются незамеченными, а другие трудно выявить. Я рекомендую вам избегать этих занятий.

Вопрос: Могу ли я использовать java.time на Android?

Да, java.time прекрасно работает как на старых, так и на новых устройствах Android. Просто требуется как минимум Java 6.

  • В Java 8 и новее, а также на новых устройствах Android (как мне сказали, начиная с уровня API 26) современный API встроен.
  • В Java 6 и 7 получите ThreeTen Backport, бэкпорт новых классов (ThreeTen для JSR 310; см. Ссылки внизу).
  • На (более старом) Android используйте Android-версию ThreeTen Backport. Он называется ThreeTenABP. И убедитесь, что вы импортируете классы даты и времени из org.threeten.bp с подпакетами.

Ссылки

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