1

I get time with time zone (without date component) from a PostgreSQL server in json like this { "time": "03:00:00+01" }. How do I handle this in Android? Is there any structure which can hold just time without date? Or converting it to the epoch Date representation i.e. Thu Jan 01 03:00:00 GMT+01:00 1970 is the only good solution?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
yaugenka
  • 2,602
  • 2
  • 22
  • 41
  • There are some options. What do you need to with the time in Android? [`OffsetTime`](https://docs.oracle.com/javase/10/docs/api/java/time/OffsetTime.html) from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/) may be the best class for representing the time, but it depends on your needs, so please tell us what they are. – Ole V.V. Mar 04 '20 at 19:07
  • I will point out that a time-of-day with an offset does not really have any meaning. Without the context of a date, the offset does no good. – Basil Bourque Mar 04 '20 at 21:34

3 Answers3

3

OffsetTime from java.time and ThreeTenABP

An OffsetTime is a time of day without date and with an offset from UTC. It thus very precisely models the information in your string from JSON. So I would clearly prefer it over Date. Also because the Date class is poorly designed and long outdated.

    String timeStringFromJson = "03:00:00+01";
    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ssX");
    OffsetTime parsedTime = OffsetTime.parse(timeStringFromJson, timeFormatter);
    System.out.println("Parsed time: " + parsedTime);

Output from this snippet is:

Parsed time: 03:00+01:00

As a detail that may or may not matter to you, the offset from the string is retained, contrary to what Date can do because a Date hasn’t got a time zone or offset.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both 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) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern 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

You can parse your date into a Date object using the SimpleDateFormat with the following pattern:

SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");

try
    {
    Date date = format.parse("03:00:00+01", Locale.getDefault());
    Log.d( "debugDate", " date is: " + date );
    }
catch (ParseException e)
    {
    e.printStackTrace();
    }

Output:

Thu Jan 01 03:00:00 GMT+01:00 1970

In case your date structure become "03:00:00+01:00", you need to use this pattern :

SimpleDateFormat format = new SimpleDateFormat("HH:mm:ssZ", Locale.getDefault());

Output:

Thu Jan 01 03:00:00 GMT+01:00 1970
Kévin Giacomino
  • 487
  • 4
  • 11
  • It still means converting it into a date dependent object. – yaugenka Mar 03 '20 at 13:58
  • Yes, this is not what you want? – Kévin Giacomino Mar 03 '20 at 14:30
  • No, this solution was mentioned in the question itself. I am looking for somthing which can handle time irrespective to date. – yaugenka Mar 03 '20 at 18:11
  • Consider not using 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. Mar 04 '20 at 19:08
  • I got `The method parse(String, ParsePosition) in the type SimpleDateFormat is not applicable for the arguments (String, Locale)`. Correcting this I get the expected output in your time zone and in mine, but when I ran in America/Toronto time zone I got `date is: Thu Jan 01 03:00:00 EST 1970`, which despite the similar look is a completely different point in time. – Ole V.V. Mar 04 '20 at 19:49
0

You can convert the String timestamp to the milliseconds since Epoch as a long value, then store/retrieve the long value and convert it back to a String timestamp as done below in main.

I'm assuming the +01 in your example is for Central European Time.

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

public class SDFTest {

    /**
    Global SimpleDateFormat
    */
    private static SimpleDateFormat sdf = null;

    public static void main(String[] args) {
        // Initialize the Simple Date Format;
        sdf = new SimpleDateFormat("HH:mm:ssX");
        // Ignore this if you need timestamps converted to your local TimeZone;
        sdf.setTimeZone(TimeZone.getTimeZone("CET"));

        // Say this is the supplied time String;
        String suppliedDate = "03:00:00+01";

        // Convert from String timestamp to long;
        long convertedToTimeStamp = getTimeStamp(suppliedDate);
        System.out.println(suppliedDate + " => " + convertedToTimeStamp + "ms");

        // Convert from long timestamp to String;
        String convertedBackToString = getDateString(convertedToTimeStamp);
        System.out.println(convertedToTimeStamp + "ms => " + convertedBackToString);
    }


    /**
    Converts String timestamp to the number of milliseconds since Epoch.
    */
    private static long getTimeStamp(String date_str) {
        try {
            Date date = sdf.parse(date_str);
            return date.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
    Converts long timestamp to String
    */
    private static String getDateString(long timestamp) {
        try {
            Date date = new Date(timestamp);
            return sdf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

Output:

Convert String timestamp to long and back

As the Date component is not present in the suppliedDate it won't ever matter.

electrocrat
  • 446
  • 3
  • 8