I'm writing a java gui application that has to display dates.
Since this application is primarily going to run on Windows systems, I would like to be able to use date & time formats that correspond to the Windows localization settings.
I found DateFormatProvider class, in Java 6, which gave me high hopes ... but I haven't found an implementation that will use the Windows localization information.
Any suggestions?
You should be able to use the DateFormatProvider methods with the default locale returned by getDefault().
The Java Virtual Machine sets the
default locale during startup based on
the host environment.
EDIT: if you can't just pass the default locale to the DateFormat class, there is example code here for implementation of a concrete class that extends DateFormatProvider.
I haven't heard about any Java date formatter that uses MS Windows formatting routines (or just definitions for that matter). Since Java is meant to be multiplatform (compile once, run anywhere), it simply couldn't use underlying OS behavior, for consistency reasons.
You can use DateFormat class as defined here:
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
String formattedDate = dateFormatter(new Date());
One important issue about this class: LONG date formats are broken for Czech, Polish and Russian, possibly for other Slavic languages too. I recommend using MEDIUM date format instead.
BTW. This will format dates for Gregorian or Julian calendars. It won't give you Arabic nor Hebrew calendars (although former is default for some countries).
Edit
I am not aware of your specific requirements, but since you mentioned Locale, maybe ICU4J's DateFormat class is what you looking for. Still, as per my knowledge (which might be incomplete here), they are using their own formatter and localized text database. However, this database is probably more complete (especially on Mac) than the one bundled with JDK (previous ICU snapshot).
Related
TL;DR: How do I get from having locale and SHORT/MEDIUM/LONG etc to the pattern String to parse a date.
Full version:
Accessing the pattern of a locale-specific date format seems to be problem not well covered in Java.
This is in the context of
the JDK8+ DateTime API not providing access, and
the classic SimpleDateFormat not looking future-proof enough.
I'm bringing this question back due to the JDK-specificity of the first, and the implementation-specific-ness of the second question, this time to be answered in a non-version-specific way, long after 2017 (the date of the first question):
Use case:
On the user interface, show the date format that a date will be parsed with, when entered: E.g. For Locale.US display start date (M/d/yy), for Locale.GERMANY show Startdatum (dd.MM.yy) next to an input (or, in HTML, as a placeholder).
This would be trivial to achieve - as long as it still works - with
DateFormat usFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
DateFormat deFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMANY);
System.out.println(((SimpleDateFormat) usFormat).toPattern()); // M/d/yy
System.out.println(((SimpleDateFormat) deFormat).toPattern()); // dd.MM.yy
but this code involves the old API and an implementation specific typecast - both are assumptions that I'm not too confident using.
Maintaining my own library of locale-specific patterns seems even less advisable, but with the DateTime API not granting any access to its internal patterns (they must be there):
Is there a way to solve this problem in a future-proof way?
Due to the linked questions above, this likely involves a specific minimal Java version, and that's fine. I'm currently still bound to be 8 and 11 compatible, but this could either push the version further, or provide an alternative future proof implementation for instances running under newer Java versions.
You can use the DateTimeFormatterBuilder to get the format string:
String usFormat = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.US);
String deFormat = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.GERMANY);
System.out.println(usFormat); // M/d/yy
System.out.println(deFormat); // dd.MM.yy
Is there any implementation of Persian calendar DatePicker on JavaFx?
There is no Persian chronology to use on DatePicker to achieve a Persian calendar
I have now developed a ready-to-use calendar picker which also offers a persian calendar. It was originally inspired by the nice work of Christian Schudt, but completely rewritten and enhanced. Just download my library Time4J-v4.20 (or later, available in Maven) and use this code demo:
CalendarPicker<PersianCalendar> picker = picker.persianWithSystemDefaults();
picker.setLengthOfAnimations(Duration.seconds(0.7));
picker.setShowInfoLabel(true);
picker.setLocale(new Locale("fa", "IR"));
picker.setShowWeeks(true);
picker.setCellCustomizer(
(cell, column, row, model, date) -> {
if (CellCustomizer.isWeekend(column, model)) {
cell.setStyle("-fx-background-color: #FFE0E0;");
cell.setDisable(true);
}
}
);
You can also set other properties like minimum and maximum date. Here an example image using Farsi language and a localized week model for Iran. You can navigate through all Persian months, years or decades (by clicking on the header) or jump to current date (by clicking on the footer).
As it is stated in the docs, you can set the used calendar system via the ObjectProperty<Chronology> of the DatePicker.
The method you need to do so is
public final void setChronology(Chronology value)
As there's no default persian/iranian calendar system (only the hiraj system is implemented) implemented, you have to write your own:
"Adding New Calendars
The set of available chronologies can be extended by applications. Adding a new calendar system requires the writing of an implementation of Chronology, ChronoLocalDate and Era. The majority of the logic specific to the calendar system will be in the ChronoLocalDate implementation. The Chronology implementation acts as a factory.
To permit the discovery of additional chronologies, the ServiceLoader is used. A file must be added to the META-INF/services directory with the name 'java.time.chrono.Chronology' listing the implementation classes. See the ServiceLoader for more details on service loading. For lookup by id or calendarType, the system provided calendars are found first followed by application provided calendars.
Each chronology must define a chronology ID that is unique within the system. If the chronology represents a calendar system defined by the CLDR specification then the calendar type is the concatenation of the CLDR type and, if applicable, the CLDR variant,
Implementation Requirements:
This interface must be implemented with care to ensure other classes operate correctly. All implementations that can be instantiated must be final, immutable and thread-safe. Subclasses should be Serializable wherever possible."
Source: https://docs.oracle.com/javase/8/docs/api/java/time/chrono/Chronology.html?is-external=true
I need to get a Date instance from input file. I don't know the date format, but I want to get it from user profile settings.
Te following code does not working:
DateFormat form = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
try {
Date t = form.parse("6/6/2015");
}
unparseable date error
I want to know if there is any way to get date from string without knowing the date string pattern.
I need this date to create MySQL query. Maybe there is another way to build this query without parsing date? I am using Entity Beans.
No. Consider the date "1/2/2015": is that February 1st or January 2nd. Depends on your locale.
Instead, you should be more specific: rather than getting a date formatter for your locale, use SimpleDateFormat with an explicit pattern.
I want to know if there is any way to get data from string without knowing the data string pattern.
Without any more information, this is very error prone. For example, consider "7/6/2015" - does that mean June 7th, or July 6th?
If you know the user's locale, you can do a lot better - for example, you could obtain DateFormat instances for long, medium, short and full date patterns for that locale, and try them one at a time. Bear in mind, however, that depending on where this code is executing, the default locale (as you're using at the moment) may not be the user's locale. You mention the user profile settings - hopefully that already contains a locale.
One alternative is to ask the user to tell you what the format is - maybe provide lots of different examples, and let them pick the one that matches.
Finally, if the file has lots of dates in and you're confident they'll all be in the same format, you could try to parse all of them in each of several different formats - that's likely to reduce the chances of error, as "7/6/2015" becomes unambigious if you've also seen "13/1/2015" for example.
The set of date and time functions I need are pretty basic.
An object to represent a date/time (for convenience in function calls).
Conversion functions to and from y,m,d,h,m,s.
Format/parse functions to and from numeric-only localised string representation. Eg dd/mm/yyyy, yyyy-mm-dd, mm.dd.yyyy or whatever order and delimiters are locally expected.
A system function to get the current local date and time (timezones not required).
Compatible with the DatePicker widget.
Thread safe. Static functions available to both UI and worker (NDK) threads.
So far I've found that:
Calendar and GregorianCalendar can do the conversions, but they're clunky to use and they're not thread safe.
SimpleDateFormat can do the formatting, if I could only figure out which magic string to feed it! The default is not numeric.
Time has a nicer set of conversion functions, but has no date/time object and the parse/format functions are documented only indirectly. And it smells a lot more like Unix than Java.
So do I find a way to fix the thread safety and try to persuade SimpleDateFormat to give me what I need? Or do I give up and jump ship to Time? Or have I missed something?
Just to be clear, this is not a request for a library recommendation or a shopping list. It's a request for assistance on how to implement a specific set of functions using the given Android API. I'm looking for an expert on using these libraries to point out a path through the morass. I would hope that a well-written answer would benefit other readers also struggling with this part of Android.
Personally I find Joda-Time to be able to handle almost everything you need for date and time. Since it's just a .jar it should be able to be imported.
Here's how to use it, for the questions you asked specifically:
An object to represent a date/time - DateTime for immutable or MutableDateTime for one that you need to apply transformations to.
These objects have many methods for conversion, see the Joda-Time API for AbstractDateTime as an example, as all of Joda's classes extend AbstractDateTime
You can use String convertedToString = new DateTime().toString("yyyy-MM-dd") to get it as 2014-05-05. To reverse this, use this API: DateTimeFormatter parseDateTime(someStringThatRepresentsADate)
DateTime now = new DateTime() gives you now, as a DateTime object
You can get a DateTime object from several other classes, such as Calendar by doing something like DateTime fromCalendar = new DateTime(myCalendarObject)
See The FAQ for Joda on multi-threading
In order to import Joda into your Android project, assuming you're using Android studio and Gradle, see this answer: Android Studio: Add jar as library?
I am working with timezones in a Java application using JodaTime. I encounter a problem when trying to build a DateTimeZone (JodaTime) object from the id of a java timezone. Joda throws a
java.lang.IllegalArgumentException: The datetime zone id 'SystemV/HST10' is not recognised
for the folowing list of timezones:
SystemV/HST10
SystemV/YST9
SystemV/YST9YDT
SystemV/PST8
SystemV/PST8PDT
SystemV/MST7
SystemV/MST7MDT
SystemV/CST6
SystemV/CST6CDT
SystemV/EST5
SystemV/EST5EDT
SystemV/AST4
SystemV/AST4ADT
What are these timezones used for? Are they relevant to non-programmers? Should an application designed for general uses support these timezones?
Thanks.
The SystemV time-zone IDs are old and deprecated. However, you can make Joda-Time understand them by re-compiling the joda-time jar file with the systemv time-zone data file included. See the commented out lines in the systemv data file. (ie. uncomment the lines and rebuild the jar file).
I'll add this as a new post, as it provides the answers to my question. SystemV timezones were used in an old UNIX OS, that was named, you guessed it, UNIX SYSTEM V. After discussing with my team, we decided that they are of no importance to non-programers and even to programmers nowadays. So we decided not to use them in our application.
Some references about the SystemV timezones:
http://en.wikipedia.org/wiki/IANA_time_zone_database#Files_in_tzdata
http://en.wikipedia.org/wiki/System_V
You can simply convert java TimeZone to DateTimeZone, using method DateTimeZone#forTimeZone
TimeZone tz = //...
DateTimeZone dtz = DateTimeZone.forTimeZone(tz);
Some of this zones can be parsed without "SystemV/"
So you can use
String tzId = "SystemV/MST7MDT";
DateTimeZone tz = DateTimeZone.forID(tzId.replaceAll("SystemV/", ""));
Also you can make next
TimeZone tz = TimeZone.getTimeZone("SystemV/MST7MDT");
DateTimeZone jodaTz = DateTimeZone.forTimeZone(tz);