I just installed the upgrade version Lollipop on my android phone and this doesn't work anymore:
String time = "Apr 07 10:35:27 CEST 2015";
long l1 = new SimpleDateFormat("MMM dd HH:mm:ss zzz yyyy").parse(time).getTime();
long l2 = new SimpleDateFormat("MMM dd HH:mm:ss zzz yyyy",
Locale.ENGLISH).parse(time).getTime();
Both doesn't work:
W/System.err(11473): java.text.ParseException: Unparseable date: "avr. 07 10:35:27 CEST 2015" (at offset 17)
The problem is that SimpleDateFormat now returns GMT+02:00 instead of previously CEST after I installed 5.0
"CEST" is not a recognized timezone pattern according to CLDR, which Android uses. It may be that it was recognized in prior because SimpleDateFormat was lifted from Apache Harmony, which followed Java's own time format standard.
Related
Following is the code to parse date. I have used 'joda-time:joda-time:2.9.9' lib for formatter.
String date = "Sun Sep 04 17:29:52 +0000 2022";
DateTimeFormatter dateFormat = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss Z
yyyy").withLocale(Locale.UK);
dateFormat.parseDateTime(date);
Above code was throwing illegelArgument exception in Android 12. When I changed locale from UK to US, its started working.
But strange thing is that if I tried to parse Wed Mar 23 14:28:32 +0000 2016 this date with above code, its working in all OS.
Out of mind question is why one date is getting parse and another is not.
What's actually changed in Android 12 that suddenly code is getting failed?
What's actually changed in Android 12 that suddenly code is getting
failed?
Earlier, the short name for September in the Locale.UK was Sep but it got changed to Sept starting with Java 16. Check this related thread.
There is no change in other short names in the Locale.UK and therefore it worked for Wed Mar 23 14:28:32 +0000 2016 for example.
Modern Date-Time API
For the sake of completeness, I would like to discuss a bit about the modern date-time API. Probably you must have already seen the following note on the Home Page of the Joda-Time API:
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.
Demo using the modern date-time API:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "Sun Sep 04 17:29:52 +0000 2022";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.ROOT);
OffsetDateTime zdt = OffsetDateTime.parse(strDateTime, formatter);
System.out.println(zdt);
}
}
Output:
2022-09-04T17:29:52Z
Notice that I have use Locale.ROOT in the demo. If you use Locale.UK, it will throw the same error that you have got. However, if you change Sep to Sept and use Locale.UK, it will work.
Learn more about the modern Date-Time API from Trail: Date Time.
import java.text.SimpleDateFormat;
import java.util.Locale;
Locale locale = new Locale("bd", "bn");
String pattern = "EEEEE MMMMM yyyy HH:mm:ss.SSSZ";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, locale);
String date = simpleDateFormat.format(System.currentTimeMillis());
System.out.println("DateTime :: " + date);
Please provide the Simple Date format for the following in android
The DateFormat of 21/08/2021 -> SimpleDateFormat("dd/MM/yyyy")
I Want the SimpleDateFormat for the following two Values
The DateFormat of January 01, 2021 at 3:37:59 PM UTC+5:30 -> SimpleDateFormat("?")
The DateFormat of Wed Sep 15 10:10:59 GMT+05:30 2021 -> SimpleDateFormat("?")
Thanks in advance
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*.
Solution using java.time, the modern Date-Time API:
For the first format, you can build the required DateTimeFormatter using the DateTimeFormatterBuilder.
For the second pattern, you can simply use DateTimeFormatter with the required pattern letters.
Demo:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
DateTimeFormatter dtf1 =
new DateTimeFormatterBuilder()
.appendPattern("MMMM dd, uuuu 'at' h:mm:ss a 'UTC'")
.appendOffset("+H:mm", "Z")
.toFormatter(Locale.ENGLISH);
System.out.println(now.format(dtf1));
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss OOOO uuuu", Locale.ENGLISH);
System.out.println(now.format(dtf2));
}
}
Output:
September 15, 2021 at 10:22:43 PM UTC+5:30
Wed Sep 15 22:22:43 GMT+05:30 2021
ONLINE DEMO
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.
I'm parsing a String that has a date format into a variable of type date. When I ran the code in the emulator it worked fine because the time zone was UTC. Once I tried to run it on my phone it didn"t work because the time zone is GMT+01:00 as you can see in the error below
Caused by: java.text.ParseException: Unparseable date: "Mon Feb 01 22:55:22 GMT+01:00 2021"
And here is the code withe the problem
val cal = Calendar.getInstance()
val sdf = SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy",Locale.ENGLISH)
cal.time = sdf.parse(reminderdate)
Your help would be appreciated thank you
I suggest you to try this:
SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);
Im trying parse a String with a date to convert it into a Date format. Strings are in the following format.
Thursday, Jan 09 2020; 04:31:59 PM (GMT +05:30)
SimpleDateFormat sdf3 = new SimpleDateFormat("EEE, MMM dd yyyy; hh:mm:ss a",Locale.ENGLISH);
for(int i=0 ; i <jArr.length() ; i++){
String tempDate = jArr.get(i).toString();
dateList.add(tempDate);
}
try{
Date d1 = sdf3.parse(dateList.get(0));
} catch (Exception e) {
e.printStackTrace();
}
Note: This function is working fine for android version > 6.
To get your desired format you have to use SimpleDateFormat like below:
String dateString = "Thursday, Jan 09 2020; 04:31:59 PM (GMT +05:30)";
SimpleDateFormat sourceFormat = new SimpleDateFormat("EEE, MMM dd yyyy; hh:mm:ss a",Locale.ENGLISH);
try{
Date d1 = sourceFormat.parse(dateString);
} catch (Exception e) {
e.printStackTrace();
}
SimpleDateFormat targetFormat = new SimpleDateFormat("dd/MM/yy; hh:mm:ss a", Locale.ENGLISH)
String desiredString = targetFormat.format(d1);
//desiredString is now "09/01/20; 04:31:59 PM"
Try this EPOCH_FORMAT in the arguments of SimpleDateFormat :
String formatter = "EE MMM dd HH:mm:ss z yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(formatter,Locale.US);
java.time and ThreeTenABP
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"EEEE, MMM dd uuuu; hh:mm:ss a '(GMT' xxx')'", Locale.ENGLISH);
String tempDate = "Thursday, Jan 09 2020; 04:31:59 PM (GMT +05:30)";
OffsetDateTime odt = OffsetDateTime.parse(tempDate, formatter);
System.out.println(odt);
Output from this snippet is:
2020-01-09T16:31:59+05:30
In order to get the correct time you need to parse the GMT offset that is in the string.
I am using java.time, the modern Java date and time API because SimpleDateFormat and Date are poorly designed and long outdated, the former in particular notoriously troublesome. And because java.time is so much nicer to work with.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
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.time to 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.
SimpleDateFormat parse works in a JUnit test (Robolectric test runner), but fails if run on device.
#Test
public void testDateParse() throws ParseException {
String datetime = "Wed Sep 03 12:59:27 BST 2014";
new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH)
.parse(datetime);
}
When it fails on the device the exception says:
java.text.ParseException: Unparseable date: "Wed Sep 03 12:59:27 BST 2014" (at offset 20)
Offset 20 is the B of BST, so it's timezone related.
Indeed "GMT" works: String datetime = "Wed Sep 03 12:59:27 GMT 2014";
I guess the interesting question here is why does this run ok on Robolectric but fails to run on an Android test.
Robo runs on the JVM and there is a difference in behaviour for Timezone parsing between Android and good ol' Java.
In the Android documentation:
Other than the special cases "UTC" and "GMT" (which are synonymous in this context, both corresponding to UTC), Android does not support the deprecated three-letter time zone IDs used in Java 1.1.
In the Java documentation:
the ID for a TimeZone, either an abbreviation such as "PST", a full name such as "America/Los_Angeles", or a custom ID such as "GMT-8:00". Note that the support of abbreviations is for JDK 1.1.x compatibility only and full names should be used.
So the answer is that the 3-letter abbreviations should not be used (because they are ambiguous), but can be used on the JVM for compatibility reasons, but not on Android.