0

I have an issue with a Simple Date Format, I don't know why. This is my algorithm

if (realtimeDeparture != null) {
        int hours = this.realtimeDeparture / 3600;
        int minutes = (this.realtimeDeparture % 3600) / 60;
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        try {
            Calendar cal = Calendar.getInstance(Locale.FRENCH);
            String date = cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH)+1)+ "-" + cal.get(Calendar.DAY_OF_MONTH)+ " " + hours+":"+minutes;
            result = df.parse(date);
}

I have an API which give me a number of seconds after 00h00 (realtimeDeparture) I want to extract from this integer a real Date Object So I did this algorithm but I loose hour I don't know why.

For example, there is some input and result value :

date = 2018-5-7 12:26
result = Mon May 07 00:26:00 GMT+02:00 2018

I tried to check if 07/05/2018 is different than 7/5/2018, but same issue :

date = 2018-05-07 12:26 
result = Mon May 07 00:26:00 GMT+02:00 2018

How I can get my Date Object from a number of second from 00h00 ? Or how I can fix my algorithm ?

rjdkolb
  • 10,377
  • 11
  • 69
  • 89
Shining
  • 425
  • 6
  • 20
  • what is give actual value from server side. what result you want. –  May 07 '18 at 10:41
  • the String date is what I get from server side. the result is not coherent with the sting date, the parsing dosn't work. My value from server : 2018-5-7 12:26 result I want : Mon May 07 12:26:00 GMT+02:00 2018 result I get : Mon May 07 00:26:00 GMT+02:00 2018 – Shining May 07 '18 at 10:46
  • give that data and which format to show that date. –  May 07 '18 at 10:47
  • I don't understand ... I have this string : "2018-5-7 12:26", I want this date : Mon May 07 12:26:00 GMT+02:00 2018 (There is no format, I want a Date Object, I want to parse a string to an object). I don't ask for show a date, but for date obect creation. – Shining May 07 '18 at 10:50
  • 1
    As an aside consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends, and adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project in order to use `java.time`, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. May 07 '18 at 10:58
  • Just use `LocalTime.ofSecondOfDay​(this.realtimeDeparture)`, and you’ve got the object you want. `LocalTime` is a class in `java.time`. – Ole V.V. May 07 '18 at 11:01
  • 2
    @Shining Just a thought or might be a typo, but since you're using the french locale: Are you sure you want to use "hh" for the hour instead of "HH"? According to the [docs](https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html) the lowercase "hh" is for 1-12 am/pm hour while "HH" is for the - in Europe far more common - 0-23 hour format. – tjanu May 07 '18 at 11:47
  • @tjanu That is not just a thought. That is the cause of the error. – Ole V.V. May 07 '18 at 12:31
  • 1
    As Ole V.V. noted, old date-time classes such as `java.util.Date`, `java.util.Calendar`, and `java.text.SimpleDateFormat` are now legacy, supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. Much of the *java.time* functionality is back-ported to Java 6 & Java 7 in the [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) project. Further adapted for earlier Android in the [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP) project. See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque May 07 '18 at 20:29

3 Answers3

1

Your calculation looks fine to me so my guess is the issue is the formatting.

Have you tried using

cal.set(Calendar.HOUR_OF_DAY, hours);
cal.set(Calendar.MINUTE, minutes);

and then getting the date with

Date date = cal.getTime();
Keith Mthunzi
  • 141
  • 1
  • 7
  • I tried A LOT of thing but not that. Works fine, But I don't know why the other algorithm do not work, he was working yesterday afternoon ... Thank you a lot. – Shining May 07 '18 at 10:59
1

Using java.time, the modern Java date and time API, this is so much easier, more straightforward and less error-prone:

    int realtimeDeparture = 44783;
    LocalTime time = LocalTime.ofSecondOfDay(realtimeDeparture);
    System.out.println(time);

This prints:

12:26:23

If you need today’s date at the time of day in question, you need to decide a time zone first, for example:

    ZoneId zone = ZoneId.of("Asia/Bangkok");
    ZonedDateTime dateTime = LocalDate.now(zone).atTime(time).atZone(zone);
    System.out.println(dateTime);

2018-05-07T12:26:23+07:00[Asia/Bangkok]

Question: Why do I need a time zone? Because it is never the same date everywhere on earth. You may specify ZoneId.systemDefault() in order to use the JVM’s time zone setting, which in turn usually comes from the device. It may, however, be changed at any time from another part of your program or another program running in the same JVM.

What went wrong in your code?

In your format pattern string you are using lowercase hh for hours, 12 in your example. hh is for hour within AM or PM, from 01 through 12. When you don’t specify AM or PM, SimpleDateFormat uses AM as default. 12:26 AM means 26 minutes past midnight, the same as 00:26 on a 24 hour clock. So this was what SimpleDateFormat gave you.

You were sort of lucky to test with hour-of-day of 12. Other hours of day work as you would have expected in spite of your bug. Others have made the same error, and it has gone unnoticed for long. For comparison, the modern API would in a similar situation have thrown an exception to make you aware of the missing AM/PM marker. I clearly prefer this behaviour.

Question: Can I use java.time on Android?

Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26, I’m told) the modern API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Try this code..

   String date=" 2018-5-7 12:26";
    SimpleDateFormat spf=new SimpleDateFormat("yyyy-mm-dd hh:mm");
    Date newDate= null;
    try {
        newDate = spf.parse(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    spf= new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy", Locale.ENGLISH);
    date = spf.format(newDate);
    System.out.println(date);

then object want to convert like below code..

        try {
        Date dateToshow=spf.parse(date);
        Log.d("Date object:",dateToshow.toString());
    } catch (ParseException e) {
        e.printStackTrace();
    }
  • thank you, but I don't ask for a string, but a Date Object. – Shining May 07 '18 at 10:55
  • i update my answer again. –  May 07 '18 at 10:58
  • I get `Sun Jan 07 00:26:00 CET 2018`. It’s even more wrong than the erroneous result in the question. It’s very typical of `SimpleDateFormat` to give you an incorrect result and pretend all is well. I discourage using that class at all. – Ole V.V. May 07 '18 at 14:11