How to convert date from English to Arabic - java

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.

Related

how to convert from 10-JUN-02 01.57.07.848594000 PM to yyyy-MM-dd-HH24.MI.SS.FF6 in java

how to convert from 10-JUN-02 01.57.07.848594000 PM to yyyy-MM-dd-HH24.MI.SS.FF6 in java
Start by taking a look at
Date and Time Classes
Java string to date conversion
Failed to parse single digit hour and lowercase am-pm of day into Java 8 LocalTime
You question is not unique nor uncommon and some due diligence in researching your issue will be more highly rewarded.
You basic question is actually two questions:
How to parse a String to a date/time object
How to format a date/time object
I appreciate that in this day and age there are at least 3 distinct methods you might approach these problems. However, the Date/Time API introduced in Java 8 should be your preferred approach.
Having said that, you will probably have two major stumbling blocks in getting something to work.
Both relate to the uncommon case of your input (JUN and pm).
Java 8 introduced the DateTimeFormatterBuilder class which can be used to overcome this issue.
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd-MMM-yy hh.mm.ss.SSSSSSSSS a")
.toFormatter(Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse("10-JUN-02 01.57.07.848594000 pm", dtf);
This will provide you with a date/time representation of your input.
Then, you just need another DateTimeFormatter to format the output as desired...
DateTimeFormatter output = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS", Locale.ENGLISH);
System.out.println(output.format(ldt));
which outputs...
2002-06-10-13.57.07.848594
Make sure you have a read through the JavaDocs for DateTimeFormatter to better understand the formatter specifications

Format String into Date considering localization in GWT

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.

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());

Parse time with microseconds in Java

I am having problems parsing time strings in Java that are in the format of 2013-01-09 09:15:03.000000. In my data, the last three digits are always 0 (meaning the input strings have only millisecond precision), so I passed this format to SimpleDateFormat:
formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS'000'");
but formatter.parse("2013-01-09 09:15:02.500000"); throws an exception:
Unparseable date: "2013-01-09 09:15:02.500000"
at java.text.DateFormat.parse(DateFormat.java:357)
Anyone knows how to do it correctly? I can work around by using format yyyy-MM-dd HH:mm:ss.SSS and using substring to get rid of last three digits but that's really hacky.
EDIT: can anyone explain why the format string yyyy-MM-dd HH:mm:ss.SSS'000' can't be used to parse time "2013-01-09 09:15:02.500000"
try java.sql.Timestamp
Timestamp ts = Timestamp.valueOf("2013-01-09 09:15:03.500000");
Date date = new Date(ts.getTime())
it's also thread-safe and fast as opposed to SimpleDateFormat
java.time
I should like to contribute the modern answer. Use java.time, the modern Java date and time API. One option, you may use a formatter:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS");
LocalDateTime dateTime = LocalDateTime.parse(timeString, formatter);
System.out.println(dateTime);
When using the string from your question, "2013-01-09 09:15:02.500000", this printed:
2013-01-09T09:15:02.500
If you want the value printed with six decimals on the seconds even when the last three decimals are 0, use the same formatter to format the time back into a string:
System.out.println(dateTime.format(formatter));
The other option, you may exploit the fact that your string resembles the ISO 8601 format, the format that the modern classes parse as their default, that is, without any explicit formatter. Only ISO 8601 has a T to denote the start of the time part, but we can fix that easily:
LocalDateTime dateTime = LocalDateTime.parse(timeString.replace(' ', 'T'));
It gives the same result, 2013-01-09T09:15:02.500. It’s shorter, but also more tricky.
Why bother?
The classes Date and Timestamp are long outdated, and SimpleDateFormat in particular has proven troublesome. Its surprising behaviour in your situation is just one little story out of very many. The modern API is generally so much nicer to work with.
Why didn’t your formatter work?
While the format pattern strings used by SimpleDateFormat and DateTimeFormatter are similar, there are differences. One is that SimpleDateFormat understands uppercase S as milliseconds no matter of there are one or nine of them, whereas to DateTimeFormatter they mean fraction of second. Your SimpleDateFormat furthermore grabbed all six digits after the decimal point, ignoring the fact that you had typed only three S, so there were no zeroes left to match the '000' (by the way, the apostrophes are not necessary, only letters need them).
Link
Oracle Tutorial
I've figured out myself. Just FYI, Apache commons' FastDateFormat seems accepting the SSS000 format and parses the time correctly.

How can I format date by locale in Java? [duplicate]

This question already has answers here:
SimpleDateFormat and locale based format string
(10 answers)
Closed 8 years ago.
I need to format date to app that has many languages, what is best way to format date, because every country has different kind of date formatting, so is it possible to format date by locale?
Yes, using DateFormat.getDateInstance(int style, Locale aLocale)
This displays the current date in a locale-specific way.
So, for example:
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, yourLocale);
String formattedDate = df.format(yourDate);
See the docs for the exact meaning of the style parameter (SHORT, MEDIUM, etc)
SimpleDateFormat has a constructor which takes the locale, have you tried that?
http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html
Something like
new SimpleDateFormat("your-pattern-here", Locale.getDefault());
Joda-Time
Using the Joda-Time 2.4 library. The DateTimeFormat class is a factory of DateTimeFormatter formatters. That class offers a forStyle method to access formatters appropriate to a Locale.
DateTimeFormatter formatter = DateTimeFormat.forStyle( "MM" ).withLocale( Java.util.Locale.CANADA_FRENCH );
String output = formatter.print( DateTime.now( DateTimeZone.forID( "America/Montreal" ) ) );
The argument with two letters specifies a format for the date portion and the time portion. Specify a character of 'S' for short style, 'M' for medium, 'L' for long, and 'F' for full. A date or time may be ommitted by specifying a style character '-' HYPHEN.
Note that we specified both a Locale and a time zone. Some people confuse the two.
A time zone is an offset from UTC and a set of rules for Daylight Saving Time and other anomalies along with their historical changes.
A Locale is a human language such as Français, plus a country code such as Canada that represents cultural practices including formatting of date-time strings.
We need all those pieces to properly generate a string representation of a date-time value.
Take a look at java.text.DateFormat.
Easier to use (with a bit less power) is the derived class, java.text.SimpleDateFormat
And here is a good intro to Java internationalization: http://java.sun.com/docs/books/tutorial/i18n/index.html (the "Formatting" section addressing your problem, and more).
I agree with Laura and the SimpleDateFormat which is the best way to manage Dates in java. You can set the pattern and the locale. Plus you can have a look at this wikipedia article about Date in the world -there are not so many different ways to use it; typically USA / China / rest of the world -

Categories