-2

I have a DatePicker element ("DPstart").
I want to save the timestamp (in milliseconds) of midnight at the string "newStartDate", Without regard to the time zone of the user.
How can I do this?

DatePicker DPstart = (DatePicker) findViewById(R.id.datePickerStart);
Calendar calendar = new GregorianCalendar(DPstart.getYear(), DPstart.getMonth(), DPstart.getDayOfMonth());
long DPS = calendar.getTimeInMillis();
String newStartDate = Long.toString(DPS);
E.S
  • 1
  • 6
  • Duplicate question: https://stackoverflow.com/questions/5236052/get-gmt-time-in-java – SPlatten Sep 04 '17 at 13:09
  • Do you mean like in [this question: Convert Date to Milliseconds in Java](https://stackoverflow.com/questions/24817528/convert-date-to-milliseconds-in-java)? Or [this one: How to convert a date to milliseconds](https://stackoverflow.com/questions/26637168/how-to-convert-a-date-to-milliseconds)? – Ole V.V. Sep 04 '17 at 13:53
  • Does your code do the job? If not, what precisely is the difference between expected and observed behaviour? – Ole V.V. Sep 04 '17 at 13:59

2 Answers2

5

ThreeTenABP

My suggestion is you skip the outdated classes Calendar and GregorianCalendar and start using the modern Java date and time API. It’s much nicer to work with. Even when DatePicker return values are designed for use with the old classes. And even when the modern API isn’t native on very many Android phones yet (that will come).

You will need to get the ThreeTenABP library. Useful question: How to use ThreeTenABP in Android Project. Then your code could go like this:

    long dps = LocalDate.of(dpStart.getYear(), Month.values()[dpStart.getMonth()],
                            dpStart.getDayOfMonth())
            .atStartOfDay(ZoneOffset.UTC)
            .toInstant()
            .toEpochMilli();
    String newStartDate = Long.toString(dps);

Picking 4 September 2017, the result will be 1504483200000.

My way of converting from the date picker’s 0-based month to LocalDate’s more human 1-based month is a bit peculiar. If you find it simpler just to add 1, that will work too:

    long dps = LocalDate.of(dpStart.getYear(), dpStart.getMonth() + 1, dpStart.getDayOfMonth())
            // …

I have renamed your variables to conform with Java coding conventions. They say a variable name should begin with a lowercase letter.

As an aside, I believe that accepted best practices for storing timestamps is you store either the Instant you get from toInstant() or its string representation (from toString()) rather than the millisecond value. Millisecond values are very hard for most of us to interpret, for example when we see them in the debugger. Instant values are readily understood, at least roughly what time they refer to. An even better human-readable format would be the string representation of the LocalDate, it looks like 2017-09-04. The string representations of both Instant and LocalDate conform with ISO 8601.

The outdated solution

If you definitely don’t want to rely in a third party library like ThreeTenABP, even temporarily until the modern date and time API comes to Android, I believe the solution with Calendar is (1) make sure it uses UTC time zone (2) clear the hours, minutes, seconds and milliseconds to make sure you get the time at midnight:

    Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    calendar.clear();
    calendar.set(dpStart.getYear(), dpStart.getMonth(), dpStart.getDayOfMonth());

The result is the same as above.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0
public Long timestampFromString(String format,String time){
        // format example "yyyy.MM.dd hh:mm"
        DateFormat formatter = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = formatter.parse(time);
            return date.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    public String stringFromTimestamp(String format,Long time){
        Timestamp timestamp = new Timestamp(time);
        return new SimpleDateFormat(format).format(timestamp);
    }
  • Thanks for wanting to contribute. Three points: (1) Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. Today we have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. Yes, you can use it on Android. For older Android see [How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). — – Ole V.V. May 19 '20 at 03:46
  • — (2) It’s like it’s answering a different question, isn’t it? (3) Please include some explanation with your answers. How the code works and not least how it answers the question (if it does :-) It’s from the explanations that we all learn. – Ole V.V. May 19 '20 at 03:47