2

I have the problem that I cannot format a String, having in form of "270317" (German version), into a Date.

For accomplishing this, I use GWT. What I have so far is this:

String input = "270317";
LocaleInfo locale = null;
if (locale == null) {
    locale = LocaleInfo.getCurrentLocale();
}
date = DateTimeFormat.getFormat(input).parse(input);

The outcome is always the current date: 07/28/2017

What I want to achieve is to have the date as it is written in the country where the program is being executed. If that is not really possible then I would prefer to have it written in this way: 03/27/2017.

Bernd
  • 593
  • 2
  • 8
  • 31
  • Instead of `getFormat(input)`, you should pass the pattern, something like `getFormat("ddMMyy")` –  Jul 28 '17 at 14:14
  • My problem is that I do not know how to get the right pattern for the localization? I want to use the pc`s localization ( someone is using Englisch, someone is using french ). – Bernd Jul 28 '17 at 14:20
  • I don't use GWT very often, but it seems that the predefined formats uses the system's locale: http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsFormatting.html#datetimeformat - *"...use the default formats and let the localization mechanism in the DateTimeFormat do the work for you"* –  Jul 28 '17 at 14:23
  • I tried it but is says the constructor Date(String) is deprecated and doing it the following way crashes: Date date = new Date(input); Date newDate = DateTimeFormat.getShortDateFormat().format(date); – Bernd Jul 28 '17 at 14:41
  • You need another `DateTimeFormat` to parse the input. Probably `date = DateTimeFormat.getFormat("ddMMyy").parse(input)` (if the input is always in this format) or use the default format if the input is also localized. –  Jul 28 '17 at 14:42
  • May I also suggest you to take a look at the new API's: If you're using **Java 8**, there's the [new java.time API](https://docs.oracle.com/javase/tutorial/datetime/). For **Java <= 7**, you can use the [ThreeTen Backport](http://www.threeten.org/threetenbp/), a great backport for Java 8's new date/time classes. And for **Android**, there's the [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) (more on how to use it [here](https://stackoverflow.com/a/38922755/7605325)). –  Jul 28 '17 at 14:45
  • Maybe I understand wrong but it still produces the same error - I always get the today`s date - Date date = new Date(); date = DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).parse(input); – Bernd Jul 28 '17 at 15:07
  • What's your gwt version? I'll try to make a test later. –  Jul 28 '17 at 15:15
  • If I am not totally wrong, it should be 2.7 - thank you very much for your help. I started to work with GWT a few days ago and there popped up an error in our module I have to fix that. – Bernd Jul 28 '17 at 15:28

1 Answers1

2

To parse the input 270317 to a Date, you must provide the expected format (you're using input as the format, which is wrong):

String input = "270317";
Date date = DateTimeFormat.getFormat("ddMMyy").parse(input);

This will parse the date correctly, if the input format is always as day-month-year. If the inputs are produced in a localized format, then you can use DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT) or any other format - but this is locale-specific and it can vary a lot between different environments.

Check your inputs to know if you'll need to use a fixed or a localized format.

After you parsed the date, you can then format it to whatever format you want. If you want a locale-specific format, just use:

DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).format(date);

This is locale specific, so the output can vary. In my system, I've got:

2017-03-27


Java new Date/Time API

Although you're using GWT, this specific code for date parsing/formatting could be handled by a better API. GWT uses java.util.Date, which has lots of problems and design issues.

If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.

If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.

To parse and format a date, you can use a DateTimeFormatter. As you're using only day, month and year, I'm using the LocalDate class (which has only the date fields):

String input = "270317";
// parse the date
DateTimeFormatter parser = DateTimeFormatter.ofPattern("ddMMyy");
LocalDate date = LocalDate.parse(input, parser);

// locale specific format
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
System.out.println(formatter.format(date));

As this is locale specific, in my system I've got the output:

27/03/17

If you want to use exactly the same pattern produced by GWT, you can use:

// get the GWT format
String pattern = DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).getPattern();
// use the same format in the formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
System.out.println(formatter.format(date));

Based on the GWT docs, it seems to use patterns compatible with DateTimeFormatter (at least for date fields), so this should work for all cases.

If you want a fixed format (like 03/27/2017), just do:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");

Check the javadoc for more details about date patterns.

Community
  • 1
  • 1
  • Thank you very much for your support. I will try that on Monday, since I am not at work today and tomorrow. Thanks! – Bernd Jul 29 '17 at 13:44
  • Hi, I tried it and it seems to be good! Now, they changed the request: some people are located in USA, UK, Germany, .., so everyone has a different style of input ( in Germany they write: ddMMyy, in USA they will use MM/dd/YY, and every input should now be transformed to the USA - standard input. Maybe you can help me again? I think it has to be done via localization but Locale is only available in Java, in GWt they use LocaleInfo, but I do not know how to get the user`s localization and then convert it to this pattern: mm/dd/YYYY - Maybe you can help me one again, Thank you very much. – Bernd Jul 31 '17 at 10:02
  • I'm not sure how to configure locales in GWT (maybe [this](http://www.gwtproject.org/doc/latest/DevGuideI18nLocale.html) can help). Maybe you'll have to check each case and try to parse one by one (or check the string before parsing). But to change the output to USA format, just change the formatter above to use `MM/dd/yyyy`. –  Jul 31 '17 at 13:16
  • Could you edit your question, specifying all the date formats for the inputs? The inputs can be from **anywhere** in the world or is there a specific set of formats? If you have a well defined set of formats, just create lots of `DateTimeFormatter`'s for each case (if you know the locale, or where the requests come from, it's better because you'll know which formatter to use - otherwise you'll have to try each one until the parsers succeeds) –  Jul 31 '17 at 13:23
  • 1
    Hi, thank you very much. I will talk through LocalInfo and now they came up with a pattern for our offices in different countries. So, I will implement a case locale: ... and for every locale I will define a different pattern. Thank you so much for helping me. Furthermore, I succeeded in converting everything in this way ( here I use a different package "shared" from GWT ): DefaultDateTimeFormatInfo info = new DefaultDateTimeFormatInfo();DateTimeFormat dtf = new DateTimeFormat(pattern, info) {}; String x = dtf.parse(input); – Bernd Jul 31 '17 at 15:00