SimpleDateFormat - convert to other locale - java

I define a format like following:
sdf = new SimpleDateFormat("MMMM dd\nEEEE, YYYY", Locale.getDefault())
Now I get exceptions on some devices like this one:
java.lang.IllegalArgumentException: Unknown pattern character 'Y'
So the problem is, the Y is not supported in this devices local. So I have to change the format to following:
// the string format is formatted in english, so we pass in Locale.ENGLISH
new SimpleDateFormat("MMMM dd\nEEEE, YYYY", Locale.ENGLISH)
Question
How can I now use this SimpleDateFormat to print a date in the locale language? I want that EEEE is german, english, spanish or whatever. So I need to use the english format string but then print the formatted string in local language. How can I do this?
Example
SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd\nEEEE, YYYY", Locale.getDefault());
Date d = new Date();
String formatted = sdf.format(d);
Expected
DE: Juli 2017\nMittwoch, 2017
EN: July 2017\nWednesday, 2017
Idea
Create a SimpleDateFormat with the current local like new SimpleDateFormat("MMMM dd\nEEEE, YYYY", Locale.getDefault()); but now I can't be sure that my string passed into the constructor is valid for the current locale... (Like the exception shows, Y is not valid in every locale)

Fix strings must be inside of sibgle quotes:
new SimpleDateFormat("MMMM dd'\n'EEEE',' yyyy", Locale.ENGLISH)
But \n is a newline. Hopefuly you want it there.
UPDATE
(Like the exception shows, Y is not valid in every locale):
Y is valid in every Locale!!

Related

How to localize timezone 'z' for a date format "MM/dd/yyyy HH:mm:ss a z"

I want to format current date in MM/dd/yyyy HH:mm:ss a z format based on locale.
String pattern = "MM/dd/yyyy HH:mm:ss a z";
DateFormat dateFormat = new SimpleDateFormat(pattern, new Locale("ja", "JP"));
Date date = new Date();
System.out.println(dateFormat.format(date));
Output:
04/01/2018 17:15:23 午後 EDT
I want to display EDT in Japanese too. If I try zzzz instead of z in
the pattern, then timezone is localized and displays "Eastern Daylight Time" in Japanese:
String pattern = "MM/dd/yyyy HH:mm:ss a zzzz";
DateFormat dateFormat = new SimpleDateFormat(pattern, new Locale("ja", "JP"));
Date date = new Date();
System.out.println(dateFormat.format(date));
Output:
04/01/2018 17:20:17 午後 東部夏時間
How can we localize the Timezone abbreviation 'EDT' and display in Japanese?
The localized strings are built-in in the JVM, but you can replace them by getting the DateFormatSymbols from the formatter and changing it:
String pattern = "MM/dd/yyyy HH:mm:ss a z";
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, new Locale("ja", "JP"));
DateFormatSymbols symbols = dateFormat.getDateFormatSymbols();
String[][] zones = symbols.getZoneStrings();
for (int i = 0; i < zones.length; i++) {
// position 4 is the abbreviation for Daylight Saving Time
String zoneAbbrev = zones[i][4];
// overwrite zone short names (replace EDT with whatever string you want)
if ("EDT".equals(zoneAbbrev)) {
zones[i][2] = "東部夏時間"; // change it to the short name for Standard Time
zones[i][4] = "東部夏時間"; // change it to the short name for Daylight Saving Time
}
}
symbols.setZoneStrings(zones);
dateFormat.setDateFormatSymbols(symbols);
I don't know what should be the correct strings, so I used the same as above, but you can replace them with the correct values: zones[i][2] contains the short name for EST (Standard Time) and zones[i][4] contains the short name for EDT (Daylight Saving Time).
If you're allowed to use external libraries, then please use Apache Commons DateUtils method:
public static Calendar toCalendar(Date date, TimeZone tz)
To create the calendar document from your date and manipulate it after.

How to convert date strings from different TimeZones to Date object in one TimeZone

Im working on an RSS reader software. I get items with their pubDate (publish date) values as string, convert them to Date object, and put them to my DB. However, when I check my DB, I saw some interesting values such as the date of tomorrow.
I research this situation and found that it is about time zone value Z. For example when I get "Mon, 26 May 2014 21:24:29 -0500", it becomes "2014-05-27 05:24:29", the next day !
All I want is to get dates in any timezone and convert them to date in common timezone, such as my country's.
Here is my code :
public static String convert(String datestr) throws ParseException {
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
Date date = formatter.parse(datestr);
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return resultFormatter.format(date);
}
And I use the method like that :
System.out.println(convert("Mon, 26 May 2014 21:24:29 -0500"));
The output is : 2014-05-27 05:24:29
Any idea ?
Since you haven't set a time zone, it's using your system's default.
Set a specific IANA time zone.
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
resultFormatter.setTimeZone(TimeZone.getTimeZone("America/New_York"));
return resultFormatter.format(date);
Looks like you passed a Date with timezone, but given a wrong format. If you are passing timezone like "-0500" you should rather use:
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
Remember that the system will always display the date using the current, default timezone (TimeZone.getDefault()) unless you override it by:
resultFormatter.setTimeZone(...)
This is working as expected. The date is converted as per your system's timezone.
Check the UTC offset of your system and replace it in the sample date string and look at the output.
For e.g: India is UTC+5:30
String datestr="Mon, 26 May 2014 21:24:29 +0530";
output:
2014-05-26 21:24:29
Alternate solution
If you don't want to consider the timezone of the input date string then simply truncate this information and remove zzz from pattern as well as shown in below code:
String datestr = "Mon, 26 May 2014 21:24:29 -0530";
datestr = datestr.replaceAll("\\s[-+](\\d+)$", ""); // truncate the timezone info if not needed
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss"); // remove zzz from the pattern
Date date = formatter.parse(datestr);
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(resultFormatter.format(date));

SimpleDateFormat parsing date string incorrectly

I'm trying to parse a String into a Date and then format that Date into a different String format for outputting.
My date formatting code is as follows:
SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat dateParser = new SimpleDateFormat("d/M/yyyy h:m:s a");
String formattedDocumentDate = dateFormatter.format(dateParser.parse(sysObj.getString("document_date")));
The result of sysObj.getString("document_date") is 1/31/2013 12:00:01 AM. And when I check the value of formattedDocumentDate I get 01/07/2015.
Any help is much appreciated.
You are parsing days 31 as months. SimpleDateFormat tries to give you a valid date. Therefore It adds to 1/0/2013 31 months. This is 2 years and 7 month. So you get your result 01/07/2015. So SimpleDateFormat works correct.
One solution for you is to change your date pattern to M/d/yyyy h:m:s a or your input data.
To avoid these tries you have to switch off SimpleDateFormat lenient mode. Then you will get an exception if the format does not fit.
It looks like your input format is actually months first, then days. So should be "MM/dd/yyyy".
So:
SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/M/yyyy");
SimpleDateFormat dateParser = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a");
String formattedDocumentDate = dateFormatter.format(dateParser.parse(sysObj.getString("document_date")));
Another example like this
SimpleDateFormat sdfInput = new SimpleDateFormat("yyyyMMdd");
System.out.println("date is:"+new java.sql.Date( sdfInput.parse("20164129").getTime() ));
Output is: 2019-05-29
I expect to throw parse exception but not (41)is not a valid month value.
on the other hand if I gave 20170229, system can recognize the February of 2017 doesn't have a lap year and return 2017-03-01 interesting.

Unparsable date exception

I'm currently working on some simple project in Java and I have date in the following string:
String dateString = "Sun 7/14 03:44 AM 2013";
and want to to convert this string to Date object. I'm using following lines of code to do that. I searched site and found solution how to do this with DateFormatter:
DateFormat format = new SimpleDateFormat("EEE M/dd hh:mm a yyyy");
Date d = format.parse(dateString);
But I'm probably doing something wrong, because I always get exception:
Unparseable date: "Sun 7/14 03:44 AM 2013"
This seems to be problem with pattern I'm using but tried different patterns and nothing work.
Certain fields such as the day of week fields and/or AM/PM marker may not match those from your default Locale. ParseException has the method getErrorOffset to determine exactly where the pattern does not match.
try
DateFormat format =
new SimpleDateFormat("EEE M/dd hh:mm a yyyy", Locale.ENGLISH);
It is important to add Locale as you are parsing language day of week names.
String dateString = "Sun 7/14 03:44 AM 2013";
DateFormat format = new SimpleDateFormat("EEE M/dd hh:mm a yyyy", Locale.US);
Date d = format.parse(dateString);
I tried this out and the following worked,
String stringDate = "Sun 7/14 03:44 AM 2013";
DateFormat format = new SimpleDateFormat("EEE MM/dd hh:mm a yyyy");
System.out.println("Parsed Date = "+format.parse(stringDate));
The output was as follows
Parsed Date = Sun Jul 14 03:44:00 BST 2013
SimpleDateFormat formatter = new SimpleDateFormat("/* type your own format*/");
String formattedDate = formatter.format(todaysDate);
System.out.println("Formatted date is ==>"+formattedDate);
try this code
The modern answer for the sake of completeness. While the other answers were good answers in 2013, Date, DateFormat and SimpleDateFormat are now long outdated, and I recommend you replace them with their modern counterparts:
DateTimeFormatter parser
= DateTimeFormatter.ofPattern("EEE M/dd hh:mm a yyyy", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(dateString, parser);
The result is a LocalDateTime of 2013-07-14T03:44 as expected.
The format pattern string is still the same, and the need for an English language locale is the same.

SimpleDateFormat in Android giving unwanted time zone in Android 1.6

Given the following:
String dt = "Wed Jan 1 12:34:03 2010";
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy");
Date output = sdf.parse(dt);
Produces:
Wed Jan 1 12:34:03 ADT 2010
Where is the timezone coming from? I don't have z in my format pattern.
Thanks,
Doug
You're apparently displaying the toString() outcome of the Date object like as
System.out.println(output);
The format is specified in the javadoc and it indeed includes the timezone.
toString
public String toString()
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
You need SimpleDateFormat#format() to convert the obtained Date object to a String in the desired format before representing it. For example,
String s = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(output);
System.out.println(s); // 01-01-2010 12:34:03
When a Date object is created, the timezone is set from the system settings.
try output.getTimeZoneoffset() and it returns the offset in minutes (for ADT it's -180)

Categories

Resources