1

I recently started coding my really first Android project using Android Studio 3.1.2 and SDK 19.

One of my Objects has Date attributes. At some points I want to display the whole date time or parts of it in a TextView. So I tried it the rookie way and called toString() on my Date. However the displayed text contains elements I didn't define in the SingleDateFormat pattern I used to create the Date Object.

This is how I create the Date on myObject:

Date date1;
Date date2;

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

try {
    date1 = format.parse(json.getString("date_1"));
    dtae2 = format.parse(json.getString("date_2"));
} catch(ParseException e) {
    //error handling stuff
    e.printStackTrace();
}

This is where I want to display the Date on a View:

myTextView.setText("First appearance logged at " + myObject.getDate1().toString());

I expected a String like 2018-08-16 12:14:42 to be displayed. Instead what I get is Thu Aug 12:14:42 GMT +02:00 2018. This seems to be another DateFormat and ignoring my custom pattern.

So my question is, if there's a way to manipulate the output of toString(), so the Date gets displayed in the way I defined in the pattern. Can I somehow pass the pattern to the toString() method?

EDIT

I changed the attributes of my Objects to String type, though it's way easier for presenting. The reason to convert them into a Date is, that I need to calculate the duration between the two guys, but that's not a problem i can't solve. Thanks to the community.

procra
  • 535
  • 4
  • 29
  • To actually answer your question, subclass SimpleDateFormat and override the toString function. I personally would not do this as there are easier approaches to what you want to achieve – Zun Aug 16 '18 at 10:25
  • 1
    @InsaneCat I am sure the asker will be able to find all the answers, including yours, without a reference from these comments. Your comment has an aggressive smell to it, and it would suit you to remove it. – Ole V.V. Aug 16 '18 at 17:59
  • 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. Aug 16 '18 at 17:59
  • Possible duplicate of [return date type with format in java](https://stackoverflow.com/questions/50485203/return-date-type-with-format-in-java) – Ole V.V. Aug 16 '18 at 18:01
  • Storing your date-times as strings is the wrong solution. Better to use a proper date-time type and then format it (typically using a built-in format) when you need to present it to a user, like in a `TextView`. – Ole V.V. Aug 16 '18 at 18:02
  • 1
    FYI, the troublesome 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 Aug 18 '18 at 21:13

5 Answers5

1

According to your need, you can just use json.getString("date_1").

You don't need to set extra logics. Parsing is needed when you want to convert String date to Date object for some calculation.

If you want to change format of received date then use this method.

changeStringDateFormat(json.getString("date_1"), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");

Just put this method inside your Util.

public String changeStringDateFormat(String date, String inputDateFormat, String outPutDateFormat) {
    Date initDate = null;
    try {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(inputDateFormat);
        initDate = simpleDateFormat.parse(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    SimpleDateFormat outputFormatter = new SimpleDateFormat(outPutDateFormat);
    String parsedDate = outputFormatter.format(initDate);
    return parsedDate;
}

See Java Date Doc, It returns string from default format.

public String toString()

Converts this Date object to a String of the form:

dow mon dd hh:mm:ss zzz yyyy

Community
  • 1
  • 1
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
  • i think this leads to the solution I thought of. The twist is I need them as Date objects t later calculate the difference between these two guys, before I actually just passed the string from the json. – procra Aug 16 '18 at 10:30
  • 1
    Okay, then use `json.getString("date_1")` for showing and your parsing method is correct. Also toString() does not return in format you want. If you want get string date then you have to again parse date from date. – Khemraj Sharma Aug 16 '18 at 10:32
  • since i got a NullPointerException on SimpleDateFormat.format() now, i'll try your suggestion :D – procra Aug 16 '18 at 11:25
  • With some little or bigger workarounds this works for me – procra Aug 16 '18 at 11:37
  • I don't think you have to do some extra effort, show your code, I will update it. – Khemraj Sharma Aug 16 '18 at 11:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/178130/discussion-between-procra-and-khemraj). – procra Aug 16 '18 at 11:52
1

Simply Write this code snippet

JAVA FILE

 public class MainActivity extends AppCompatActivity {
    TextView my_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        my_text = findViewById(R.id.my_text);

        String pattern = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        String date = simpleDateFormat.format(new Date());
        Toast.makeText(getApplicationContext(), "" + date, Toast.LENGTH_SHORT).show();
        my_text.setText("Your Date is :  " + date);
    }
}

XML FILE

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="mydemo.com.anew.MainActivity">

    <TextView
        android:id="@+id/my_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

See output:

enter image description here

See Screenshot of output same like your requirement get a current date:

enter image description here

Refer this Tutorial

Hope this may help to you

InsaneCat
  • 2,115
  • 5
  • 21
  • 40
1

tl;dr

Use the modern java.time classes instead of the terrible legacy Date & SimpleDateFormat classes.

myJavaUtilDate          // Never use `java.util.Date`.
.toInstant()            // Convert from legacy class to modern replacement. Returns a `Instant` object, a moment in UTC.
.atOffset(              // Convert from the basic `Instant` class to the more flexible `OffsetDateTime` class.
    ZoneOffset.UTC      // Constant defining an offset-from-UTC of zero, UTC itself.
)                       // Returns a `OffsetDateTime` object.
.format(                // Generate a `String` with text representing the value of this `OffsetDateTime` object.
    DateTimeFormatter.ISO_LOCAL_DATE_TIME  // Pre-defined formatter stored in this constant. 
)                       // Returns a `String` object.
.replace( "T" , " " )   // Replace the standard `T` in the middle with your desired SPACE character.

2018-08-16 10:14:42

java.time

You are using terrible old classes that were supplanted years ago by the java.time classes.

If handed a java.util.Date object, immediately convert to java.time.Instant. Both represent a moment in UTC. Instant has a finer resolution of nanoseconds rather than milliseconds.

To convert between the legacy and modern classes, look to new conversion methods added to the old classes.

Instant

Instant instant = myJavaUtilDate.toInstant() ;  // New method on old class for converting to/from java.time classes.

ISO 8601

To generate a String with text in standard ISO 8601 format similar to your desired format, call toString.

String output = instant.toString() ;  // Generate text in standard ISO 8601 format.

Elapsed time = Duration

By the way, to calculate elapsed time, use the Duration classes. Pass a pair of Instant objects to calculate the number of 24-hour "days", hours, minutes, and seconds elapsed.

Duration d = Duration.between( start , stop ) ;  // Calc elapsed time.

2018-08-16T10:14:42Z

OffsetDateTime

For other formatting, convert from the basic Instant class to the more flexible OffsetDateTime class.

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

odt.toString(): 2018-08-16T10:14:42Z

DateTimeFormatter

Your desired format is close to the predefined formatter DateTimeFormatter.ISO_LOCAL_DATE_TIME. Just replace the T in the middle with a SPACE.

String output = odt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
                   .replace( "T" , " " ) ;

2018-08-16 10:14:42

ZonedDateTime

Keep in mind that we are only looking at UTC so far. For any given moment, the date and the time-of-day both vary around the globe by zone.

If you want to see that same moment through the lens of the wall-clock time used by the people of a certain region (a time zone), then apply a ZoneId to get a ZonedDateTime object.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

zdt.toString(): 2018-08-16T11:14:42+01:00[Africa/Tunis]

You can use the same formatter as seen above to generate a string in your desired format.

String output = zdt.format( f ) ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

You need to use SimpleDateFormat something like this:

String myFormat = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
myTextView.setText("First appearance logged at " + sdf.format(date1));
Rahul Khurana
  • 8,577
  • 7
  • 33
  • 60
  • this would only remove the GMT part, i also want the month to be presented as number and leave out the day of week – procra Aug 16 '18 at 11:16
0

In my project I've been formatting using the format() function, like so:

myTextView.setText("First appearance logged at " + format.format(myObject.getData1()));

I hope that helps.

Shai
  • 101
  • 1
  • 11