Joda Time toDate () неверный результат

Я использую этот код:

date - Дата объекта из DatePicker в виде строки Thu Sep 10 00:00:00 GMT+03:00 2020

mDate = DateTime(date)
           .withHourOfDay(0)
           .withMinuteOfHour(0)
           .withSecondOfMinute(0)
           .withMillisOfSecond(0)
           .toDate()

Результат mDate - Wed Sep 09 03:00:00 GMT+03:00 2020

Что в этом плохого?


person Pavel Poley    schedule 07.09.2020    source источник
comment
почему это правильно? util.date без часового пояса и время joda с часовым поясом?   -  person Pavel Poley    schedule 07.09.2020
comment
Павел Полей - Ваше преобразование неверное, что я уже объяснил в своем ответе. Если вы не скажете мне, что именно вы не можете понять, чем я могу вам помочь? Из-за неправильного преобразования mDate представляет дату и время, отличные от той, которая указана в вашем DatePicker.   -  person Arvind Kumar Avinash    schedule 07.09.2020


Ответы (1)


Вы неправильно конвертируете объект DateTime в java.util.Date. Правильный способ - получить миллисекунды от объекта DateTime и инициализировать java.util.Date миллисекундами.

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Define formatter
        DateTimeFormatter formatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss zZ yyyy");

        // Date-time string from DatePicker
        String strDateTime = "Thu Sep 10 00:00:00 GMT+03:00 2020";

        DateTime dateTime = DateTime.parse(strDateTime, formatter);
        System.out.println(dateTime);

        // No. of milliseconds from the epoch of 1970-01-01T00:00:00Z 
        long millis = dateTime.getMillis();
        System.out.println(millis);

        Date mDate = new Date(millis);
        // Display java.util.Date object in my default time-zone (BST)
        System.out.println(mDate);

        //Display java.util.Date in a different time-zone and using custom format
        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+3"));
        System.out.println(sdf.format(mDate));
    }
}

Вывод:

2020-09-09T21:00:00.000Z
1599685200000
Wed Sep 09 22:00:00 BST 2020
Thu Sep 10 00:00:00 GMT+03:00 2020

Примечание. java.util.Date не представляет объект даты и времени. Это просто означает «нет». миллисекунд из эпохи 1970-01-01T00:00:00Z. У него нет информации о часовом поясе или смещении зоны. Когда вы его распечатываете, Java печатает строку, полученную путем применения часового пояса вашей JVM. Если вы хотите распечатать его в другом часовом поясе, вы можете сделать это с помощью SimpleDateFormat, как показано выше.

Я рекомендую вам перейти с устаревшего и подверженного ошибкам java.util API даты и времени и SimpleDateFormat на современный java.time API даты и времени и соответствующий API форматирования (пакет, java.time.format). Узнайте больше о современном API даты и времени на странице Trail: Date Time < / а>. Если ваш уровень API Android по-прежнему не соответствует Java8, проверьте Как использовать ThreeTenABP в Android Project и API Java 8+, доступные через удаление сахара .

В следующей таблице представлен обзор современных классов даты и времени. : введите описание изображения здесь

person Arvind Kumar Avinash    schedule 07.09.2020
comment
Новый API Java содержит time-zone or zone-offset information? - person Pavel Poley; 07.09.2020
comment
@PavelPoley - Да, я показал это в моем последнем ответе. Я предоставил вам соответствующие ссылки, которые вам следует изучить. Не стесняйтесь сообщить мне, если вы хотите, чтобы я опубликовал еще код. - person Arvind Kumar Avinash; 07.09.2020
comment
Хотя я искренне одобряю переход на java.time, он, к сожалению, был включен в Android только с уровня API 26 (Android O, 8.0), и многие люди по-прежнему ориентируются на более низкие уровни, подобные этому, и поэтому не могут использовать его на Android. Что-то вроде joda-time или threetenbp - их лучший выбор. - person Joachim Sauer; 07.09.2020
comment
Если я использую java.util.date внутри POJO, какой класс в новом API является альтернативой? - person Pavel Poley; 07.09.2020
comment
@PavelPoley - это зависит от того, что вам нужно, например если вам нужен только год, месяц и день, используйте LocalDate. Если вам нужно указать год, месяц, день и время, используйте LocalDateTime. Если вам нужна информация о дате, времени и часовом поясе / смещении зоны, используйте _3 _ / _ 4_. Таблица, которую я опубликовал в своем ответе, дает вам обзор, и вы можете выбрать класс в соответствии с вашими потребностями. - person Arvind Kumar Avinash; 07.09.2020
comment
В основном мне нужно _1 _, _ 2 _, _ 3_, но мне также нужна поддержка day difference и plus days (этой функции нужно время / смещение?), Также этот объект даты должен храниться в документе Firestore - person Pavel Poley; 07.09.2020
comment
@JoachimSauer Joda-Time также не входит в состав Android. В любом случае нам нужно добавить внешнюю зависимость. Так что мы можем просто выбрать backport java.time, ThreeTenABP. - person Ole V.V.; 08.09.2020
comment
@PavelPoley Для года, месяца и дня, разницы в днях и дополнительных дней используйте либо LocalDate из Joda-Time, либо LocalDate из java.time. - person Ole V.V.; 08.09.2020
comment
@Arvind Kumar Avinash Я перешел на Java time api, чтобы делать все вычисления (DAYS.between и plusDays ()), теперь работают нормально, но с поддержкой старого util.date, спасибо за вашу помощь и время. - person Pavel Poley; 08.09.2020
comment
@PavelPoley - Добро пожаловать. Желаю успехов! - person Arvind Kumar Avinash; 08.09.2020