Converting string to java.util.date - java

I am working with date strings that need to be converted to java.util.date objects.
I'm using the following code to do this:
public void setDates(String from, String to) throws ParseException
{
Date fromDate = new Date();
Date toDate = new Date();
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
fromDate = df.parse(from);
toDate = df.parse(to);
this.setDepartDate(fromDate);
this.setReturnDate(toDate);
}
The problem is that the string values that I have to convert are always(And I have no control over this) in the following format: "20 September, 2013".
This causes my function to through a ParseException when it reaches fromDate = df.parse(from);
Could anyone help me understand why, and perhaps suggest a solution?

Check out the SimpleDateFormat JavaDocs for the available format options, but basically, you need to change your date format to something more like dd MMMM, yyyy
try {
String dateValue = "20 September, 2013";
SimpleDateFormat df = new SimpleDateFormat("dd MMMM, yyyy");
Date date = df.parse(dateValue);
System.out.println(date);
} catch (ParseException exp) {
exp.printStackTrace();
}
Which outputs...
Fri Sep 20 00:00:00 EST 2013

As per the javadoc use following format
SimpleDateFormat df = new SimpleDateFormat("dd MMMMM, yyyy");
Also decide if this parsing needs to be Lenient or not and if it needs to be strict use setLenient(false)
By default, parsing is lenient: If the input is not in the form used
by this object's format method but can still be parsed as a date, then
the parse succeeds. Clients may insist on strict adherence to the
format by calling setLenient(false).
Also note that SimpleDateFormat is not threadsafe. If there is a choice I recommend using Joda Time Library that provide much enhanced functionality.

You wrote
[...] in the following format: "20 September, 2013".
Then your SimpleDateFormat should be
"dd MMM, yyyy"
You can check out the SimpleDateFormat documentation.

When you parse a date, you need to know some context or use some assumptions. You can use SimpleDateFormat, but you may need to pre-parse the string to see which format it is before you use it. You may have to try multiple format to see if one or more way to parse the date.
BTW is 01/02/30 the 1st Feb 1930 or 2nd Jan 2030 or 30th feb 2001, you need to know something about what the date is likely to mean or have some control over the format.

LocalDate
The modern approach uses the java.time classes that supplanted the troublesome old date-time classes (Date, Calendar, etc.) years ago.
String input = "20 September, 2013" ;
Locale locale = Locale.US ; // Determines the human language and cultural norms used in parsing the input string.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "d MMMM, uuuu" , locale ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
See this code run live at IdeOne.com.
ld.toString(): 2013-09-20
ZonedDateTime
If you want a time-of-day with that date, such as the first moment of the day, you must specify a time zone. A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your [desired/expected time zone][2] explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
Apply that ZoneId to get a ZonedDateTime. Never assume the day starts at 00:00:00. Anomalies such as Daylight Saving Time (DST) mean the day may start at another time such as 01:00:00. Let java.time determine the first moment of the day.
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
Instant
To adjust into UTC, extract an Instant.
Instant instant = zdt.toInstant() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

You need to use following date pattern, dd MMMM, yyyy
Try this code,
String dateValue = "20 September, 2013";
// Type of different Month views
SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM, yyyy"); //20 September, 2013
SimpleDateFormat sdf1 = new SimpleDateFormat("dd MM, yyyy"); //20 09, 2013
SimpleDateFormat sdf2 = new SimpleDateFormat("dd MMM, yyyy"); //20 Sep, 2013
Date date = sdf.parse(dateValue); // returns date object
System.out.println(date); // outputs: Fri Sep 20 00:00:00 IST 2013

Related

Parsing from String to Date throws Unparsable Date Error

I have an variable called data, and it has today's date as in this format: Thu May 24 13:14:41 BRT 2018. Then I format it to MySQL's Date type format, which is yyyy-MM-dd. This code does it:
String dataFormatada = new SimpleDateFormat("yyyy-MM-dd").format(data);
What I want to do is to bring it back to Date type. I've tried somethings but they didn't work. The main solution is to do as discribed in this other Stack Overflow's questioin, and with a little mod I got to what's suposely what I want:
String target = "Thu Sep 28 20:29:30 JST 2000";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date result = df.parse(target);
System.out.println(result);
But it doesn't work as I get this error when trying to parse:
java.text.ParseException: Unparseable date: "Thu Sep 28 20:29:30 JST 2000"
So I cannot just reformat the data variable, and I cannot bring dataFormatada back to Date format. How do I bring dataFormatada to Date type formatted as yyyy-MM-dd?
Your target String format is in EEE MMM dd HH:mm:ss zzz yyyy format. So you need to use EEE MMM dd HH:mm:ss zzz yyyy as pattern instead of yyyy-MM-dd.
String target = "Thu Sep 28 20:29:30 JST 2000";
DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);
Date result = df.parse(target);
System.out.println(result);
And if you want convert Date object i.e result to yyyy-MM-dd then please use the below code.
DateFormat dfDateToStr = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
String formattedDate = dfDateToStr.format(result);
System.out.println("Formatted Date String : "+formattedDate);
You need two formator, one to parse the orginal string to Date object, one to format it to desired string:
public static void main(String[] args) throws Exception {
String target = "Thu Sep 28 20:29:30 JST 2000";
DateFormat parser = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy", Locale.ENGLISH);
Date result = parser.parse(target);
System.out.println(result);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String dataFormatada = format.format(result);
}
tl;dr
For a SQL-standard DATE column, use the java.time.LocalDate class with JDBC 4.2 or later.
myPreparedStatement.setObject(
… ,
ZonedDateTime.parse( // Represent a moment in a particular time zone.
"Thu May 24 13:14:41 BRT 2018".replace( "BRT" , "Europe/London" ) ,
DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" , Locale.UK )
)
.toLocalDate() // Extract a date-only value, without time-of-day and without time zone.
)
ISO 8601
I have an variable called data, and it has today's date as in this format: Thu May 24 13:14:41 BRT 201
This is a terrible format. When exchanging date-time values as text, use only the standard ISO 8601 formats. Conveniently, the java.time classes use these formats by default when parsing/generating strings.
BST = ?? (Brazil Standard Time, British Standard Time, … )
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as BST or IST as they are not true time zones, not standardized, and not even unique(!).
The ZonedDateTime class will try to guess the intended time zone. But you should not be relying on guesses in your code.
String input = "Thu May 24 13:14:41 BRT 2018";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" , Locale.UK );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
2018-05-24T13:14:41-03:00[America/Sao_Paulo]
Looks like java.time guessed you meant Brazil Standard Time by BST. If you meant some other zone such as British time, replace that BST string by a proper time zone name.
Specify Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
String input = "Thu May 24 13:14:41 BRT 2018".replace( "BRT" , "Europe/London" );
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" , Locale.UK );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
2018-05-24T13:14:41+01:00[Europe/London]
LocalDate
You apparently care about only the date. So extract a date-only object, a LocalDate.
LocalDate ld = zdt.toLocalDate() ;
Smart objects, not dumb strings
Do not exchange date-time values with your database as text. Instead use JDBC and objects. As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
myPreparedStatement.setObject( … , ld ) ;
Retrieval.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Format a Date String with Time zone and return Date object

I need to format a string date with given time zone and return the date object back. I am currently in IST time zone.
So IST is 5 hours and 30 minutes ahead of UTC.
public void getDate(){
String dateStr = "11/25/2016T13:30:00.000";
String dateFormat = "MM/dd/yyyy'T'HH:mm:ss.SSS";
Date date = formatedStringToDate(dateStr, dateFormat);
System.out.println(date);
}
public static Date formatedStringToDate(final String date, final String dateFormat) throws ParseException {
final SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date parsedDate = null;
if (date != null) {
try {
parsedDate = sdf.parse(date);
} catch (ParseException e) {
throw e;
}
}
return parsedDate;
}
I get the below out put.
Fri Nov 25 19:00:00 **IST** 2016
The time seems to be change from 5.30 hours but then if its a IST to UCT time converstion, it should be 5.30 hours before 13:30:00 which is 08:00:00?
Also how could I change the highlighted IST part of out put string to show the currect time zone in this case UTC?
When you call toString on a Date (by printing it) you get the default format (because a Date is an object that stores a number of milliseconds, or nanoseconds in Java 9+, since an epoch). To see the result in UTC you need something like,
final DateFormat sdf = DateFormat.getDateTimeInstance(DateFormat.FULL,
DateFormat.FULL);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = formatedStringToDate(dateStr, dateFormat);
System.out.println(sdf.format(date)); // <-- format the Date
tl;dr
LocalDateTime.parse( "2017-11-25T13:30:00.000" )
.atZone( ZoneId.of( "Asia/Kolkata" ) )
2017-11-25T13:30+05:30[Asia/Kolkata]
java.time
The modern approach uses the java.time classes that replaced the troublesome old legacy date-time classes.
Parse your input string as a LocalDateTime given the lack of any indicator of zone or offset-from-UTC.
Using standard ISO 8601 format for such strings is preferred. The java.time classes use the standard formats by default when parsing/generating strings.
LocalDateTime ldt = LocalDateTime.parse( "2017-11-25T13:30:00.000" ) ;
ldt.toString(): 2017-11-25T13:30
If you are certain this date-time was intended to represent a moment by the wall-clock time of India, then assign a time zone to produce a ZonedDateTime object.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
zdt.toString(): 2017-11-25T13:30+05:30[Asia/Kolkata]
You can adjust into another zone for comparison.
ZonedDateTime zdtMontreal = zdt.withZoneSameInstant( ZoneId.of( "America/Montreal") );
zdtMontreal.toString(): 2017-11-25T03:00-05:00[America/Montreal]
To parse/generate strings in other formats such as the one in your Question, use the DateTimeFormatter or DateTimeFormatterBuilder classes. Search Stack Overflow for more info, as these have been covered extensively.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu'T'HH:mm:ss.SSS" , Locale.US ) ;
Use that formatter for parsing.
LocalDateTime ldt = LocalDateTime.parse( "11/25/2016T13:30:00.000" , f ) ;
And for generating.
String output = ldt.format( f ) ; // Generate string.
Consider using ISO 8601 formats instead.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Java TimeZone conversions

I understand that java Date is timezoneless and trying to set different timezone on Java Calendar wouldn't convert date to an appropriate Time Zone. So I have tried following code
public static String DATE_FORMAT="dd MMM yyyy hh:mm:ss";
public static String CURRENT_DATE_STRING ="31 October 2011 14:19:56 GMT";
DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(dateFormat.parseObject(CURRENT_DATE_STRING));
but it outputs wrong date Mon Oct 31 16:19:56 when it must be 12:19:56?
The main issue here is your date format string is using hh (12-hour clock) instead of HH (24-hour)
Secondly, your date format should specify that your date string contains the timezone.
(Alternatively you could uncomment the commented line, to tell it the correct timezone).
Thirdly, you should use a DateFormat to output the time to screen aswell...
Finally, UTC = GMT, so the UTC time is also 14:19:56
(GMT, 'British Winter Time', is the same as UTC, whereas BST is one hour ahead)
public class DateFormatTest {
public static String DATE_FORMAT="dd MMM yyyy HH:mm:ss z";
public static String CURRENT_DATE_STRING ="31 October 2011 14:19:56 GMT";
public static void main(String[] args) throws ParseException {
DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
//dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
Date d= dateFormat.parse(CURRENT_DATE_STRING);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(dateFormat.format(d));
}
}
Output: 31 Oct 2011 14:19:56 UTC
HTH
tl;dr
On that date, at that time, in some eastern Europe time zones, the clocks were running two hours ahead of UTC. So the hour of 14 in UTC (GMT) will appear as 16 (not 12) in zones such as Europe/Helsinki.
ZonedDateTime
.parse
(
"31 October 2011 14:19:56 GMT" ,
DateTimeFormatter.ofPattern
(
"dd MMMM uuuu HH:mm:ss z" ,
Locale.US
)
)
.withZoneSameInstant
(
ZoneId.of( "Europe/Helsinki" )
)
.toString()
2011-10-31T16:19:56+02:00[Europe/Helsinki]
java.time
I understand that java Date is timezoneless
Actually, a java.util.Date represents a moment as seen in UTC, an offset of zero hours-minutes-seconds.
Beware of Date::toString. That terrible toString method dynamically applies the JVM’s current default time zone while generating its text. This creates an illusion of that time zone having been part of the object. One of many reasons to never use this class.
trying to set different timezone on Java Calendar wouldn't convert date to an appropriate Time Zone
You should be using the modern java.time classes, never Calendar. Specifically, use ZonedDateTime to represent a moment as seen through the wall-clock time used by the people of a particular region (a time zone).
"31 October 2011 14:19:56 GMT";
Your input of "31 October 2011 14:19:56 GMT" does not match your formatting pattern "dd MMM yyyy hh:mm:ss". That pattern fails to account for the offset of your input, an offset of zero hours-minutes-seconds indicated by the GMT at the end.
Firstly, do not exchange date-time values using such formats. Learn to use ISO 8601 standard formats for exchanging date-time values as text. The java.time classes conveniently use these standard formats by default when parsing/generating text, so no need to specify a pattern at all.
But if you must parse that particular input string of yours, define a formatting pattern to match.
String input = "31 October 2011 14:19:56 GMT";
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd MMMM uuuu HH:mm:ss z" , locale );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
Notice how we specified a Locale, to determine the human language and cultural norms used in translation of your input.
EEST – Eastern European Summer Time
Apparently you want to view this moment as seen in the time zone of eastern Europe. I will arbitrarily choose one of the several time zones in that area.
Be aware that EEST is not a real time zone. Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST or EEST as they are not true time zones, not standardized, and not even unique(!).
ZoneId zoneHelsinki = ZoneId.of( "Europe/Helsinki" );
ZonedDateTime zdtHelsinki = zdt.withZoneSameInstant( zoneHelsinki );
Dump to console.
System.out.println( "zdt = " + zdt );
System.out.println( "zdtHelsinki = " + zdtHelsinki );
zdt = 2011-10-31T14:19:56Z[GMT]
zdtHelsinki = 2011-10-31T16:19:56+02:00[Europe/Helsinki]
Notice how the hour changed from 14 to 16 because at that moment the clocks in Finland were running two hours ahead of UTC.
but it outputs wrong date Mon Oct 31 16:19:56 when it must be 12:19:56?
No the hour 14 is in UTC. Eastern Europe runs ahead of UTC, not behind it. As seen above, Finland on that day was running two hours ahead, so the little hand on the clocks of Finland were pointing at 4 (16 hour) rather than 12.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Use Joda Time. It's recommended by many StackOverflow users and is well documented with examples on timezone conversion.
Good luck!
What's the whole output? Date.toString() should print time zone. Maybe it's not in UTC in your case.

How do I display a date with a custom timezone?

Lets say I have a string that represents a date that looks like this:
"Wed Jul 08 17:08:48 GMT 2009"
So I parse that string into a date object like this:
DateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZ yyyy");
Date fromDate = (Date)formatter.parse(fromDateString);
That gives me the correct date object. Now I want to display this date as a CDT value.
I've tried many things, and I just can't get it to work correctly. There must be a simple method using the DateFormat class to get this to work. Any advice? My last attempt was this:
formatter.setTimeZone(toTimeZone);
String result = formatter.format(fromDate);
Use "zzz" instead of "ZZZ": "Z" is the symbol for an RFC822 time zone.
DateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Having said that, my standard advice on date/time stuff is to use Joda Time, which is an altogether better API.
EDIT: Short but complete program:
import java.text.*;
import java.util.*;
public class Test
{
public List<String> names;
public static void main(String [] args)
throws Exception // Just for simplicity!
{
String fromDateString = "Wed Jul 08 17:08:48 GMT 2009";
DateFormat formatter = new SimpleDateFormat
("EEE MMM dd HH:mm:ss zzz yyyy");
Date fromDate = (Date)formatter.parse(fromDateString);
TimeZone central = TimeZone.getTimeZone("America/Chicago");
formatter.setTimeZone(central);
System.out.println(formatter.format(fromDate));
}
}
Output: Wed Jul 08 12:08:48 CDT 2009
Using:
formatter.setTimeZone(TimeZone.getTimeZone("US/Central"));
outputs:
Wed Jul 08 12:08:48 CDT 2009
for the date in your example on my machine. That is after substituting zzz for ZZZ in the format string.
Sorry for digging out an old-thread. But I was wondering if there is a java-class that holds all the time-zone-ids as a constant class.
So instead of having to hard-code the time-zone-id while setting time-zone like this:
formatter.setTimeZone(TimeZone.getTimeZone("US/Central"));
we would instead be doing something more standard/uniform:
formatter.setTimeZone(TimeZone.getTimeZone(SomeConstantClass.US_CENTRAL));
where SomeConstantClass.java is a class that holds the constants referring to the different time-zone-ids that are supported by the TimeZone class.
The modern way is with the java.time classes.
ZonedDateTime
Specify a formatting pattern to match your input string. The codes are similar to SimpleDateFormat but not exactly. Be sure to read the class doc for DateTimeFormatter. Note that we specify a Locale to determine what human language to use for name of day-of-week and name of month.
String input = "Wed Jul 08 17:08:48 GMT 2009";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss z uuuu" , Locale.ENGLISH );
ZonedDateTime zdt = ZonedDateTime.parse ( input , f );
zdt.toString(): 2009-07-08T17:08:48Z[GMT]
We can adjust that into any other time zone.
Specify a proper time zone name in the format of continent/region. Never use the 3-4 letter abbreviation such as CDT or EST or IST as they are not true time zones, not standardized, and not even unique(!).
I will guess that by CDT you meant a time zone like America/Chicago.
ZoneId z = ZoneId.of( "America/Chicago" );
ZonedDateTime zdtChicago = zdt.withZoneSameInstant( z );
zdtChicago.toString() 2009-07-08T12:08:48-05:00[America/Chicago]
Instant
Generally best to work in UTC. For that extract an Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
This Instant class is a basic building-block class of java.time. You can think of ZonedDateTime as an Instant plus a ZoneId.
Instant instant = zdtChicago.toInstant();
instant.toString(): 2009-07-08T17:08:48Z
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Inconsistent date parsing using SimpleDateFormat

I'm really scratching my head on this one. I've been using SimpleDateFormats with no troubles for a while, but now, using a SimpleDateFormat to parse dates is (only sometimes) just plain wrong.
Specifically:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = sdf.parse("2009-08-19 12:00:00");
System.out.print(date.toString());
prints the string Wed Aug 19 00:00:00 EDT 2009. What the heck? - it doesn't even parse into the wrong date all the time!
Update: That fixed it beautifully. Wouldn't you know it, that was misused in a few other places as well. Gotta love debugging other people's code :)
I think you want to use the HH format, rather than 'hh' so that you are using hours between 00-23. 'hh' takes the format in 12 hour increments, and so it assumes it is in the AM.
So this
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2009-08-19 12:00:00");
System.out.print(date.toString());
Should print out
Wed Aug 19 12:00:00 EDT 2009
The hour should be specified as HH instead of hh. Check out the section on Date and Time patterns in http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html
You're printing out the toString() representation of the date, rather than the format's representation. You may also want to check the hour representation. H and h mean something different. H is for the 24 hour clock (0-23), h is for the 12 hour clock (1-12), (there is also k and K for 1-24 and 0-11 based times respectively)
You need to do something like:
//in reality obtain the date from elsewhere, e.g. new Date()
Date date = sdf.parse("2009-08-19 12:00:00");
//this format uses 12 hours for time
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//this format uses 24 hours for time
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.print(sdf.format(date));
System.out.print(sdf2.format(date));
tl;dr
LocalDateTime ldt = LocalDateTime.parse( "2009-08-19 12:00:00".replace( " " , "T" ) );
java.time
Other Answers are correct but use legacy date-time classes. Those troublesome old classes have been supplanted by the java.time classes.
Your input string is close to standard ISO 8601 format. Tweak by replacing the SPACE in the middle with a T. Then it can be parsed without specifying a formatting pattern. The java.time classes use ISO 8601 by default when parsing/generating Strings.
String input = "2009-08-19 12:00:00".replace( " " , "T" );
The input data has no info about offset-from-UTC or time zone. So we parse as a LocalDateTime.
LocalDateTime ldt = LocalDateTime.parse( input );
If by the context you know the intended offset, apply it. Perhaps it was intended for UTC (an offset of zero), where we can use the constant ZoneOffset.UTC.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
Or perhaps you know it was intended for a particular time zone. A time zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).
ZonedDateTime zdt = ldt.atZone( ZoneId.of( "America/Montreal" ) );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.

Categories

Resources