Formatting dates for display and storage

Asked

Viewed 707 times

0

In this Android app, I have a date field in the SQLITE database table, thus defined:

    String createTable = "CREATE TABLE " + TABLE_RUNS + " ( " +
            _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            COL_RUN_DATE + " DATETIME DEFAULT CURRENT_DATE, " +...

When entering a new record, it automatically places the date as YYYY-MM-DD.

When displaying, I pass the date by this method that returns it in DD/MM/AA format. This is done by calling the following method:

String strDateToShow(String dateToFormat){
    // format date to display
    SimpleDateFormat formatFrom, formatTo;
    formatFrom = new SimpleDateFormat("yyyy-MM-dd");
    formatTo   = new SimpleDateFormat();
    if(dateToFormat != null) {
        try {
            Date mDate = formatFrom.parse(dateToFormat);
            dateToFormat = formatTo.format(mDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    if(dateToFormat == null){
        dateToFormat = formatTo.format(new Date());
    }
    return stringToSpace(dateToFormat);
}

Example: between 2017-01-26 sai 26/01/17

Later, when it comes to updating the record, I try to do the reverse, but it’s not working. Via debug I noticed that there is always an exception in the following commented line:

private String strDateToStore(String dateToFormat){
    // format date
    SimpleDateFormat formatFrom, formatTo;
    formatFrom = new SimpleDateFormat();
    formatTo = new SimpleDateFormat("yyyy-MM-dd");
    if(dateToFormat != null) {
        try {
            Date mDate = formatFrom.parse(dateToFormat); // <-- aqui ocorre a exceção.
            dateToFormat = formatTo.format(mDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    if(dateToFormat == null){
        dateToFormat = formatTo.format(new Date());
    }
    return stringToSpace(dateToFormat);
}

Example: Enters 26/01/17 and leaves 26/01/17 when it should leave 2017-01-26

The display format may vary. If it was always day/month/year, just make it explicit, but the format should be the place where the application is being used.

PS. The solution does not need to use the methods. Just convert from and to that is good.

UPDATE: Due to the content of the answers, it is necessary to clarify a little more the situation.

When the record is generated, the date is automatically inserted into the yyyy-MM-dd format, for example 2017-01-25. Records are shown in a list. At this time, the date is converted to the display format. At some point, the user decides to change the record data and it will update the database, I take the date and convert the display format, whatever, in the format yyyy-MM-dd, which is the core of the proposed issue.

Some remarks:

1) the methods of operations in the database, use a POJO, so I need to reformat the date. If it were an explicit UPDATE (SQL) statement, I could skip the date and it would be kept, but as is the type

database.update(TABLE_RUNS, values, whereClause, null);

I have to take back all my values.

2) My Jerico solution: I will record the original date on tag textView’s date and time to update, instead getText() I’ll use getTag(). Solve, but it’s a branch break. It would be cool (and less asnice) to have one (or two) universal(s) method(s) for converting from/to dates.

3 answers

2

This error happens because you do not put the input format in Simpledateformat, try changing the line below

Of:

formatFrom = new SimpleDateFormat();

To:

formatFrom = new SimpleDateFormat("dd/MM/yy");

You can also use one method to reuse the code, instead of using two virtually equal methods:

private String strToDate(String dateToFormat, String formatIn, String formatOut){
    // format date
    SimpleDateFormat formatFrom, formatTo;
    formatFrom = new SimpleDateFormat(formatIn);
    formatTo = new SimpleDateFormat(formatOut);
    if(dateToFormat != null) {
        try {
            Date mDate = formatFrom.parse(dateToFormat); // <-- aqui ocorre a exceção.
            dateToFormat = formatTo.format(mDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    if(dateToFormat == null){
        dateToFormat = formatTo.format(new Date());
    }
    return stringToSpace(dateToFormat);
}

And call the same method but with different parameters.

For reading:

String dataLeitura = strToDate(data, "yyyy-MM-dd", "dd/MM/yy");

And for writing:

String dataEscrita = strToDate(data, "dd/MM/yy", "yyyy-MM-dd");

  • The dd-MM-yy format reflects the LOCALE. I’m not sure it will always be this format. If it had, it would be solved. It has to pull the format of the date that the device is using?

  • @Renefreak Let me see if I understand your question, in the input information you have to take the format configured in the system to perform the conversion?

  • @Renefreak, if you need Voce you can take the Dateformat of the system with 'Dateformat.getDateFormat(context)' and pass the format as method parameter.

  • what I need: to display the date in the format that the user expects to see their dates, be dd/mm, mm/dd (you don’t know this in advance). What we know is, how the date is stored in the database: yyyy-mm-dd. Look at the answer I gave, with the changes in the code you suggested.

1

What you have to note is that you are entering with a different format than you are using in SimpleDateFormat(). Basically you have to use two formats, one input and one output. For input in this your case would be 26/01/17 and exit 2017-01-26, then the method parameter SimplesDateFormat() respectively would be dd-MM-yy incoming and yyyy-MM-dd output. See the method below how the problem can be solved:

public String convertStringInDate(String str){
    // formato de entrada deve ser 26/01/17 
    SimpleDateFormat dateFormatIn = new SimpleDateFormat("dd-MM-yy", Locale.US);
    SimpleDateFormat dateFormatInOut = new SimpleDateFormat("yyyy-MM-dd", Locale.US);

    Date convertedDate = new Date();
    try {
        convertedDate = dateFormatIn.parse(str);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return String.valueOf(dateFormatInOut.format(convertedDate));
}

For more details, see in the documentation.

EDIT

Important to define the location for the SimpleDateFormat, although sometimes defined as getDefault(), should be taken care because it may not be suitable for all use cases, especially output reading devices. See a note in the documentation:

Default locale is not suitable for output readable by device. The best option is usually Locale.US - this locality is guaranteed to be available on all devices, and is frequently used.

See more details here..

  • The dd-MM-yy format reflects the LOCALE. I’m not sure it will always be this format. If it had, it would be forgotten. It has to pull the format of the date that the device is using?

  • @Renefreak made a mistake, I corrected by editing the answer. It has to pull yes the locale that is configured in your app, although be subject to another question, based on the locale you have the date format.

  • Maybe I’m using the wrong term when speaking on LOCALE. My problem is with this line: SimpleDateFormat dateFormatIn = new SimpleDateFormat("dd-MM-yy", Locale.US); Not with Locale, which either, but I’m not sure that the format will be dd/MM/yy, can be MM/dd/yy or other yet.

  • @Renefreak there is a default format depending on the location, Ex.: yyyy-MM-dd H:m:s, but when you do SimpleDateFormat("dd-MM-yy", Locale.US), you are defining that you want to convert from the default to that, and vice versa. If you define Locale.US, it gives you the certainty that it will always come in this format yyyy-MM-dd HH:mm:ss which is the American format. So for that your case, will not give problem at all,

  • I think I understand (your comment, why the functioning of SimpleDateFormat still confuses me. ). And if the user is in a country that the display should be "MM-dd-yy", will it work? Ah, I’ve updated the question, including with the stick breaker I’ll use if I can’t solve the term.

  • @Renefreak if you set the format of your output as MM-dd-yy and insert a fixed location, always, I always say, it will record in that format of the location who you are setting. For the display, first you will convert that your string rescued from the bank in Date format, and then you can apply the region format. But at first you have to convert to Date, which treatment the OS itself does.

  • @Renefreak to give you more confidence, take a test yourself by changing the language of your application.

Show 3 more comments

0


With the help of colleagues and some modifications to the code, I achieved the desired effect.

This method returns a string formatted as a system date, from a string in yyyy-MM-dd format. Enter 2017-01-26, exit 26-1-17 or 1-26-17, according to the settings of the device.

public String convertDateToShow(String strDate){
    // formato de entrada deve ser 2017-01-17
    SimpleDateFormat dateFormatIn = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
    // sem argumentos, pega o formato do sistema para exibir a data
    SimpleDateFormat dateFormatOut = new SimpleDateFormat();
    // com argumentos formato e locale a saida e sempre a mesma
    //  SimpleDateFormat dateFormatOut = new SimpleDateFormat("dd-MM-yy", Locale.US);
    Date convertedDate = new Date();
    try {
        convertedDate = dateFormatIn.parse(strDate);
    } catch (ParseException e) {
            e.printStackTrace();
    }


    return stringToSpace(String.valueOf(dateFormatOut.format(convertedDate)));
}

// stringToSpace() retorna a string a esquerda do primeiro espaço da string passada.
// necessario porque a conversao retorna dd/MM/yy 12:00 hs
private String stringToSpace(String string){

    int spaceIndex = string.indexOf(" ");
    if(spaceIndex > 0) {
        string = string.substring(0, spaceIndex);
    }
    return string;
}

Returns a string formatted as date in yyyy-MM-dd format, from a string formatted as system date. Enter 26-1-17 or 1-26-17 and exit 2017-26-01

public String convertDateToStore(String strDate){
    // formato de entrada do sistema (dd-MM-yy ou MM-dd-yy ou...)
    // sem argumentos, pega o formato do sistema para exibir a data
    SimpleDateFormat dateFormatIn = new SimpleDateFormat();
    // com argumentos formato e locale a saida e sempre a mesma
    // SimpleDateFormat dateFormatIn = new SimpleDateFormat("dd-MM-yy", Locale.US);
    SimpleDateFormat dateFormatOut = new SimpleDateFormat("yyyy-MM-dd", Locale.US);

    Date convertedDate = new Date();
    try {
        convertedDate = dateFormatIn.parse(strDate);
    } catch (ParseException e) {
            e.printStackTrace();
    }
    return String.valueOf(dateFormatOut.format(convertedDate));
}

And zefini.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.