1

I am using this code:

date - Date object from DatePicker, as string Thu Sep 10 00:00:00 GMT+03:00 2020

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

The result mDate - Wed Sep 09 03:00:00 GMT+03:00 2020

What wrong with this?

Pavel Poley
  • 5,307
  • 4
  • 35
  • 66
  • why it is correct? util.date without time zone and joda time with time zone? – Pavel Poley Sep 07 '20 at 14:05
  • Pavel Poley - Your conversion is wrong which I've already explained in my answer. Unless you tell me what exactly you are not able to understand, how can I help you further? Because of your wrong conversion, `mDate` represents a different date-time from the one which is there in your `DatePicker`. – Arvind Kumar Avinash Sep 07 '20 at 14:08

1 Answers1

2

You are not converting the DateTime object to java.util.Date correctly. A correct way is to get the milliseconds from DateTime object and initialize the java.util.Date with the milliseconds.

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));
    }
}

Output:

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

Note: java.util.Date does not represent a Date/Time object. It simply represents the no. of milliseconds from the epoch of 1970-01-01T00:00:00Z. It does not have any time-zone or zone-offset information. When you print it, Java prints the string obtained by applying the time-zone of your JVM. If you want to print it in some other timezone, you can do so using the SimpleDateFormat as shown above.

I recommend you switch from the outdated and error-prone java.util date-time API and SimpleDateFormat to the modern java.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time. If your Android API level is still not compliant with Java8, check How to use ThreeTenABP in Android Project and Java 8+ APIs available through desugaring.

The following table shows an overview of modern date-time classes: enter image description here

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • The new Java api contains `time-zone or zone-offset information`? – Pavel Poley Sep 07 '20 at 13:12
  • 1
    @PavelPoley - Yes, I had shown it in my last [answer](https://stackoverflow.com/a/63774901/10819573). I've provided you with relevant links which you should explore. Feel free to let me know if you want me to post some more code. – Arvind Kumar Avinash Sep 07 '20 at 13:14
  • While I wholeheartedly approve of switching to `java.time` it's unfortunately only been included in Android since API Level 26 (Android O, 8.0) and many people are still targeting lower levels like that and thus can't use it on Android. Something like joda-time or threetenbp is their best bet. – Joachim Sauer Sep 07 '20 at 13:25
  • If I where using `java.util.date` inside POJO's, which class in the new api is the alternative? – Pavel Poley Sep 07 '20 at 13:34
  • @PavelPoley - It depends on what you need e.g. if you need just year, month and day, you should go with `LocalDate`. If you need to have year, month, day, and time, you should go with `LocalDateTime`. If you need date, time and time-zone/zone-offset information, you should go with `ZonedDateTime`/`OffsetDateTime`. The table which I have posted in my answer gives you an overview and you can choose the class as per your need,. – Arvind Kumar Avinash Sep 07 '20 at 13:38
  • Basically I need `year`,`month`,`day`, but I also need support for `day difference` and `plus days`(this function need time/offset?), also this date object should be stored in Firestore document – Pavel Poley Sep 07 '20 at 13:43
  • 2
    @JoachimSauer Joda-Time isn’t included in Android either. We need to add an external dependency anyway. So we may just as well pick the backport of java.time, [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP). – Ole V.V. Sep 08 '20 at 04:53
  • @PavelPoley For year, month and day, day difference and plus days use either `LocalDate` from Joda-Time or `LocalDate` from java.time. – Ole V.V. Sep 08 '20 at 04:54
  • 1
    @Arvind Kumar Avinash I migrated to Java time api, to do all the calculations (DAYS.between and plusDays()), work fine now, but with support to old util.date, thank you for your help and time. – Pavel Poley Sep 08 '20 at 08:53
  • @PavelPoley - You are most welcome. Wish you success! – Arvind Kumar Avinash Sep 08 '20 at 08:54