Как я могу добавить один месяц, чтобы перейти в миллисекунды?

У меня проблема с изменением текущего времени в миллисекунды, миллисекунды отображаются за месяц до установленной даты и времени. Я знаю, что компьютер начинает месяцы с 0, как я могу решить проблему? Сначала я переношу дату и время в String, затем конвертирую String в дату в SimpleDateFormat, а затем конвертирую дату в Long.

Например: когда пользователь вводит дату "2018/2/14 11:18" (AM), дата преобразуется в длинную "1515899940000" .

Вот мой код:

private void  setDateField() {

    Calendar c = Calendar.getInstance();

    int yy = c.get(Calendar.YEAR);
    int mm = c.get(Calendar.MONTH);
    int dd = c.get(Calendar.DAY_OF_MONTH);

    c.set(Calendar.MONTH, mm);
    c.set(Calendar.DAY_OF_MONTH, dd);
    c.set(Calendar.YEAR, yy);

    DatePickerDialog datePickerDialog = new DatePickerDialog(this,android.R.style.Theme_Holo_Light_Dialog ,new DatePickerDialog.OnDateSetListener() {

        @Override
        public void onDateSet(DatePicker datePicker, int selectedYear, int selectedMonth, int selectedDate) {

            year = selectedYear;
            month = selectedMonth;
            day = selectedDate;
            date_time = year + "/" + (month + 1) + "/" + day;
            timePicker();
        }
    },year, month, day);

    datePickerDialog.getDatePicker().setMinDate(c.getTimeInMillis());
    datePickerDialog.show();

}

private void timePicker(){
    // Get Current Time
    final Calendar c = Calendar.getInstance();
    hours = c.get(Calendar.HOUR_OF_DAY);
    minutes = c.get(Calendar.MINUTE);
    // Launch Time Picker Dialog
    TimePickerDialog timePickerDialog = new TimePickerDialog(this,android.R.style.Theme_Holo_Light_Dialog,new TimePickerDialog.OnTimeSetListener() {

                @Override
                public void onTimeSet(TimePicker view, int hourOfDay,int minute) {

                    hours = hourOfDay;
                    minutes = minute;
                    string_date = date_time+" "+format(hours) + ":" +format(minutes) ;
                    addtime.setText(string_date);
                    Log.e("JEJEJEJE",string_date);

                    SimpleDateFormat f = new SimpleDateFormat("yyyy/mm/dd HH:mm");
                    try {
                        Date d = f.parse(string_date);
                        milliseconds = d.getTime();
                        Log.e("LONGGGGGGG", String.valueOf(milliseconds));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }, hours, minutes, true);
    timePickerDialog.show();

}

person Mark    schedule 13.02.2018    source источник
comment
Мне очень непонятно, извините. Не могли бы вы указать точно желаемый результат и разницу между наблюдаемым и желаемым результатом? Также может помочь минимальный, полный и проверяемый пример.   -  person Ole V.V.    schedule 13.02.2018
comment
Подумайте о том, чтобы выбросить давно устаревший и заведомо неприятный SimpleDateFormat и друзей и добавить ThreeTenABP в свой проект Android, чтобы использовать java.time, современный API даты и времени Java. С ним намного приятнее работать.   -  person Ole V.V.    schedule 13.02.2018
comment
Вы проверили те вопросы о выпуске месяца, на которые я ссылался? Я серьезно говорю, что думаю, что они будут вам полезны.   -  person Ole V.V.    schedule 14.02.2018


Ответы (2)


Я предлагаю: Во-первых, вместо ваших переменных (полей?) year, month, day, hours и minutes просто объявите

private LocalDate date;
private LocalTime time;
private long milliseconds;

(Сохраните переменную milliseconds, так как вы захотите получить здесь свой результат.)

В onDateSet присвойте значение date следующим образом:

        date = LocalDate.of(selectedYear, selectedMonth + 1, selectedDate);

Именно здесь мы принимаем во внимание, как вы сказали, что selectedMonth средства выбора даты отсчитывается от 0, а LocalDate нумерует месяцы, как это делают люди, от 1.

Теперь ваш метод timePicker становится

private void timePicker(){
    // Get Current Time
    time = LocalTime.now(ZoneId.systemDefault());
    // Launch Time Picker Dialog
    TimePickerDialog timePickerDialog = new TimePickerDialog(this,
            android.R.style.Theme_Holo_Light_Dialog,
            new TimePickerDialog.OnTimeSetListener() {

                @Override
                public void onTimeSet(TimePicker view, int hourOfDay,int minute) {

                    time = LocalTime.of(hourOfDay, minute);

                    milliseconds = date.atTime(time)
                            .atZone(ZoneId.systemDefault())
                            .toInstant()
                            .toEpochMilli();
                    Log.e("LONGGGGGGG", String.valueOf(milliseconds));
                }
            },
            time.getHour(),
            time.getMinute(),
            true);
    timePickerDialog.show();

}

Вы сильно все усложняли. Я рекомендую:

  1. Не используйте строки для даты или времени в своей бизнес-логике, используйте объекты даты и времени. Это также означает, что вам не нужен модуль форматирования, такой как SimpleDateFormat (который, я могу добавить, печально известен хлопотами, так что хорошо, что вы можете обойтись без него).
  2. Используйте java.time, современный API даты и времени Java. С ним гораздо приятнее работать, чем со старомодными классами даты и времени, такими как Calendar.

Два пункта идут рука об руку в приведенных выше фрагментах. Кроме того, насколько я вижу, вы не используете объект Calendar (c) в setDateField, просто удалите его и все его использование.

Что пошло не так в вашем коде?

Виновником был ваш SimpleDateFormat. Попробуйте использовать его следующим образом:

    SimpleDateFormat f = new SimpleDateFormat("yyyy/mm/dd HH:mm");
    System.out.println(f.parse("2018/04/17 12:45"));

На моем компьютере это печатает

Wed Jan 17 12:45:00 CET 2018

Он печатает дату в январе независимо от того, что находится в строке. Это потому, что вы пробовали mm в нижнем регистре для месяца. mm - это минуты (которые вы также использовали правильно), месяц - MM в верхнем регистре. Таким образом, ваш форматировщик вообще не может анализировать месяц и назначает вашей дате месяц по умолчанию, то есть первый месяц года, январь. И эта январская дата, конечно же, также вошла в ваше значение в миллисекундах.

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

Да, вы можете использовать java.time на Android. Для его использования требуется только Java 6.

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

Ссылки

person Ole V.V.    schedule 17.02.2018

Документация объекта Calendar

Объект Calendar предлагает нам такие методы, как getTimeInMillis() и add(int field, int amount). Добавление выглядит как add(Calendar.MONTH, 1)

person Adrian Grygutis    schedule 13.02.2018
comment
Я добавил его, но когда я хочу, чтобы пользователь выбрал время, оно начинается через месяц после текущего времени. - person Mark; 13.02.2018
comment
я не уверен, что вы хотите сделать. Вы хотите добавить время к какой дате? - person Adrian Grygutis; 14.02.2018