Handling timezone when parsing date in Java 6 - java

I am trying to parse/validate the date 2013-06-19T12:00-05:00 using Java 6
I have tried several patterns, including following:
yyyy-MM-dd'T'HH:mmz
yyyy-MM-dd'T'HH:mmZ
yyyy-MM-dd'T'HH:mm'Z'
yyyy-MM-dd'T'HH:mm Z
yyyy-MM-dd'T'HH:mm z
yyyy-MM-dd'T'HH:mm'z'
yyyy-MM-dd'T'HH:mm-Z
yyyy-MM-dd'T'HH:mm-z
yyyy-MM-dd'T'hh:mm:ssZ
yyyy-mm-DD'T'hh:mm:ssZ
yyyy-MM-DD'T'hh:mm:ssZ
yyyy-MM-dd'T'HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ssz
but keep getting ParseException.
What would be the appropriate format/pattern for parsing 2013-06-19T12:00-05:00?
Thanks.

I would suggest that you use the excellent Joda-Time library to do this, specifically the parse(String str) method of the DateTime class, which will parse your example date using the default ISODateTimeFormat.dateTimeParser()
The JavaDoc for DateTime.parse(String str) is at http://www.joda.org/joda-time/apidocs/org/joda/time/DateTime.html#parse%28java.lang.String%29 and you can read more about Joda-Time at http://www.joda.org/joda-time/

String dateString = "2013-06-19T12:00-05:00";
String pattern = "yyyy-MM-dd'T'HH:mmZ";
DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern);
DateTime dateTime = dtf.parseDateTime(dateString);
Date ans=dateTime.toDate();
System.out.println(ans);

Use simpledateformat with pattern like "yyyy-MM-dd'T'HH-mm:ss:SS"

The Joda-Time 2.3 library is already built to handle that variation of ISO 8601 format. No need to create a formatter.
I arbitrarily chose Montréal Québec as a time zone because of your -05:00 time zone offset. You may rather work with UTC/GMT date-times in which case you can pass a pre-defined instance: DateTimeZone.UTC.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
String dateTimeString = "2013-06-19T12:00-05:00";
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" ); // Or for UTC/GMT, use: DateTimeZone.UTC
DateTime dateTime = new DateTime( dateTimeString, timeZone );
Dump to console…
System.out.println( "dateTimeString: " + dateTimeString );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime in UTC/GMT: " + dateTime.toDateTime( DateTimeZone.UTC ) );
When run…
dateTimeString: 2013-06-19T12:00-05:00
dateTime: 2013-06-19T13:00:00.000-04:00
dateTime in UTC/GMT: 2013-06-19T17:00:00.000Z
Note the one hour difference because Montréal Québec was in Daylight Saving Time (DST) on that date.

The date 2013-06-19T12:00-05:00 can't be parsed under Java 6 in current form. On other hand using Joda-Time seems to be an overkill.
To solve problem I added timezone to the date:
public Date extractDate(String dateStr) {
Pattern aPattern = Pattern.compile("\\d+([+-]\\d+:\\d+)$", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher matcher = aPattern.matcher(dateStr);
if(matcher.find()){
String timezone = matcher.group(1);
System.out.println("timezone:" + timezone);
dateStr = StringUtils.replace(dateStr, timezone, "GMT" + timezone);
}
Date date = null;
String [] datePatterns = {"yyyy-MM-dd'T'HH:mmZ"};
try {
date = DateUtils.parseDateStrictly(dateStr, datePatterns);
}
catch (Exception except) {
except.printStackTrace();
}
return date;
}

Related

Converting calendar to date in dd-MMM-yyyy format

I am trying to add 17 days to 10-APR-2014 and convert the date to dd-MMM-yyyy format, but I am getting Sun Apr 27 00:00:00 GMT+05:30 2014.
Here is my code:
import java.util.*;
import java.text.*;
public class HelloWorld{
public static void main(String []args){
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
Calendar c = Calendar.getInstance();
c.setTime(new Date());
c.add(Calendar.DATE, 17);
String output = sdf.format(c.getTime());
System.out.println(output);
System.out.print(new SimpleDateFormat("dd-MMM-yyyy").parse(output));
}
}
How can I make the output be 27-Apr-2014?
You are printing a Date parsed from a String formatted from the calendar date.
Instead, print the formatted calendar date:
System.out.print(new SimpleDateFormat("dd-MMM-yyyy").format(c.getTime()));
If displaying and using the dates is disjunct, do this:
Date date; // from Calendar or wherever
String str = new SimpleDateFormat("dd-MMM-yyyy").format(date));
// display str
Then when you want to do something with a selected date:
String selection;
Date date = new SimpleDateFormat("dd-MMM-yyyy").parse(selection));
// do something with date
The answer by Bohemian is correct. Here I present an alternative solution.
Avoid j.u.Date
The java.util.Date and .Calendar classes bundled with Java are notoriously troublesome. Avoid them. Use either Joda-Time or the new java.time package in Java 8.
Date-Only
If you need only a date, without any time component, both Joda-Time and java.time offer a LocalDate class.
Time Zone
Even for a date-only, you still need a time zone to get "today". At any moment the date may vary ±1 depending on your location on the globe. If you do not specify a time zone, the JVM's default time zone will be applied.
Example Code
Here is some example code in Joda-Time 2.3.
Determine "today" based on some time zone. Add seventeen days.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
LocalDate today = new LocalDate( timeZone );
LocalDate seventeenDaysLater = today.plusDays( 17 );
Generate a String representation of the date-time value…
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MMM-yyyy" );
String output = formatter.print( seventeenDaysLater );
Dump to console…
System.out.println( "today: " + today );
System.out.println( "seventeenDaysLater: " + seventeenDaysLater );
System.out.println( "output: " + output );
When run…
today: 2014-04-21
seventeenDaysLater: 2014-05-08
output: 08-May-2014

How to set the TimeZone for String parsing in Android

I try to parse a String and set a time zone, but I can't produce the desired result.
String dtc = "2014-04-02T07:59:02.111Z";
SimpleDateFormat readDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Date date = null;
try {
date = readDate.parse(dtc);
Log.d("myLog", "date "+date);
} catch (ParseException e) {
Log.d("myLog", "dateExcep " + e);
}
SimpleDateFormat writeDate = new SimpleDateFormat("dd.MM.yyyy, HH.mm");
writeDate.setTimeZone(TimeZone.getTimeZone("GMT+04:00"));
String dateString = writeDate.format(date);
At the output of the variable "dateString" still gives the time 07:59:02 , and I want to make it +4 hours in advance that is 11:59:02
You need to instruct the read-formatter to interprete the input as UTC (GMT - remember that Z stands for UTC in ISO-8601-format):
String dtc = "2014-04-02T07:59:02.111Z";
SimpleDateFormat readDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
readDate.setTimeZone(TimeZone.getTimeZone("GMT")); // missing line
Date date = readDate.parse(dtc);
SimpleDateFormat writeDate = new SimpleDateFormat("dd.MM.yyyy, HH.mm");
writeDate.setTimeZone(TimeZone.getTimeZone("GMT+04:00"));
String s = writeDate.format(date);
Then you will get:
02.04.2014, 11.59
Joda-Time
Doing date-time work much easier and simpler with the Joda-Time library than with the notoriously troublesome bundled java.util.Date & .Calendar classes.
Time Zone
Using proper time zone names, rather than a specific offset, is generally a wiser approach.
Example Code
Here is some example code using Joda-Time 2.3.
Notice:
Joda-Time has built-in parsers for strings in ISO 8601 format. No need to instantiate parsing or formatting objects.
Joda-Time is both parsing the UTC string and adjusting it to another time zone all in one call to the DateTime constructor.
When converting to a UTC-based dateTime in the last line, we still have the same moment in the timeline of the Universe (same count of milliseconds since Unix epoch).
Source…
String input = "2014-04-02T07:59:02.111Z";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Dubai" );
DateTime dateTimeDubai = new DateTime( input, timeZone ); (a) Parse, (b) Adjust time zone.
DateTime dateTimeUtc = dateTimeDubai.withZone( DateTimeZone.UTC );
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTimeDubai: " + dateTimeDubai );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run…
input: 2014-04-02T07:59:02.111Z
dateTimeDubai: 2014-04-02T11:59:02.111+04:00
dateTimeUtc: 2014-04-02T07:59:02.111Z
you can take whatever pattern you want like i have date+ time zone. so you can set according to you. here is my code.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
here i have set the date format.
String currentDate = dateFormat.format(currentLocalTime);
String localTime = date.format(currentLocalTime);// to get the time zone i have used this.
String newtime=currentDate+localTime;// and then i have apeend this now print log you will get the desire result.

UTC date parsing inconsistency in Java

Something weird is happening while parsing a UTC/GMT date. I set the date format as
"yyyy-MM-dd'T'HH:mm:ss'Z'"
where Z is for UTC. And I give following date string to parse:
String startTimestampString = "2013-10-02T00:00:00Z";
I hope to get same date as output but instead it shows
2013-10-01 17:00:00.0
Now sure from where this 7 hour lag coming from?
Code:
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class DateTest {
public static void main(String[] args) throws ParseException {
SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
date.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(TimeZone.getTimeZone("UTC").toString());
String startTimestampString = "2013-10-02T00:00:00Z";
long startTimestamp = date.parse(startTimestampString).getTime();
System.out.println(String.format("Long %d and timestamp %s", startTimestamp, new Timestamp(startTimestamp).toString()));
}
}
Output:
sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
Long 1380672000000 and timestamp 2013-10-01 17:00:00.0 // ERROR timestamp should have been 2013-10-02 00:00:00.0
java.util.Date Has No Time Zone
As the comments said, your problem is not understanding the confusing way in which java.util.Date works.
A Date object has no time zone, but seems to have one because its toString method applies your JVM's default time zone when generating the textual representation (the String being returned).
This poor design choice by the Java team has caused so much confusion, including countless similar Questions on StackOverflow.
The Date Is Not The String
A key idea here is that the String generated by the toString method is an entirely new object. This string is not the Date. The string is a particular representation of that moment in history as seen from you default time zone. The same moment in history appears as two different time-of-day values when seen from the Paris or Montréal or Kolkata time zones.
Avoid java.util.Date
Do not waste your time with java.util.Date and .Calendar and SimpleDateFormat. They are notoriously troublesome. Use Joda-Time or new java.time package in Java 8 (inspired by Joda-Time).
Joda-Time
Example code in Joda-Time 2.3. Your format is in the standard ISO 8601 format. Joda-Time uses ISO 8601 as its defaults, so no need for parsers/formatters in your case. Joda–Time automatically uses built-in formatters to parse ISO 8601 compliant strings.
String input = "2013-10-02T00:00:00Z";
DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTimeParis = new DateTime( input, timeZoneParis );
DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) );
DateTime dateTimeIndia = dateTimeParis.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC );
DateTimeFormatter formatter = DateTimeFormat.forStyle( "FF" ).withLocale( Locale.CANADA_FRENCH );
Dump to console…
System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeMontréal formatted: " + formatter.print( dateTimeMontréal ) );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run…
dateTimeParis: 2013-10-02T02:00:00.000+02:00
dateTimeMontréal: 2013-10-01T20:00:00.000-04:00
dateTimeMontréal formatted: mardi 1 octobre 2013 20 h 00 EDT
dateTimeIndia: 2013-10-02T05:30:00.000+05:30
dateTimeUtc: 2013-10-02T00:00:00.000Z

Java Reflection - calling a a date function

I am getting a string "Date.UTC(2013,10,9,0,0,0)" from a function return. I want to construct a date out of it. something like "2013-10-09 00:00:00"
Can I use reflection to give me a timestamp from the string?
Or do I have to use a substring and split based on "," and construct the date string?
Use a SimpleDateFormat with a pattern appropriate for your input format:
Date date = new SimpleDateFormat("'Date.UTC('yyyy,MM,dd,HH,mm,ss)").parse(str);
Here's some test code:
String str = "Date.UTC(2013,10,9,0,0,0)";
Date date = new SimpleDateFormat("'Date.UTC('yyyy,MM,dd,HH,mm,ss)").parse(str);
System.out.println(date);
Output:
Wed Oct 09 00:00:00 EST 2013
Note that Date objects carry no formatting information. If you want to print a Date in a particular format, create a DateFormat for that purpose.
To parse a DateTime in any Format, you should have a look at http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html, especially at the method parse()
The API will serve any further information you need to accomplish your goal.
Nope, no need for reflection nor string-splitting. Let a date-time formatter do the parsing work for you.
The answer by Bohemian is correct technically. But not advisable. The bundled java.util.Date and Calendar are notoriously troublesome and should be avoided. Use either Joda-Time or the new java.time.* package found in Java 8.
Example Code
String input = "Date.UTC(2013,10,9,0,0,0)";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "'Date.UTC('yyyy,MM,dd,HH,mm,ss)" ).withZone( DateTimeZone.UTC );
DateTime dateTime = formatter.parseDateTime( input );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime in India: " + dateTime.withZone( DateTimeZone.forID( "Asia/Kolkata" ) ) );
When run…
dateTime: 2013-10-09T00:00:00.000Z
dateTime in India: 2013-10-09T05:30:00.000+05:30

Date in to UTC format Java

I have a string like this 2013-10-22T01:37:56. I Need to change this string into UTC Date format like this MM/dd/yyyy KK:mm:ss a. I have tried some code but it is not returning the UTC datetime.
My code is
String[] time = itsAlarmDttm.split("T");
String aFormatDate = time[0]+ " "+time[1];
String aRevisedDate = null;
try {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Date dateObj = sdf.parse(aFormatDate);
aRevisedDate = new SimpleDateFormat("MM/dd/yyyy KK:mm:ss a").format(dateObj);
System.out.println(aRevisedDate);
} catch (ParseException e) {
itsLogger.error("Error occured in Parsing the Data Time Object: " +e.getMessage());
} catch (Exception e) {
itsLogger.error("Error occured in Data Time Objecct: " +e.getMessage());
}
I am getting the output is MM/dd/yyyy KK:mm:ss a format. But Not UTC time format.
How to solve this issue?
Try this... Worked for me and printed 10/22/2013 01:37:56 AM Ofcourse this is your code only with little modifications.
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC")); // This line converts the given date into UTC time zone
final java.util.Date dateObj = sdf.parse("2013-10-22T01:37:56");
aRevisedDate = new SimpleDateFormat("MM/dd/yyyy KK:mm:ss a").format(dateObj);
System.out.println(aRevisedDate);
Try to format your date with the Z or z timezone flags:
new SimpleDateFormat("MM/dd/yyyy KK:mm:ss a Z").format(dateObj);
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
// or SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy KK:mm:ss a Z" );
sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
System.out.println( sdf.format( new Date() ) );
What Time Zones?
No where in your question do you mention time zone. What time zone is implied that input string? What time zone do you want for your output? And, UTC is a time zone (or lack thereof depending on your mindset) not a string format.
ISO 8601
Your input string is in ISO 8601 format, except that it lacks an offset from UTC.
Joda-Time
Here is some example code in Joda-Time 2.3 to show you how to handle time zones. Joda-Time has built-in default formatters for parsing and generating String representations of date-time values.
String input = "2013-10-22T01:37:56";
DateTime dateTimeUtc = new DateTime( input, DateTimeZone.UTC );
DateTime dateTimeMontréal = dateTimeUtc.withZone( DateTimeZone.forID( "America/Montreal" );
String output = dateTimeMontréal.toString();
As for generating string representations in other formats, search StackOverflow for "Joda format".
java.time
It’s about time someone provides the modern answer. The modern solution uses java.time, the modern Java date and time API. The classes SimpleDateFormat and Date used in the question and in a couple of the other answers are poorly designed and long outdated, the former in particular notoriously troublesome. TimeZone is poorly designed to. I recommend you avoid those.
ZoneId utc = ZoneId.of("Etc/UTC");
DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern(
"MM/dd/yyyy hh:mm:ss a zzz", Locale.ENGLISH);
String itsAlarmDttm = "2013-10-22T01:37:56";
ZonedDateTime utcDateTime = LocalDateTime.parse(itsAlarmDttm)
.atZone(ZoneId.systemDefault())
.withZoneSameInstant(utc);
String formatterUtcDateTime = utcDateTime.format(targetFormatter);
System.out.println(formatterUtcDateTime);
When running in my time zone, Europe/Copenhagen, the output is:
10/21/2013 11:37:56 PM UTC
I have assumed that the string you got was in the default time zone of your JVM, a fragile assumption since that default setting can be changed at any time from another part of your program or another programming running in the same JVM. If you can, instead specify time zone explicitly, for example ZoneId.of("Europe/Podgorica") or ZoneId.of("Asia/Kolkata").
I am exploiting the fact that you string is in ISO 8601 format, the format the the modern classes parse as their default, that is, without any explicit formatter.
I am using a ZonedDateTime for the result date-time because it allows us to format it with UTC in the formatted string to eliminate any and all doubt. For other purposes one would typically have wanted an OffsetDateTime or an Instant instead.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601

Categories

Resources