I use the following simple date format to parse a string,
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
String time = "Wed Mar 06 21:00:00 IST 2014";
Date date = dateFormat.parse(time);
This throws no error whreas,
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
String time = "Wed Mar 06 21:00:00 KST 2014";
Date date = dateFormat.parse(time);
Throws unparseable date exception.
where,
IST - Indian standard time
*KST - korean standard time*
I have decided to remove time zone because of the exception.
Is there any other way to work around this issue?
Please help
Avoid Time Zone Codes
Avoid those 3 or 4 letter codes for time zones. They are neither standardized nor unique. For example, the IST you cite as "Indian Standard Time" is also "Irish Standard Time". Plus they are confusing when in fact you may mean "Summer Time"/"Daylight Saving Time". Instead use proper time zone names, usually made up of a country plus primary city.
Use Sensible Formats For Date-Time Strings
That format "Wed Mar Thu 21:00:00 IST 2014" is not good. Besides being wrong (looks like you typed "Wed" or "Thu" where you should have a day-of-month number), it uses the 3-4 letter code, contains superfluous data (day of week), and assumes English readers. When moving date-time values around as text, use the sensible ISO 8601 format: YYYY-MM-DDTHH:MM:SS.sssZ such as 2014-03-04T23:20:28Z.
If changing that format is out of your control, you'll have to determine all the possible 3-4 letter codes that may be used in your data sets and see if your date-time library can handle them.
Avoid java.util.Date/Calendar
The java.util.Date and .Calendar classes are notoriously troublesome. They are outmoded as of Java 8 with the new java.time package. That package is based on the Joda-Time library. Use either Joda-Time or java.time.
Joda-Time
Note that in contrast to java.util.Date, a Joda-Time DateTime object truly knows its assigned time zone.
Here's some Joda-Time 2.3 example code.
String inputIso = "2014-03-19T21:00:00+05:30";
DateTimeZone timeZoneIndia = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( inputIso, timeZoneIndia );
// Adjust to Korea Time.
DateTimeZone timeZoneKorea = DateTimeZone.forID( "Asia/Seoul" );
DateTime dateTimeKorea = dateTimeIndia.withZone( timeZoneKorea );
// Adjust to UTC (GMT).
DateTime dateTimeUtc = dateTimeKorea.withZone( DateTimeZone.UTC );
String inputLame = "Thu Mar 20 21:00:00 KST 2014";
DateTimeZone timeZone = null;
if( inputLame.contains( "IST" )) { // Assume IST = India time.
timeZone = DateTimeZone.forID( "Asia/India" );
inputLame = inputLame.replace( " IST ", " ");
}
if( inputLame.contains( "KST" )) { // Assume KST = Korea time.
timeZone = DateTimeZone.forID( "Asia/Seoul" );
inputLame = inputLame.replace( " KST ", " ");
}
DateTimeFormatter formatter = DateTimeFormat.forPattern( "EEE MMM dd HH:mm:ss yyyy" ).withZone( timeZone ).withLocale( java.util.Locale.ENGLISH );
DateTime dateTimeLame = formatter.parseDateTime( inputLame );
Dump to console…
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeKorea: " + dateTimeKorea );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeLame: " + dateTimeLame );
When run…
dateTimeIndia: 2014-03-19T21:00:00.000+05:30
dateTimeKorea: 2014-03-20T00:30:00.000+09:00
dateTimeUtc: 2014-03-19T15:30:00.000Z
dateTimeLame: 2014-03-20T21:00:00.000+09:00
Both the dates are invalid, hence both would throw the error:
String time = "Wed Mar Thu 21:00:00 IST 2014";
Thu is invalid as the day of the week is already consumed by EEE - Wed combination. You need to set a day of the month there.
Try parsing the following date, it should work for your case:
String time = "Wed Mar 12 21:00:00 KST 2014";
Try this piece of code and see if KST is a valid time zone id
String[] timezoneIdArr = TimeZone.getAvailableIDs();
for (String tzId : timezoneIdArr) {
System.out.println(tzId);
}
If not, then enter zone id like "Asia/Seoul" or something. That should work.
Please note that I have not tried it. Please check exact spellings of the time zones.
Update:
Try the code below. See what KST yields. Uncomment and try with Asia/Seoul. For your reference, uncomment and see how PST works.
private static void calTest() {
String zone = "KST";
//String zone = "Asia/Seoul";
//String zone = "PST";
long millis = System.currentTimeMillis();
//get calendar of Korea time zone.
Calendar kst = Calendar.getInstance(TimeZone.getTimeZone(zone));
//set its time to a UTC millisecond value. probably redundant, but just to demonstrate
kst.setTimeInMillis(millis);
String formattedKst = formatTime(kst);
System.out.println(" Original - " + formattedKst);
//now we convert the formatted string back to a Calendar .
Calendar parsedKst = parseTime(formattedKst, zone);
System.out.println(" Parsed - ");
System.out.println("" + parsedKst.get(Calendar.YEAR) + "-"
+ (parsedKst.get(Calendar.MONTH) + 1) + "-"
+ parsedKst.get(Calendar.DATE) + " "
+ parsedKst.get(Calendar.HOUR_OF_DAY) + ":"
+ parsedKst.get(Calendar.MINUTE) + ":"
+ parsedKst.get(Calendar.SECOND) + "."
+ parsedKst.get(Calendar.MILLISECOND) + " "
+ parsedKst.getTimeZone().getID() + " "
+ parsedKst.getTimeZone().getDisplayName() + " "
);
}
private static Calendar parseTime(String formattedDateTime, String ID) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX zzz");
sdf.setTimeZone(TimeZone.getTimeZone(ID));
sdf.setLenient(false);
try {
sdf.parse(formattedDateTime);
} catch (ParseException e) {
e.printStackTrace();
}
return sdf.getCalendar();
}
private static String formatTime(Calendar cal) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX zzz");
sdf.setCalendar(cal);
return sdf.format(cal.getTime());
}
Related
SimpleDateFormat formatter = new SimpleDateFormat(“EEE MMM dd HH:mm:ss zzz yyyy”);
Date date= null ;
date = formatter.parse(String.valueOf(m.getSentDate()));
formatter = new SimpleDateFormat(“dd.MM.yyyy”);
tarih=formatter.format(date);
ERROR = “java.text.ParseException: Unparseable date: “Wed Jan 20 15:13:09 EET 2016″ (at offset 0)”
I get this error code permanently
java mail api from history= Mon jan 18 21:17:31 ETT 2016
I want to convert methods = 18.01.2016 21:17:31
I'm sorry my bad english
Your formatter should be working. So something else is wrong.
Here is my example code using your formatter and your input string.
String input = "Wed Jan 20 15:13:09 EET 2016";
SimpleDateFormat formatter = new SimpleDateFormat ( "EEE MMM dd HH:mm:ss zzz yyyy" );
Date date = null;
try {
date = formatter.parse ( input );
} catch ( ParseException e ) {
System.out.println ( "Exception… " + e );
}
System.out.println ( "date: " + date + " | date via formatter: " + formatter.format ( date ) + " | as Instant: " + date.toInstant () );
When run.
date: Wed Jan 20 05:13:09 PST 2016 | date via formatter: Wed Jan 20 15:13:09 EET 2016 | as Instant: 2016-01-20T13:13:09Z
Curly-Quotes
I am seeing many curly-quotes in your code and output. Hopefully those are not in the original. Curly quotes are typographically nice but inappropriate in programming code.
If you are using word-processors for your programming, stop that. They are not built for programming and will inject these curly-quotes among many other problems. Learn to use text editors intended for programming source code.
java.time
By the way, the old java.util.Date/.Calendar classes are notoriously troublesome. They have been supplanted in Java 8 and later by the new built-in java.time framework.
I am converting from epoch time (which is in UTC) to a format as shown below. Now I tried different SO answers to convert UTCDate from UTC to local time. But I am not getting the local time.
Any help would be appreciated.
String epochTime = "1436831775043";
Date UTCDate = new Date(Long.parseLong(epochTime));
Date localDate; // How to get this?
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("h:mm a");
String result = simpleDateFormat.format(UTCDate);
Also, the conversion has to be done without the help of any external library.
Java 8
String epochTime = "1436831775043";
Instant utcInstant = new Date(Long.parseLong(epochTime)).toInstant();
ZonedDateTime there = ZonedDateTime.ofInstant(utcInstant, ZoneId.of("UTC"));
System.out.println(utcInstant);
LocalDateTime here = there.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(here);
Which outputs:
2015-07-13T23:56:15.043Z
2015-07-14T09:56:15.043
After thoughts...
I think you're chasing your tail. Date is just a container for the number of milliseconds since the epoch (January 1, 1970, 00:00:00 GMT). It doesn't internally carry a representation of a time zone (AFAIK).
For example...
String epochTime = "1436831775043";
Date UTCDate = new Date(Long.parseLong(epochTime));
// Prints the "representation" of the Date
System.out.println(UTCDate);
// Local date/time format...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy h:mm:ss a");
try {
System.out.println("local format: " + simpleDateFormat.format(UTCDate));
System.out.println("local Date: " + simpleDateFormat.parse(simpleDateFormat.format(UTCDate)));
} catch (ParseException ex) {
Logger.getLogger(JavaApplication203.class.getName()).log(Level.SEVERE, null, ex);
}
// UTC date/time format
try {
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("utc format: " + simpleDateFormat.format(UTCDate));
System.out.println("utc date: " + simpleDateFormat.parse(simpleDateFormat.format(UTCDate)));
} catch (ParseException ex) {
Logger.getLogger(JavaApplication203.class.getName()).log(Level.SEVERE, null, ex);
}
Which outputs...
Tue Jul 14 09:56:15 EST 2015
local format: 14/07/2015 9:56:15 AM
local Date: Tue Jul 14 09:56:15 EST 2015
utc format: 13/07/2015 11:56:15 PM
utc date: Tue Jul 14 09:56:15 EST 2015
If you have a look at local Date and utc date they are the same thing, even though the local format and utc format are formatted correctly.
So, instead of chasing your tale trying to get Date to "represent" a value you want, either use Java 8's Time API or JodaTime to manage the Time Zone information or simply format the Date into the Time Zone you want...
Further, if we do something like...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy h:mm:ss a");
Date localDate = simpleDateFormat.parse(simpleDateFormat.format(UTCDate));
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date utcDate = simpleDateFormat.parse(simpleDateFormat.format(UTCDate));
System.out.println(localDate.getTime());
System.out.println(utcDate.getTime());
System.out.println(localDate.equals(utcDate));
It will print...
1436831775000
1436831775000
true
You can set your time zone in the formatter:
simpleDateFormat.setTimeZone(TimeZone.getDefault());
I tried converting this date the following way:
SimpleDateFormat fromFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSSZ");
but I got:
java.text.ParseException: Unparseable date: "2014-09-20 00:00:00 -0500" (at offset 20)
That "-0500" is the offset from UTC, in RFC822 format. You just want Z, without the SSS.
The Android SimpleDateFormat docs have it like this in the table:
Symbol: Z
Meaning: time zone (RFC 822)
Kind: (Time Zone)
Example: Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00
I would also personally specify a locale, as a matter of course: this is a machine-readable format rather than a human-oriented format, so I'd usually specify Locale.US:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z",
Locale.US);
String text = "2014-08-20 00:00:00 -0500";
System.out.println(format.parse(text));
The answer by Jon Skeet is correct.
Standard Date-Time Format
Here is some example code showing how to transform your string into compliance with ISO 8601.
String inputRaw = "2014-08-20 00:00:00 -0500";
String input = inputRaw.replaceFirst( " ", "T" ).replaceFirst( " ", "" ); // Replace first SPACE with a 'T', and delete second SPACE.
// input is "2014-08-20T00:00:00-0500".
Joda-Time
You can pass that compliant string directly to the constructor of DateTime in Joda-Time. Ditto for the equivalent in the java.time package in Java 8 (inspired by Joda-Time).
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" ); // Specify it rather than have JVM's default applied.
DateTime dateTimeMontréal = new DateTime( input, timeZone );
DateTime dateTimeUtc = dateTimeMontréal.withZone( DateTimeZone.UTC );
Dump to console.
System.out.println( "inputRaw: " + inputRaw );
System.out.println( "input: " + input );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run…
inputRaw: 2014-08-20 00:00:00 -0500
input: 2014-08-20T00:00:00-0500
dateTimeMontréal: 2014-08-20T01:00:00.000-04:00
dateTimeUtc: 2014-08-20T05:00:00.000Z
my timezone is GMT+1.
so a "Date"-object with "22.09.1985 00:00UTC" prints "Sun Sep 22 01:00:00 CEST 1985" on the tostring function.
Now i'm trying to create this date by parsing "22/09/1985" with simpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getDefault());
Date d = sdf.parse("22/09/1985");
=> Sun Sep 22 00:00:00 CEST 1985
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date d = sdf.parse("22/09/1985");
=> Sun Sep 22 02:00:00 CEST 1985
how can i configure simpledateformat that it creates an Date which prints "Sun Sep 22 01:00:00 CEST 1985" with input string "22/09/1985"?
My assumption was wrong,
22.09.1985 00:00UTC is actually 22.09.1985 02:00CET
so
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date d = sdf.parse("22/09/1985");
is exactly what i wanted, the date i compared it with was wrong.
Avoid java.util.Date & Calendar
You’ve found one of the many reasons to avoid using java.util.Date & .Calendar. They are notoriously troublesome. Either use Joda-Time or, in Java 8, the new java.time package which is inspired by Joda-Time and defined by JSR 310.
Search StackOverflow for "joda date" to find many examples.
Time Zone
You said:
my timezone is GMT+1.
Incorrect, your local offset from UTC/GMT is +01. That is not your time zone. A time zone is an offset plus rules about Daylight Saving Time (DST) and other anomalies.
And that offset should have two digits: +01 (or +01:00) rather than +1, according to the ISO 8601 standard.
Avoid the 3 or 4 letter codes such as CET. They are neither standardized nor unique. Use proper time zone names.
Generally speaking, you should specify a time zone in all your date-time work rather than rely on the current JVM's default.
In both Joda-Time and java.time, a date-time object truly knows its assigned time zone. A java.util.Date has no time zone, but seems to because its toString applies the default time zone when creating a String representation, as you sadly learned the hard way.
Example Code
Some code using Joda-Time 2.3.
String input = "22/09/1985";
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Amsterdam" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy" );
DateTime dateTime = formatter.withZone( timeZone ).parseDateTime( input );
DateTime dateTimeUtcGmt = dateTime.withZone( DateTimeZone.UTC );
DateTime dateTimeIndia = dateTime.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
String outputMontreal = DateTimeFormat.forStyle( "FF" ).withZone( DateTimeZone.forID( "America/Montreal" ) ).withLocale( Locale.CANADA_FRENCH ).print( dateTime );
// All of the above date-time represent the very same moment in the timeline of the Universe.
Dump to console…
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtcGmt: " + dateTimeUtcGmt );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "outputMontreal: " + outputMontreal );
When run…
dateTime: 1985-09-22T00:00:00.000+02:00
dateTimeUtcGmt: 1985-09-21T22:00:00.000Z
dateTimeIndia: 1985-09-22T03:30:00.000+05:30
outputMontreal: samedi 21 septembre 1985 18 h 00 EDT
The fact that you're parsing a date string, using a specific time zone, doesn't make the printed Date object to use that time zone. You're still using the same implementation of Date#toString(), which formats the Date object using the default timezone.
What you would need is to format your Date object with that SimpleDateFormat object. And if you have that specific string, then you would need another SimpleDateFormat object for parsing that string:
String dateString = "22/09/1985";
SimpleDateFormat parser = new SimpleDateFormat("dd/MM/yyyy");
Date parsedDate = parser.parse(dateString);
SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(formatter.format(parsedDate));
Java Date doesn't have the concept of TimeZone associated with it. You can only format a Date object using a specified timezone, and get a string. Or else, switch to JodaTime library.
Date is a relatively "dumb" class, as it just represents the number of milliseconds since 1970-01-01 00:00:00 UTC.
If you want to print out a Date as if it were a different timezone, you need to construct a DateFormat / SimpleDateFormat for that TimeZone and format it to a String that way.
I have got the following created date "Fri Jan 24 12:22:13 +0000 2014" from twitter , but when it comes to parsing , the goes to unparsable exception error at "z"
Would you please tell em what is the correct time format ?
The below is my code
String dateString = fullS.substring(0, 11) + " "+ year;
String timeZoneHK = content.getTimeZone();
SimpleDateFormat inputDf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
SimpleDateFormat outputDf = new SimpleDateFormat("HH:mm:ss EEE MMM dd yyyy");
Date date;
try {
TimeZone timezone = null;
date = inputDf.parse(dateString);
if(timeZoneHK.equals("Hong Kong")){
timezone = TimeZone.getTimeZone("Asia/Hong_Kong");
}
outputDf.setTimeZone(timezone);
String result =outputDf.format(date);
//System.out.println(outputDf.format(date));
viewHolder.txtDate.setText(result);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Exception
01-24 22:10:30.061: W/System.err(12573): java.text.ParseException: Unparseable date: "Fri Jan 24 13:37:08 +0000 2014" (at offset 0)
Use complete date String "Fri Jan 24 12:22:13 +0000 2014" if wanted to apply the specified format. And change z to Z:
SimpleDateFormat inputDf = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
Refer to: SimpleDateFormat
Z - time zone (RFC 822) - (Time Zone) Z/ZZ/ZZZ:-0800 - ZZZZ:GMT-08:00 ZZZZZ:-08:00
Joda-Time
This kind of work is much easier with the third-party open-source date-time library, Joda-Time.
Here is some example code using Joda-Time 2.3.
String input = "Fri Jan 24 12:22:13 +0000 2014";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "EEE MMM dd HH:mm:ss Z yyyy" );
// Parse as UTC/GMT (no time zone offset) so we may conveniently compare to input.
DateTime dateTimeUtc = formatter.withZone( DateTimeZone.UTC ).parseDateTime( input );
// Convert to Hong Kong time zone.
DateTime dateTimeHongKong = dateTimeUtc.toDateTime( DateTimeZone.forID( "Asia/Hong_Kong" ) );
Dump to console…
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeHongKong: " + dateTimeHongKong );
When run…
dateTimeUtc: 2014-01-24T12:22:13.000Z
dateTimeHongKong: 2014-01-24T20:22:13.000+08:00
Back To Date
If you need a java.util.Date for other purposes, convert your DateTime.
java.util.Date date = dateTime.toDate();