0

I am reading the date of a textview and i want to know the unix time at 00.00 am.

Working with API 23.

Following is my shot at achieving it:

String sDate = mainBinding.tvTakeTimeCurrentShownDateDateFormat.getText().toString();
      Calendar actuallDate = Calendar.getInstance();

    Log.d(TAG, "oc_bt_TakeTime_lastDate: " + sDate.substring(6,8)+ " " + Integer.parseInt(sDate.substring(6,8)));
    Log.d(TAG, "oc_bt_TakeTime_lastDate: "+ sDate.substring(3,5) + " " + Integer.parseInt(sDate.substring(3,5)));
    Log.d(TAG, "oc_bt_TakeTime_lastDate: " + sDate.substring(0,2) + " " + Integer.parseInt(sDate.substring(0,2)));

      actuallDate.clear();
      actuallDate.set(Integer.parseInt(sDate.substring(6,8)), (Integer.parseInt(sDate.substring(3,5))-1), Integer.parseInt(sDate.substring(0,2)), 0, 0 ,0);

    Log.d(TAG, "oc_bt_TakeTime_lastDate: " + actuallDate.get(Calendar.DAY_OF_MONTH)+actuallDate.get(Calendar.MONTH)+actuallDate.get(Calendar.YEAR));

    Log.d(TAG, "oc_bt_TakeTime_lastDate: " + String.valueOf(actuallDate.getTimeInMillis()));

I casted it to long because I thought it might produce an overflow by casting to an int.

result:

oc_bt_TakeTime_lastDate: 19 19
oc_bt_TakeTime_lastDate: 08 8
oc_bt_TakeTime_lastDate: 24 24
oc_bt_TakeTime_lastDate: 24719
oc_bt_TakeTime_lastDate: -61547472000000
  • Because of .clear() maybe – Yash Aug 24 '19 at 08:28
  • @YashKrishan without `.clear()` it gives me `-61547471999123` – HydroHeiperGen Aug 24 '19 at 08:29
  • is -61547471999123 the value you are getting everytime or its value changes? – Yash Aug 24 '19 at 08:30
  • @YashKrishan the value is "rising" `-61547471999423` – HydroHeiperGen Aug 24 '19 at 08:32
  • 1
    @OleV.V. thank you for this advice, this was just a typo when editing the copied code. The original name is `sDate` – HydroHeiperGen Aug 24 '19 at 14:55
  • FYI, the troublesome date-time classes such as `java.util.Date`, `java.util.Calendar`, & `java.text.SimpleDateFormat` are now legacy, supplanted by the [*java.time*](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) classes. Most *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 (<26) in [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP). See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Aug 24 '19 at 19:53

3 Answers3

4

As you can see on the second-to-last display, you are setting the year 0019, not the year 2019. As getTimeInMillis is set in relation to the epoch time (Jan 1, 1970), you get a negative number.

jmart
  • 2,769
  • 21
  • 36
1

You are overcomplicating things.

java.time and ThreeTenABP

I could not read from your question exactly how your string looks. For this answer I am assuming 24.08.19. If you cannot adapt the answer to your real string, please revert in comments.

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd.MM.uu");
    String sDate = "24.08.19";
    LocalDate actualDate = LocalDate.parse(sDate, dateFormatter);
    System.out.println("Actual date: " + actualDate);
    long epochMilli = actualDate.atStartOfDay(ZoneId.systemDefault())
            .toInstant()
            .toEpochMilli();
    System.out.println("Milliseconds since the epoch: " + epochMilli);

Output on my computer in Europe/Copenhagen time zone is:

Actual date: 2019-08-24
Milliseconds since the epoch: 1566597600000

The Calendar class that you were trying to use is poorly designed and long outdated. You should not use it. For a date use LocalDate from java.time, the modern Java date and time API.

Don’t hand parse your string the way you were doing. The DateTimeFormatter class has been built in for this purpose, so leave the work to it. This also buys you a better validation of the string. uu or yy in a format pattern string will parse a 2-digit year like 19 into a year in the interval from 2000 through 2099.

What went wrong in your code?

jmart is correct: You were setting the year to year 19 common era. That’s 2000 years ago now. Since the epoch from which the milliseconds are counted was in 1970, you’re bound to get a negative number. As you have seen, using the formatter for parsing solves this problem for you.

Question: Can I use java.time on Android API level 23?

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) the modern API comes built-in.
  • In 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
  • I think since my Device is API 23 (edited this in the question, sorry about this), the way I do it is not lets say "nice" but it works. However, thank you for this excellent answer and thx for your advice. – HydroHeiperGen Aug 24 '19 at 16:32
  • 1
    Please re-read the section *Question: Can I use java.time on Android API level 23?* of my answer (I just added the level to the title). @HydroHeiperGen – Ole V.V. Aug 24 '19 at 17:53
0

I'll suggest this workaround:

  1. Create a Date object using current timestamp
  2. Use that object to set your calendar object

    Date d = new Date(timestampLong);
    Calendar actuallDate = Calendar.getInstance();
    actuallDate.setTime(d);

Yash
  • 3,438
  • 2
  • 17
  • 33