How to get Date formatted in locale with specific pattern? - java

After searching, i was unable to find a solution for this problem.
i have this:
Long parseDt = Long.valueOf(arrayJson.getJSONObject(i-j).getInt("dt")); // dt is a timestamp
Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
String date = new SimpleDateFormat("EEE d MMM", locale).format(new java.util.Date(parseDt * 1000));
So, the pattern works but when i change the phone language, it didn't swap the way it displays, i want to mean if the phone language is French it displays the date like this and it is good for most of the european language:
lun 2 juil
and if i switch language to English, it displays the date like that:
mon 2 july
instead of:
mon july 2
Do you have any clue to solve this problem respecting my pattern knowing that i want the name of the day with 3 characters maximum?
The existing predefined format (like FULL) could work but the name of the day is displayed entirely, for example it is "monday" and i would like only "mon", not "monday", so, any idea?

You could toggle the format according to the locale you got.
Locale locale = ConfigurationCompat.getLocales(
Resources.getSystem().getConfiguration()).get(0);
String fmt = (locale == Locale.ENGLISH) ? "EEE MMM d" : "EEE d MMM";
String date = new SimpleDateFormat(fmt, locale)
.format(new java.util.Date(parseDt * 1000));

Java already “knows” in which locales the day of month goes before the month name and in which it goes after. This is what the full predefined format gave you. So for a general solution that may work in all or most locales I suggest that you rely on this. We can modify the predefined full pattern to use abbreviations for day of week and for month:
int parseDt = arrayJson.getJSONObject(i-j).getInt("dt"); // dt is a timestamp
Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.FULL, null, IsoChronology.INSTANCE, locale);
formatPattern = formatPattern.replaceAll("E{3,}", "EEE").replaceAll("M{3,}", "MMM");
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(formatPattern, locale);
ZoneId zone = ZoneId.of("America/Whitehorse");
ZonedDateTime dateTime = Instant.ofEpochSecond(parseDt).atZone(zone);
String date = dateTime.format(dateFormatter);
System.out.println(date);
Example output:
In UK locale: Mon, 2 Jul 2018
In US locale: Mon, Jul 2, 2018
In FRENCH locale: lun. 2 juil. 2018
I am using regular expressions to make sure that if day of week and/or month is in the format pattern string (for example EEEE and MMMM), it is modified to its abbreviation. Since day of week may also be indicated by lowercase e or c and month by L, you may want to do the same trick with these letters.
I am using java.time, the modern Java date and time API. To use this on not-brand-new Android, get the ThreeTenABP library: use the links at the bottom. If you object to using a high-quality future-proof external library, you may be able to play a similar trick with SimpleDateFormat.
If you want to omit the year too (as in your examples), it is slightly more complicated, but doable. Here’s a simple attempt to remove the year if it comes last:
formatPattern = formatPattern.replaceFirst("^(.*[\\w'])([^\\w']*y+)$", "$1");
With this line inserted the output in French locale is just lun. 2 juil., for example. Year may also be given with letter u, you may want to take this into account too.
Converting your Unix time to a date is a time zone sensitive operation, so I give time zone in the code. Please put the one you desire where I put America/Whitehorse. If you trust that the JVM’s time zone setting reflects what the user wants, you may use ZoneId.systemDefault() (the SimpleDateFormat in your own code uses the VM setting too).
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.timeto Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.

According to the date format of the countries:
https://en.wikipedia.org/wiki/Date_format_by_country
and my app needs, I've choosen the easiest way to display it:
int parseDt = arrayJson.getJSONObject(i-j).getInt("dt"); // dt is a timestamp
Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
String dateFormat = ((locale.equals(Locale.US) || locale.equals(Locale.CHINA) || locale.equals(Locale.CANADA) || locale.equals(Locale.JAPAN)) ? "EEE, MMM d" : "EEE d MMM";
String date = new SimpleDateFormat(dateFormat, locale).format(new java.util.Date(parseDt * 1000));

Related

Date parse issue with CANADA country/locale and MM/dd/yyyy hh:mm a date [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am currently parsing date with below code
Date outDate = null;
SimpleDateFormat formatter = null;
formatter = new SimpleDateFormat(dateFormat,locale);
outDate = formatter.parse(dt);
I am aware its old way of parsing date. The problem i am facing is that the above code is not working once i use CANADA country/locale.
Below is the date and format -
date - 02/05/2021 01:17 PM format - MM/dd/yyyy hh:mm a locale -
en_CA
The code works for all the format and countries but only once i use CANADA locale and format (MM/dd/yyyy hh:mm a), i don't get output date.
java.time
I recommend that you use java.time, the modern Java date and time API, for you date and time work. Also it turns out that Canadian English uses a.m. and p.m. rather than AM and PM as in your input.
If you want to accept AM and PM in uppercase without dots — well, Canadian English doesn’t do that (at least not in the Java versions that you and I have tried). Therefore use for example Locale.ENGLISH. Define a formatter like this:
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a", Locale.ENGLISH);
Now parsing is a one-liner:
String dt = "02/05/2021 01:17 PM";
LocalDateTime dateTime = LocalDateTime.parse(dt, FORMATTER);
System.out.println(dateTime);
And output is:
2021-02-05T13:17
If instead you want to use Canadian English locale, you must fit your input string to it. Let’s first modify the formatter to the desired locale:
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a", Locale.CANADA);
To learn how the locale expects the date to be written, let’s first format some date and time using the formatter:
System.out.println(LocalDateTime.now(
ZoneId.systemDefault()).format(FORMATTER));
06/08/2021 08:28 p.m.
Ah — so p.m. (and I bet a.m. too) with lower case letters and dots. We can do that:
String dt = "02/05/2021 01:17 p.m.";
Now it parses just fine:
2021-02-05T13:17
Caveat: the strings used for AM and PM in Canadian locale may vary by Java version, I have not checked.
Link
Oracle tutorial: Date Time explaining how to use java.time.
The right format for locale new Locale("en","CA") is:
"02/05/2021 01:17 p.m."
Just change PM to p.m. in the input date (dt in your case).
Another solution could be changing the dateFormat, or remove locale from SimpleDateFormat.

How to format Simple Date Formatter in Java as dd-3 letter month-yyyy?

I have a simple date formatter with the following format:
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(DATE_FORMAT);
//accessExpiryDate is a Date object
DATE_FORMATTER.format(accessExpiryDate);
And it is formatting the date as yyyy-MM-dd. But I want to format the date such as "1 Jun 2019". day + first 3 letter of the month + year.
How can i achieve that? Is there a simple way/method/class or should i write my custom date formatter method?
java.time
Don’t use Date and SimpleDateFormat. Those classes are poorly designed and long outdated, the latter in particular notoriously troublesome. As Jon Skeet said, move to java.time, the modern Java date and time API, for a better experience.
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("d MMM u", Locale.ENGLISH);
LocalDate ld = LocalDate.of(2019, Month.JUNE, 1);
System.out.println(ld.format(dateFormatter));
Output from this snippet is:
1 Jun 2019
A number of format pattern letters including M for month can yield either a number or a text depending on how many letters you put in the format pattern string (this is true for both DateTimeFormatter and the legacy SimpleDateFormat). So MM gives you two-digit month number, while MMM gives you a month abbreviation (often three letters, but could be longer or shorter in some languages).
If you are getting an old-fashioned Date object from a legacy API that you either cannot change or don’t want to upgrade just now, you may convert it like this:
Date accessExpiryDate = getFromLegacyApi();
LocalDate ld = accessExpiryDate.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
The rest is as before. And now you’ve embarked on using the modern API and can migrate your code base in this direction at your own pace.
Link: Oracle tutorial: Date Time explaining how to use java.time.
Since you have specified the date format as yyyy-MM-dd, it is formatted as that. Just fix your date format to the expected formatting.
e.g: d MMM yyyy
As already suggested by #JonSkeet, you should read the API documentation.
Anyway, the format should be in your case d MMM yyyy.

How can I format day and month in the locale-correct order in Java?

Is there a way to format a day and month (in compact form), but not year, in the locale-correct order in Java/Kotlin? So for English it should be "Sep 20" but for Swedish "20 sep.".
For comparison, on Cocoa platforms, I can do the following (in Swift):
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "sv_SE")
formatter.setLocalizedDateFormatFromTemplate("MMM d")
print(formatter.string(from: Date()))
This will correctly turn things around. Is there an equivalent thing to do with the Java SDKs? I've been trying various forms with both DateTimeFormatter and the older SimpleTimeFormat APIs, but no success.
Notes: Unlike this question, I don't want the full medium format that includes the year. I also don't want either DateTimeFormatter.ofPattern("MMM d"), since that gives the incorrect result in Swedish, or DateTimeFormatter.ofPattern("d MMM"), since that gives the incorrect result in English.
No, sorry. I know of no Java library that will automatically turn "MMM d" around into 20 sep. for a locale that prefers the day of month before the month abbreviation.
You may try modifying the answer by Rowi in this way:
DateTimeFormatter ft =
DateTimeFormatter
.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.forLanguageTag("sv-SE"))
;
However the result is:
20 sep. 2019
It includes the year, which you didn’t ask for.
An advanced solution would use the DateTimeFormatterBuilder class to build DateTimeFormatter objects.
DateTimeFormatterBuilder
.getLocalizedDateTimePattern(
FormatStyle.MEDIUM,
null,
IsoChronology.INSTANCE,
Locale.forLanguageTag("sv-SE")
)
This returns d MMM y. Modify this string to delete the y and the space before it. Note that in other languages the y may be yy, yyyy or u and may not come last in the string. Pass your modified format pattern string to DateTimeFormatter.ofPattern.
It may be shaky. Even if you look through the format pattern strings for all available locales, the next version of CLDR (where the strings come from) might still contain a surprise. But I think it’s the best we can do. If it were me, I’d consider throwing an exception in case I can detect that the string from getLocalizedDateTimePattern doesn’t look like one I know how to modify.
You can do it in Java using LocalDate:
LocalDate dt = LocalDate.parse("2019-09-20");
System.out.println(dt);
DateTimeFormatter ft = DateTimeFormatter.ofPattern("dd MMM", new Locale("sv","SE"));
System.out.println(ft.format(dt));
You could get the DateFormat's pattern and remove the year:
val locale: Locale
val datePattern = (DateFormat.getDateInstance(DateFormat.MEDIUM, locale) as SimpleDateFormat).toPattern()
.replace("y", "").trim { it < 'A' || it > 'z' }

Is there YYYYWW Format in java

Is there any way to use Date in Java with the format YYYYWW? There is week of month but is there any way to find week of the year?
I am not quite sure about your question, but maybe you want a ISO-like week-date with year and week-of-year. If so then pay attention to the fact that there is another definition of a year, namely a year of weekdate (or other call it week-based-year). This year is in most cases the same as the standard calendar year but can differ at the begin or end of the calendar year dependent on the ISO-week-rules (monday as first day of week and first week-of-year having at least 4 days in calendar year).
If you look for this week-based-year and the ISO-week-of-year then you should use this expression:
// In France ISO-8601-week-rules are valid, so let's use this locale to choose ISO.
SimpleDateFormat sdf = new SimpleDateFormat("YYYYww", Locale.FRANCE); // big letter Y!
Otherwise you can of course just go with the other answer of #BetaRide: "yyyyww".
Standard Format
The ISO 8601 standard defines such week-of-year. You may want to review the Wikipedia articles here and here for guidance, as your format is not quite standard and is ambiguous. The standard uses a W and optionally a hyphen, such as YYYY-Www.
Joda-Time
The Joda-Time library has good support for ISO 8601 including weeks. See the ISODateTimeFormat class and its weekYearWeek method amongst others.
Note that time zone is crucial in determining a date and therefore a week. At the stroke of midnight ending Sunday in Paris means a new week in France while still "last week" in Montréal.
Example code using Joda-Time 2.5.
DateTime now = DateTime.now( DateTimeZone.forID( "America/Montreal" ) );
String output = ISODateTimeFormat.weekyearWeek().print( now );
int weekNumber = now.getWeekOfWeekyear();
When run.
now: 2014-11-03T02:30:10.124-05:00
output: 2014-W45
Avoid j.u.Date
The java.util.Date and .Calendar and SimpleDateFormat classes bundled with Java are notoriously troublesome. Avoid them. Use either Joda-Time or the new java.time package in Java 8 (inspired by Joda-Time).
You can use SimpleDateFormat to format and parse any date string.
The format you are looking for is "yyyyww".
Letter y represent Year where as be careful with - as w represents Week in year and W represents Week in month
try
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyww");
System.out.println(dateFormat.format(new Date()));
Refer this for more date-formats
yes we can use Y for week of the month and y for week of the year.
Ex: Date d =new Date();
SimpleDateFormat ft =
new SimpleDateFormat ("yyyyww");
System.out.println(ft.format(d));
can give you the current year and week.

java parsing string to date

I am trying to parse 14th March 2011 to a date in Java for a time converter application... I get 26th Dec 2010... Please help.
import java.util.*;
import java.text.*;
class date {
public static void main(String[] args) {
try {
String timestampOrig = "11/03/14,15:00:00";
SimpleDateFormat inFormat = new SimpleDateFormat("YY/MM/dd','HH:mm:ss");
Date parseDate = inFormat.parse(timestampOrig);
System.out.println("parsed date: " + parseDate.toString());
}
catch(ParseException pe){
}
}
}
output:
parsed date: Sun Dec 26 15:00:00 EST 2010
YY should be yy (in lower case). You can find the list of available characters and their meaning in the documentation.
Out of curiosity, more information about YY, which is for week year, here (not 100% sure what it is to be honest).
java.time
I am providing the modern answer using java.time, the modern Java date and time API (since March 2014).
DateTimeFormatter inFormat = DateTimeFormatter.ofPattern("uu/MM/dd,HH:mm:ss");
String timestampOrig = "11/03/14,15:00:00";
LocalDateTime parsedDateTime = LocalDateTime.parse(timestampOrig, inFormat);
System.out.println("parsed date: " + parsedDateTime.toString());
Output is:
parsed date: 2011-03-14T15:00
I recommend you don’t use SimpleDateFormat and Date. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use LocalDateTime and DateTimeFormatter, both from java.time, the modern Java date and time API. The modern API is so much nicer to work with. And BTW would throw an exception if you tried with YY for year, which I find somewhat more helpful for catching your error.
The quotes around the comma in the format pattern string are optional. I know that the documentation recommends them, but I find the format pattern string more readable without them, so left them out.
What went wrong in your code?
Uppercase Y in the format patterns string is for week based year and only useful with a week number. Apperently SimpleDateFormat wasn’t able to combine your specified month and day of month with the week based year of 2011 and instead just took the first day of the week-based year (this is typical behaviour of SimpleDateFormat, giving you a result that cannot be but wrong and pretending all is well). Assuming your locale is American or similar, week 1 is the week that contains January 1 and begins on the Sunday of the same week, therefore in this case the last Sunday of the previous year, December 26, 2010.
With java.time you may use either lowercase y or u for year. The subtle difference is explained in the question linked to at the bottom. In any case a two-digit year is interpreted into the range from year 2000 through 2099 (there are ways to control the interpretation if you need to).
Links
Oracle tutorial: Date Time explaining how to use java.time.
Question: uuuu versus yyyy in DateTimeFormatter formatting pattern codes in Java?

Categories

Resources