Format String into Date considering localization in GWT - java

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.

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.

Related

How to convert date from English to Arabic

I have this code
frame.sigdate.setText(new SimpleDateFormat("yyyy/M/d").format(new Date()));
which reads the date from my PC with English numbers. What I want to do is convert the date to Arabic numbers.
Is there anything like Local.ar ?
I appreciate any help.
java.time
Locale arabicLocale = Locale.forLanguageTag("ar");
DateTimeFormatter arabicDateFormatter
= DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(arabicLocale)
.withDecimalStyle(DecimalStyle.of(arabicLocale));
LocalDate today = LocalDate.now(ZoneId.of("Asia/Muscat"));
System.out.println(today.format(arabicDateFormatter));
Output:
١٥‏/٤‏/٢٠١٨
The key is withDecimalStyle. Without this call, the formatter would still use western numerals, as in 15‏/4‏/2018. You may want to use a more specific language tag than just ar for Arabic, for example ar-BH for Bahrain or ar-YE for Yemen. See the link at the bottom for possibilities. You should also insert your desired time zone where I put Asia/Muscat.
EDIT: The above has been tested in Java 9. Surprisingly in Java 8 it still uses western (unlocalized) digits. A possible fix (or workaround if you like) is to specify the zero digit explicitly — it will pick up the other digits from it.
DecimalStyle arabicDecimalStyle
= DecimalStyle.of(arabicLocale).withZeroDigit('٠');
DateTimeFormatter arabicDateFormatter
= DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(arabicLocale)
.withDecimalStyle(arabicDecimalStyle);
It’s an Arabic zero between the two apostrophes in the argument to withZeroDigit. Now I get this output on Java 8:
١٥/٠٤/١٨
It’s usually a good idea to use the built-in locale specific formats as I do with ofLocalizedDate in both snippets above. If you need finer control over the format, use ofPattern instead. For example, to get yyyy/mm/dd format:
DateTimeFormatter arabicDateFormatter
= DateTimeFormatter.ofPattern("uuuu/MM/dd", arabicLocale)
.withDecimalStyle(arabicDecimalStyle);
Output:
٢٠١٨/٠٤/١٥
The reason why the format changed from Java 8 to Java 9 is that Java has changed the defaults for where the locale data come from, including the built-in localized date and time formats. You can get the Java 9 format already in Java 8 by setting a system property, for example like this:
System.setProperty("java.locale.providers", "CLDR,JRE,SPI");
With this change the first code snippet above gives the same output on Java 8 as on Java 9:
١٥‏/٤‏/٢٠١٨
The important detail here is that CLDR goes first in the property string. And the advantages are you don’t need to specify your own format pattern string, localization to other locales is straightforward and users won’t be surprised by a change in behaviour once you switch to Java 9 or later.
I am using and recommending java.time, the modern Java date and time API. The SimpleDateFormat class that you used in the question is not only long outdated, it is also notoriously troublesome. IMHO you should avoid it completely. The modern API is so much nicer to work with.
Links
Oracle tutorial: Date Time explaining how to use java.time.
List of supported locales in Java 8
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/MM/yyyy");
String date = "16/08/2011";
Locale arabicLocale = Locale.forLanguageTag("ar-SA");
DateTimeFormatter arabicDateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(arabicLocale).withDecimalStyle(DecimalStyle.of(arabicLocale));
LocalDate today = LocalDate.now(ZoneId.of("Asia/Muscat"));
today = LocalDate.parse(date, formatter);
String dat = today.format(arabicDateFormatter);
System.out.println(dat);
out put ١٦‏/٨‏/٢٠١١
try below approch
java.util.Locale locale = new java.util.Locale("ar");
java.text.DecimalFormat df = (java.text.DecimalFormat)
java.text.DecimalFormat.getNumberInstance(locale);
DateTime dateTimeObjectInUTC = new DateTime(DateTimeZone.UTC);
DateTimeZone dateTimeZoneObject = DateTimeZone.forID("Asia/Riyadh");
java.util.Locale locale = new Locale("ar","SA");
DateTimeFormatter formatter = DateTimeFormat.forStyle("FF").withLocale(locale).withZone(dateTimeZoneObject);
String output = formatter.print(dateTimeObjectInUTC);
This should help!
I am using Joda-Time. Please refer to the Jodatime documentation. DateTimeZone documentation, for example.

convert string timestamp to ISO 8601 compliant string

I have a timestamp and offset in string format as shown below in two different variables:
01/14/2016 07:37:36PM
-08:00
I want to convert above timestamp into ISO 8601 compliant String, with milliseconds and timezone so it should look like this after conversion:
2016-01-14T19:37:36-08:00
How can I do that? I am using jodatime library.
The newer java.time classes work so well with ISO 8601 strings.
String dateTimeString = "01/14/2016 07:37:36PM";
String offsetString = "-08:00";
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString,
DateTimeFormatter.ofPattern("MM/dd/uuuu hh:mm:ssa"));
ZoneOffset offset = ZoneOffset.of(offsetString);
String formattedTimestamp = dateTime.atOffset(offset).toString();
System.out.println(formattedTimestamp);
This prints
2016-01-14T19:37:36-08:00
Stay away from outdated classes like SimpleDateFormat.
What is offsetString is not present? I understand that in this case you want an offset of Z for UTC. For example like this:
ZoneOffset offset;
if (offsetString == null) {
offset = ZoneOffset.UTC;
} else {
offset = ZoneOffset.of(offsetString);
}
String formattedTimestamp = dateTime.atOffset(offset).toString();
With a null offsetString we now get
2016-01-14T19:37:36Z
The classes in java.time (of which I’m using but a few) are described in JSR-310 and come built-in with Java 8. What if you would like to use them with Java 6 or 7? You get the ThreeTen Backport (link below). It gives you the majority of the classes for Java 6 and 7. I’m not perfectly happy to tell you you need an external library, but in this case it’s only until you move to Java 8. I hope you will soon.
I am sure it can be done with JodaTime too, but I haven’t got experience with it, so cannot give you the details there. What I do know, I have read the the folks behind JodaTime now recommend you move over to java.time instead. So I am asking you to swap one external library for a newer (and supposedly better) one. In itself I’m not unhappy with that. Only if you already have a codebase that uses JodaTime, it’s not really trivial.
Link: ThreeTen Backport
You can find more examples in section Examples at :- http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
String string2 = "2001-07-04T12:08:56.235-07:00";
Date result2 = df2.parse(string2);

get calendar pattern for a given locale [duplicate]

It is quite easy to format and parse Java Date (or Calendar) classes using instances of DateFormat.
I could format the current date into a short localized date like this:
DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
String today = formatter.format(new Date());
My problem is that I need to obtain this localized pattern string (something like "MM/dd/yy").
This should be a trivial task, but I just couldn't find the provider.
For SimpleDateFormat, You call toLocalizedPattern()
EDIT:
For Java 8 users:
The Java 8 Date Time API is similar to Joda-time. To gain a localized pattern we can use class
DateTimeFormatter
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
Note that when you call toString() on LocalDate, you will get date in format ISO-8601
Note that Date Time API in Java 8 is inspired by Joda Time and most solution can be based on questions related to time.
For those still using Java 7 and older:
You can use something like this:
DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
String pattern = ((SimpleDateFormat)formatter).toPattern();
String localPattern = ((SimpleDateFormat)formatter).toLocalizedPattern();
Since the DateFormat returned From getDateInstance() is instance of SimpleDateFormat.
Those two methods should really be in the DateFormat too for this to be less hacky, but they currently are not.
It may be strange, that I am answering my own question, but I believe, I can add something to the picture.
ICU implementation
Obviously, Java 8 gives you a lot, but there is also something else: ICU4J. This is actually the source of Java original implementation of things like Calendar, DateFormat and SimpleDateFormat, to name a few.
Therefore, it should not be a surprise that ICU's SimpleDateFormat also contains methods like toPattern() or toLocalizedPattern(). You can see them in action here:
DateFormat fmt = DateFormat.getPatternInstance(
DateFormat.YEAR_MONTH,
Locale.forLanguageTag("pl-PL"));
if (fmt instanceof SimpleDateFormat) {
SimpleDateFormat sfmt = (SimpleDateFormat) fmt;
String pattern = sfmt.toPattern();
String localizedPattern = sfmt.toLocalizedPattern();
System.out.println(pattern);
System.out.println(localizedPattern);
}
ICU enhancements
This is nothing new, but what I really wanted to point out is this:
DateFormat.getPatternInstance(String pattern, Locale locale);
This is a method that can return a whole bunch of locale specific patterns, such as:
ABBR_QUARTER
QUARTER
YEAR
YEAR_ABBR_QUARTER
YEAR_QUARTER
YEAR_ABBR_MONTH
YEAR_MONTH
YEAR_NUM_MONTH
YEAR_ABBR_MONTH_DAY
YEAR_NUM_MONTH_DAY
YEAR_MONTH_DAY
YEAR_ABBR_MONTH_WEEKDAY_DAY
YEAR_MONTH_WEEKDAY_DAY
YEAR_NUM_MONTH_WEEKDAY_DAY
ABBR_MONTH
MONTH
NUM_MONTH
ABBR_STANDALONE_MONTH
STANDALONE_MONTH
ABBR_MONTH_DAY
MONTH_DAY
NUM_MONTH_DAY
ABBR_MONTH_WEEKDAY_DAY
MONTH_WEEKDAY_DAY
NUM_MONTH_WEEKDAY_DAY
DAY
ABBR_WEEKDAY
WEEKDAY
HOUR
HOUR24
HOUR_MINUTE
HOUR_MINUTE_SECOND
HOUR24_MINUTE
HOUR24_MINUTE_SECOND
HOUR_TZ
HOUR_GENERIC_TZ
HOUR_MINUTE_TZ
HOUR_MINUTE_GENERIC_TZ
MINUTE
MINUTE_SECOND
SECOND
ABBR_UTC_TZ
ABBR_SPECIFIC_TZ
SPECIFIC_TZ
ABBR_GENERIC_TZ
GENERIC_TZ
LOCATION_TZ
Sure, there are quite a few. What is good about them, is that these patterns are actually strings (as in java.lang.String), that is if you use English pattern "MM/d", you'll get locale-specific pattern in return. It might be useful in some corner cases. Usually you would just use DateFormat instance, and won't care about the pattern itself.
Locale-specific pattern vs. localized pattern
The question intention was to get localized, and not the locale-specific pattern. What's the difference?
In theory, toPattern() will give you locale-specific pattern (depending on Locale you used to instantiate (Simple)DateFormat). That is, no matter what target language/country you put, you'll get the pattern composed of symbols like y, M, d, h, H, M, etc.
On the other hand, toLocalizedPattern() should return localized pattern, that is something that is suitable for end users to read and understand. For instance, German middle (default) date pattern would be:
toPattern(): dd.MM.yyyy
toLocalizedPattern(): tt.MM.jjjj (day = Tag, month = Monat, year = Jahr)
The intention of the question was: "how to find the localized pattern that could serve as hint as to what the date/time format is". That is, say we have a date field that user can fill-out using the locale-specific pattern, but I want to display a format hint in the localized form.
Sadly, so far there is no good solution. The ICU I mentioned earlier in this post, partially works. That's because, the data that ICU uses come from CLDR, which is unfortunately partially translated/partially correct. In case of my mother's tongue, at the time of writing, neither patterns, nor their localized forms are correctly translated. And every time I correct them, I got outvoted by other people, who do not necessary live in Poland, nor speak Polish language...
The moral of this story: do not fully rely on CLDR. You still need to have local auditors/linguistic reviewers.
You can use DateTimeFormatterBuilder in Java 8. Following example returns localized date only pattern e.g. "d.M.yyyy".
String datePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, null, IsoChronology.INSTANCE,
Locale.GERMANY); // or whatever Locale
The following code will give you the pattern for the locale:
final String pattern1 = ((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale)).toPattern();
System.out.println(pattern1);
Java 8 provides some useful features out of the box for working with and formatting/parsing date and time, including handling locales. Here is a brief introduction.
Basic Patterns
In the simplest case to format/parse a date you would use the following code with a String pattern:
DateTimeFormatter.ofPattern("MM/dd/yyyy")
The standard is then to use this with the date object directly for formatting:
return LocalDate.now().format(DateTimeFormatter.ofPattern("MM/dd/yyyy"));
And then using the factory pattern to parse a date:
return LocalDate.parse(dateString, DateTimeFormatter.ofPattern("MM/dd/yyyy"));
The pattern itself has a large number of options that will cover the majority of usecases, a full rundown can be found at the javadoc location here.
Locales
Inclusion of a Locale is fairly simple, for the default locale you have the following options that can then be applied to the format/parse options demonstrated above:
DateTimeFormatter.ofLocalizedDate(dateStyle);
The 'dateStyle' above is a FormatStyle option Enum to represent the full, long, medium and short versions of the localized Date when working with the DateTimeFormatter. Using FormatStyle you also have the following options:
DateTimeFormatter.ofLocalizedTime(timeStyle);
DateTimeFormatter.ofLocalizedDateTime(dateTimeStyle);
DateTimeFormatter.ofLocalizedDateTime(dateTimeStyle, timeStyle);
The last option allows you to specify a different FormatStyle for the date and the time. If you are not working with the default Locale the return of each of the Localized methods can be adjusted using the .withLocale option e.g
DateTimeFormatter.ofLocalizedTime(timeStyle).withLocale(Locale.ENGLISH);
Alternatively the ofPattern has an overloaded version to specify the locale too
DateTimeFormatter.ofPattern("MM/dd/yyyy",Locale.ENGLISH);
I Need More!
DateTimeFormatter will meet the majority of use cases, however it is built on the DateTimeFormatterBuilder which provides a massive range of options to the user of the builder. Use DateTimeFormatter to start with and if you need these extensive formatting features fall back to the builder.
Please find in the below code which accepts the locale instance and returns the locale specific data format/pattern.
public static String getLocaleDatePattern(Locale locale) {
// Validating if Locale instance is null
if (locale == null || locale.getLanguage() == null) {
return "MM/dd/yyyy";
}
// Fetching the locale specific date pattern
String localeDatePattern = ((SimpleDateFormat) DateFormat.getDateInstance(
DateFormat.SHORT, locale)).toPattern();
// Validating if locale type is having language code for Chinese and country
// code for (Hong Kong) with Date Format as - yy'?'M'?'d'?'
if (locale.toString().equalsIgnoreCase("zh_hk")) {
// Expected application Date Format for Chinese (Hong Kong) locale type
return "yyyy'MM'dd";
}
// Replacing all d|m|y OR Gy with dd|MM|yyyy as per the locale date pattern
localeDatePattern = localeDatePattern.replaceAll("d{1,2}", "dd").replaceAll(
"M{1,2}", "MM").replaceAll("y{1,4}|Gy", "yyyy");
// Replacing all blank spaces in the locale date pattern
localeDatePattern = localeDatePattern.replace(" ", "");
// Validating the date pattern length to remove any extract characters
if (localeDatePattern.length() > 10) {
// Keeping the standard length as expected by the application
localeDatePattern = localeDatePattern.substring(0, 10);
}
return localeDatePattern;
}
Since it's just the locale information you're after, I think what you'll have to do is locate the file which the JVM (OpenJDK or Harmony) actually uses as input to the whole Locale thing and figure out how to parse it. Or just use another source on the web (surely there's a list somewhere). That'll save those poor translators.
You can try something like :
LocalDate fromCustomPattern = LocalDate.parse("20.01.2014", DateTimeFormatter.ofPattern("MM/dd/yy"))
Im not sure about what you want, but...
SimpleDateFormat example:
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
Date date = sdf.parse("12/31/10");
String str = sdf.format(new Date());

How do I save and load the current time in java?

I need to be able to save and load the current time in java. I could use System.currentTimeMillis() to store it in a long, but I also need to be able to write it out in different formats, like; "yyyy-mm-dd", "dd/mm hour:min:sec", and such.
The program will save the time I got from System.currentTimeMillis() into a txt file, so even if something happens to the computer or program it needs to be able to just go right back to it's task.
tl;dr
Serializing
Serializing to text:
java.time.Instant.now().toString()
2018-01-01T01:23:45.123456789Z
Instantiate from text:
Instant.parse( “2018-01-01T01:23:45.123456789Z” )
Formatted strings
Adjust into time zone:
instant.atZone( ZoneId.of( “Africa/Tunis” ) ) // Instantiate a `ZonedDateTime` object
Generate strings in other formats:
DateTimeFormatter.ofPattern( … )
…or, better:
DateTimeFormatter.ofLocalized…
…then:
myZonedDateTime.format( formatter )
Track Date-Time Values, Not Milliseconds
Generally speaking, tracking date-time values by millisecond-since-epoch is tricky business and should be avoided. The values are meaningless when read by humans. Different software uses different numbers (seconds versus milliseconds versus nanoseconds). Different software uses different epochs (not always the beginning of 1970 as you may be expecting). Tracking by date-time values by milliseconds like trying to track text by bits rather than using String, FileReader, and FileWriter objects. We have good date-time libraries, so use them.
Joda-Time | java.time
By good date-time libraries, I am referring to Joda-Time or the new java.time package in Java 8. Avoid the older bundled classes, java.util.Date & .Calendar, as they are notoriously troublesome.
To get started with Joda-Time, try:
System.out.println( DateTime.now() );
Then search StackOverflow for "joda" or "joda date".
ISO 8601
When serializing date-time values to text storage, use the ISO 8601 format of YYYY-MM-DDTHH-MM-SS.sss+00:00 such as 2014-03-11T23:54:15+01:00 or 2014-03-11T22:54:15Z. This format is unambiguous. The format is intuitive across various cultures. The values when sorted alphabetically are also sorted chronologically.
The Joda-Time library uses the ISO 8601 format by default. Similarly the java.time package in Java 8 (inspired by Joda-Time, defined by JSR 310) also uses ISO 8601 but extends that format by appending in brackets the proper name of the time zone such as 2014-03-11T15:54:15+08:00[America/Los_Angeles].
store as long value returned from System.currentTimeMillis() and load back using Date date=new Date(long value);
You can use Calendar class or SimpleDateFormat as shown in below code:
import java.text.SimpleDateFormat;
import java.util.Calendar;
Calendar cal=Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
System.out.println(format.format(cal.getTime()));
Read more about Date formatting using SimpleDateFormat.
You can use code similar to the following
String formatted = new SimpleDateFormat("yyyy-mm-dd").format(new Date(System.currentTimeMillis()));
You'll need Date
http://docs.oracle.com/javase/7/docs/api/java/util/Date.html
And for formatting you need SimpleDateFormat
Date date = GregorianCalendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
System.out.println(sdf.format(date));
You can either use a text file or you could use the ObjectOutputStream because Date is Serializable.

String to Date in Java

I have a date string like this "2010-12-10T20:03:53-06:00"
I want to convert the same into equivalent date object in Java.
Any Idea how to do this?
What you are looking for is SimpleDateFormat.parse(). It will convert a string into a Date object.
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html
If you're using Java 7, you should be okay without any string massaging, using the new X specifier for the UTC offset:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US);
Date date = format.parse(text);
(Testing to make sure - when I've installed JDK 7 myself :)
In general I would strongly recommend using Joda Time for date handling, however. Its Z specifier can handle an offset with a colon:
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ")
.withLocale(Locale.US);
DateTime dateTime = formatter.parseDateTime(text);
In fact, there's an ISODateTimeFormat class to make this even simpler:
DateTimeFormatter formatter = ISODateTimeFormat.dateTimeNoMillis();
Joda Time is a significantly better date/time API than the built-in one. (It's far from perfect, but it's a lot better than Date and Calendar...)
You should use DateFormat class for this:
First you need to get rid of that : in the timezone part and make your date string like this
2010-12-10T20:03:53-0600
and use the code snippet below:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date d = formatter.parse("2010-12-10T20:03:53-0600");
Note: I checked this on Java 6 and Mr. Skeet has mentioned a better answer dealing with Java 7 as I don't know more about Java 7
Use Joda time. It is powerful and easy to use.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.
Demo:
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
OffsetDateTime odt = OffsetDateTime.parse("2010-12-10T20:03:53-06:00");
System.out.println(odt);
}
}
Output:
2010-12-10T20:03:53-06:00
ONLINE DEMO
For any reason, if you need to convert this object of OffsetDateTime to an object of java.util.Date, you can do so as follows:
Date date = Date.from(odt.toInstant());
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
You can't parse a date with a colon in the time zone with the standard JDK Date until Java 7. Before Java 7 timezone would have to be either a full time zone with name or in the form -0600.
You have 3 options:
if you use Java 7+, use this pattern: "yyyy-MM-dd'T'HH:mm:ssX" with a SimpleDateFormat
manually remove the colon and parse
use Joda Time, for example: https://stackoverflow.com/a/2375539/829571
Here is an example with the second option:
public static void main(String[] args) throws ParseException {
String input = "2010-12-10T20:03:53-06:00";
int colon = input.lastIndexOf(":");
input = input.substring(0, colon) + input.substring(colon + 1, input.length());
System.out.println(input);
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date date = fmt.parse(input);
System.out.println("date = " + date);
}

Categories