SimpleDataForma ParseException: Unparseable date? [duplicate] - java

I'm trying to parse date like this:
DateFormat df = new SimpleDateFormat("MMM dd, yyyy K:mm:ss,SSS a z", Locale.ENGLISH);
Date date = df.parse("Oct 04, 2015 2:11:58,757 AM UTC");
And I'm getting a value of 5 hours am, because i live in UTC+3 timezone. But i need to have value of 2am, however, with the same format string(date string given in a specified format, which i'm not allowed to change). How to do this?
Upd: I don't need to format the date in proper timezone, i need to COMPARE these dates by its values without timezones. I want exactly that date have parsed ignoring the timezone in original string - and be always in the same timezone (my, for example), no matter what contains original string: UTC or UTC+3 or something else.

The accepted Answer is working too hard. Manipulating offsets is the province of a date-time library. Doing such work yourself is a waste of your time, and likely to be a source of bugs.
The old java.util.Date/.Calendar classes are notoriously troublesome. Avoid them. Instead use either java.time or Joda-Time.
java.time
Java 8 and later has a new java.time framework built-in.
Confused Question
Your Question is confused. You say you want to ignore time zone, yet you accept an answer that does indeed parse and process the time zone. And that answer then adjusts the result by an offset. So, it seems that you do not want to ignore the time zone.
Indeed, ignoring the time zone rarely makes sense. Perhaps you want to compare a pair of factories in Berlin and in Detroit to see if they both take a lunch break at the same time. In this case you are comparing their respective wall-clock time. The java.time framework offers the “Local” classes for this purpose: LocalDate, LocalTime, and LocalDateTime. But this is rarely needed in most business scenarios in my experience. These objects are not tied to the timeline.
So it seems that what you do want is to be able to compare date-time values across various time zones. The java.time classes do that implicitly. ZonedDateTime objects with various assigned time zones can be compared to one another with isBefore, isAfter, and isEqual methods.
Example Code
First we parse the input string.
The z pattern code means to expect and parse a time zone. The resulting date-time object will also be assigned this object if no other specific time zone is specified.
We also assign a Locale object with a human language component matching the text we expect to see in the input string. In this case, we need any Locale with English.
String input = "Oct 04, 2015 2:11:58,757 AM UTC";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd, yyyy K:mm:ss,SSS a z" ).withLocale( Locale.ENGLISH );
ZonedDateTime then = ZonedDateTime.parse( input, formatter );
Next we get the current time for Québec. This arbitrary choice of time zone will demonstrate further below that we can compare this ZonedDateTime object to another with a different time zone. Specifically, comparing against the UTC time zone assigned to our then object above.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
Do the comparison.
Boolean isThenBeforeNow = then.isBefore( now );
By the way, generally-speaking, the best practice in date-time work is to convert all your date-time values to UTC time zone for business logic, storage, and data exchange. Adjust into a time zone only as need be to satisfy a user’s expectations on-screen or in reports.
ZonedDateTime nowUtc = now.withZoneSameInstant( ZoneOffset.UTC );
Dump to console.
System.out.println( "input: " + input );
System.out.println( "then: " + then );
System.out.println( "now: " + now );
System.out.println( "isThenBeforeNow: " + isThenBeforeNow );
System.out.println( "nowUtc: " + nowUtc );
When run.
input: Oct 04, 2015 2:11:58,757 AM UTC
then: 2015-10-04T02:11:58.757Z[UTC]
now: 2015-10-19T19:28:04.619-04:00[America/Montreal]
isThenBeforeNow: true
nowUtc: 2015-10-19T23:28:04.619Z
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, 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.

Upd2: Solved
Okay, now i get what i want:
DateFormat df = new SimpleDateFormat("MMM dd, yyyy K:mm:ss,SSS a z", Locale.ENGLISH);
Date date = df.parse("Oct 04, 2015 2:11:58,757 AM UTC");
long diff = TimeZone.getDefault().getRawOffset() - df.getTimeZone().getRawOffset();
date = new Date(date.getTime()-diff);
Anyway, thanks for everyone

Related

Java - Parsing a JLabel to java.util.Date

I'm simply trying to parse a string in JLabel to a date using a simpleDateFormatter(). Based On everything I've searched online, this code should work. However, I'm receiving the "cannot find symbol - method parse(java.lang.String)" error during compiliation. Any advice on how to resolve the issue would be greatly appreciated.
The JLabel in question was populated with a date from a database query using JDBC.
Additionally, I'm aware that that java.util.Date has been deprecated, but would still like to use it for this.
Code Snippet:
private Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
private JLabel dateDataLabel = new JLabel("");
private void setAndParseLabel()
{
dateDataLabel.setText(formatter.format(validatePass.eventDate));
java.util.Date aDate = formatter.parse(dateDataLabel.getText());
}
tl;dr
You are ignoring crucial issue of time zone. You are unwittingly parsing the input as a value in UTC.
You are using terrible old date-time classes that were supplanted years ago. Use java.time instead.
Example code:
LocalDateTime
.parse(
"2018-01-23 13:45".replace( " " , "T" ) // Comply with standard ISO 8601 format by replacing SPACE with `T`. Standard formats are used by default in java.time when parsing/generating strings.
) // Returns a `LocalDateTime` object. This is *not* a moment, is *not* a point on the timeline.
.atZone( // Apply a time zone to determine a moment, an actual point on the timeline.
ZoneId.of( "America/Montreal" )
) // Returns a `ZonedDateTime` object.
.toInstant() // Adjust from a time zone to UTC, if need be.
java.time
The modern approach uses the java.time classes.
Your input string is almost in standard ISO 8601 format. To fully comply, replace that SPACE in the middle with a T.
String input = "2018-01-23 13:45".replace( " " , "T" ) ;
Parse as a LocalDateTime because your input has no indicator of time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
A LocalDateTime by definition does not represent a moment, is not a point on the timeline. It represents potential moments along a range of about 26-27 hours (the range of time zones around the globe).
To determine a moment, assign a time zone (ZoneId) to get 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( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
If you wish to see that same moment through the wall-clock time of UTC, extract an Instant.
Instant instant = zdt.toInstant() ; // Adjust from some time zone to UTC.
Avoid java.util.Date where feasible. But if you must interoperate with old code not yet updated to java.time, you can convert back-and-forth. Call new conversion methods added to the old classes.
java.util.Date d = java.util.Date.from( instant ) ; // Going the other direction: `myJavaUtilDate.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, 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.
java.text.Format does not have method parse, so the code does not compile.
You can refer it by java.text.DateFormat:
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
There is no method parse in java.text.Format. Use java.text.DateFormat instead:
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");

Java convert millisecond timestamp to date with respect to given timezone

I have seen many resources on this but one thing I cant get is when converting the millisecond timestamp, how I add a corresponding time zone, during the conversion process.
Date date = new Date(Long.valueOf(dateInMil*1000L);
SimpleDateFormat myDate = new SimpleDateFormat("EEE, MMM d, ''yy");
String formatted = myDate.format(date);
Now if I have a time zone/offset in string formate i.e. "-04:00" or "+2:00" how to apply it to the above so I can get the proper date ?
tl;dr
Instant.ofEpochMilli( myCountOfMilliseconds )
.atZone( ZoneId.of( "Africa/Tunis" ) )
.toString()
java.time
The modern approach uses the java.time classes rather than the troublesome old Calendar/Date classes that are now legacy.
Assuming your count of milliseconds is a count since the epoch reference of first moment of 1970 in UTC (1970-01-01T00:00), then parse as a 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).
Instant instant = Instant.ofEpochMilli( myCountOfMilliseconds ) ;
To move from UTC to another time zone, apply a ZoneId to get a ZonedDateTime.
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( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Objects vs text
After assigning the time zone, then generate a string in your desired format (not before). You may be conflating date-time values (objects) with strings representing their value textually. Learn to think of smart objects, not dumb strings.
DateTimeFormatter
To generate a String in a particular format, use a DateTimeFormatter. Search Stack Overflow as this been covered many many times, as have the other concepts shown here. Of special note are the DateTimeFormatter.ofLocalized… methods.
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.
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.
I was doing a similar thing in my previous project.You can use setTimeZone method of SimpleDateFormat class. Something like this :
mydate.setTimeZone(TimeZone.getTimeZone("GMT -0400"));
DateTimeFormatter myDateFormatter
= DateTimeFormatter.ofPattern("EEE, MMM d, ''yy", Locale.ENGLISH);
long dateInSec = 1_554_321_098L;
String utcOffsetString = "-04:00";
ZoneOffset offset = ZoneOffset.of(utcOffsetString);
String date = Instant.ofEpochSecond(dateInSec)
.atOffset(offset)
.format(myDateFormatter);
System.out.println(date);
This prints
Wed, Apr 3, '19
The other example offset you gave, +2:00, is slightly more difficult since ZoneOffset.of requires either only hours (+2) or two-digit hours before the colon (+02:00). One solution is to fix the string before handing it to ZoneOffset:
String utcOffsetString = "+2:00";
utcOffsetString = utcOffsetString.replaceFirst("([-+])(\\d:\\d{2})", "$10$2");
ZoneOffset offset = ZoneOffset.of(utcOffsetString);
The result is still Wed, Apr 3, '19. If there were already 2-digit hours in the string, replaceFirst won’t replace anything, so you just get the same string back.
If I change the offset to +08:00, I get Thu, Apr 4, '19 instead.
Edit: I frankly find the regular expression I use for fixing the offset string quite unreadable. Here’s a simpler way of fixing it:
DateTimeFormatter offsetFormatter = DateTimeFormatter.ofPattern("O", Locale.ENGLISH);
ZoneOffset offset = ZoneOffset.from(offsetFormatter.parse("GMT" + utcOffsetString));
Like Basil Bourque I am using java.time. See all the details in his answer.
Not exactly what your looking for but close
String timeZone = "America/Los_Angeles"
TimeZone tz = TimeZone.getTimeZone(timeZone);
SimpleDateFormat sdf = new SimpleDateFormat("EEEEE MMMMM d hh:mm a");
sdf.setTimeZone(tz);
Date localizedTime = sdf.format(new Date());
If you keep the localization strings instead of the offsets this will work. Or you can make a map.

Convert current date & time to equivalent GMT date & time

I used the below code where I've printed the modified GMT date in String & in Date format, it's giving me two different values.
Date initial = new Date();
DateFormat dateFormatter = DateFormat.getInstance();
dateFormatter.setTimeZone (TimeZone.getTimeZone("UTC"));
String gmtS = dateFormatter.format(initial);
Date gmt = dateFormatter.parse(gmtS);
System.out.println("Data type is Date = " + gmt);
System.out.println("Data type is String "+gmtS);
Output
gtm where value id of type Date = Thu Jul 03 23:15:00 EDT 2014
gmtS where value id of type String = 7/4/14 3:15 AM
But I want to see the value (7/4/14 3:15 AM) as a Date type.
Any help is really appreciated.
When you output a Date by calling toString() (which is what System.out.println("Data type is Date = " + gmt); does) you will get that Date according to the system time zone, because that is what Date.toString() returns.
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
where:
...
zzz is the time zone (and may reflect daylight saving time). Standard time
zone abbreviations include those recognized by the method parse. If time
zone information is not available, then zzz is empty - that is, it
consists of no characters at all.
So, to get the output you expect use your dateFormatter to format it again.
String gmtS = dateFormatter.format(initial);
Date gmt = dateFormatter.parse(gmtS);
System.out.println("Data type is Date = " + dateFormatter.format(gmt));
tl;dr
Instant.now().toString()
2019-02-07T19:15:29.123456Z
Avoid legacy date-time classes
You are using date-time classes that are terribly troublesome, with many flaws in design.
First, you should know that java.util.Date represents a moment in UTC, always in UTC by definition. But its toString method tells a lie, dynamically applying the JVM’s current default time zone while generating the text representing the moment in the Date object.
java.time
The modern approach uses the java.time classes.
Instant
For a moment in UTC, use Instant. Like java.time.Date it represents a moment always in UTC (but with a finer resolution of nanoseconds versus milliseconds). Indeed, you can convert easily back-and-forth between Date and Instant by using new methods added to the old class.
Unlike toString on Date, the toString method on Instant always tells the truth. The method generates text in standard ISO 8601 format. The T in the middle separates the date portion from the time portion. The Z on the end is short for UTC and is pronounced “Zulu”.
Instant.now().toString(): 2019-01-23T12:34:56.123456789Z
OffsetDateTime
The Instant class is a basic building-block class in java.time, with limited functionality. If you want more flexible formatting, use the OffsetDateTime class with the offset set to UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Or skip the Instant class.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
To generate text representing the value of the OffsetDateTime object, use the DateTimeFormatter class. Search Stack Overflow as this has been covered many many times already.
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, 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.

Date Time Conversion based on the TimeZone Java/Groovy

I am in MST and I want my Date in PST. I set the timeZone that I want.
Now if i do c.getTime() I always get my server time.
Instead I want Pacific Date time. Please help
How to get the date time Object in the specified timezone.
Calendar c= Calendar.getInstance();
TimeZone timezone= TimeZone.getTimeZone("PST");
c.setTimeZone(timezone)
Or, use JodaTime
#Grab( 'joda-time:joda-time:2.3' )
import org.joda.time.*
def now = new DateTime()
println now.withZone( DateTimeZone.forTimeZone( TimeZone.getTimeZone( "PST" ) ) )
​TimeZone.setDefault(TimeZone.getTimeZone('PST'))
println new Date() //PST time
You can set the default timezone to PST/MST according to your need and then get the date. I would do this in a test method, if possible.
UPDATE: The Joda-Time project has been succeeded by the java.time classes. See this other Answer.
(a) Use Joda-Time (or new JSR 310 built into Java 8). Don't even think about using the notoriously bad java.util.Date/Calendar.
(b) Your question is not clear. Your comments on answers talk about comparing, but you say nothing about comparing in your question.
(c) Avoid the use of 3-letter time zone abbreviations. Read note of deprecation in Joda-Time doc for TimeZone class.
(d) Avoid default time zone. Say what you mean. The time zone of your computer can change intentionally or not.
(e) Search StackOverflow for 'joda' for lots of code snippets and examples.
(f) Here's some Joda-Time example code to get you started.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// Specify your time zone rather than rely on default.
org.joda.time.DateTimeZone californiaTimeZone = org.joda.time.DateTimeZone.forID( "America/Los_Angeles" );
org.joda.time.DateTimeZone denverTimeZone = org.joda.time.DateTimeZone.forID( "America/Denver" );
org.joda.time.DateTime nowDenver = new org.joda.time.DateTime( denverTimeZone );
org.joda.time.DateTime nowCalifornia = nowDenver.toDateTime( californiaTimeZone );
// Same moment in the Universe’s timeline, but presented in the local context.
System.out.println( "nowDenver: " + nowDenver );
System.out.println( "nowCalifornia: " + nowCalifornia );
When run…
nowDenver: 2013-11-21T18:12:49.372-07:00
nowCalifornia: 2013-11-21T17:12:49.372-08:00
About Joda-Time…
// Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
// http://www.joda.org/joda-time/
// Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
// JSR 310 was inspired by Joda-Time but is not directly based on it.
// http://jcp.org/en/jsr/detail?id=310
// By default, Joda-Time produces strings in the standard ISO 8601 format.
// https://en.wikipedia.org/wiki/ISO_8601
// About Daylight Saving Time (DST): https://en.wikipedia.org/wiki/Daylight_saving_time
// Time Zone list: http://joda-time.sourceforge.net/timezones.html
tl;dr
ZonedDateTime
.now(
ZoneId.of( "America/Los_Angeles" )
)
See this code run live at IdeOne.com. (Be aware the system clock on that site seems to be about a half-hour slow today.)
zdt.toString(): 2019-07-27T12:29:42.029531-07:00[America/Los_Angeles]
java.time
The modern approach uses the java.time classes built into Java 8 and later, defined in JSR 310.
I am in MST and I want my Date in PST. I set the timeZone that I want.
Never depend on the current default time zone of the JVM at runtime. As a programmer, you have no control over that default. So the results of your code may vary unexpectedly.
Always specify the optional time zone arguments to date-time methods.
Now if i do c.getTime() I always get my server time.
Learn to think not of client-time or server-time, but rather UTC. Most of your business logic, data storage, data exchange, and logging should be done in UTC. Think of UTC as the One True Time™, and all other offsets/zones are but mere variations.
For UTC, use Instant.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Generate text representing that moment in standard ISO 8601 format.
String output = instant.toString() ;
Instead I want Pacific Date time. Please help How to get the date time Object in the specified timezone.
None of your terms (Pacific, MST, or PST) are true time zones.
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 as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
To adjust from UTC to a time zone, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Edmonton" ) ; // https://time.is/Edmonton
ZonedDateTime zdt = instant.atZone( z ) ;
And try one of the time zones on the west coast of North America.
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ; // https://time.is/Los_Angeles
ZonedDateTime zdt = instant.atZone( z ) ;
To generate strings in formats other than ISO 8601, use the DateTimeFormatter class. Search Stack Overflow as this has been covered many many times already.
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.
The Java Date object do not have a timezone -- it just represents a point in time.
If you would like to format a date into a timezone, you can set it in the DateFormat class. For example:
Date date = new Date ();
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("PST"));
System.out.println(df.format(date));
df.setTimeZone(TimeZone.getTimeZone("EST"));
System.out.println(df.format(date));
will display a time in PST, then a time in EST.
I had to a similar issue myself recently, and setting the timezone to a locale worked better for me (i.e. not EST/EDT, but America/New_York). I tried EST then tried to do the daylight savings time offset stuff for EDT and this turned out to be a heck of lot easier. Set your timezone to whatever you want it to be then make use of the Date object to create a new date and it will for that timezone. Then you can use the format method to take a timestamp however you please.
TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));
Date date = new Date();
timeStamp = date.format('yyyy-MM-dd HH:mm:ss.SSSZ');
System.out.println(timeStamp);
Returns
"2019-07-25 17:09:23:626-0400"

SimpleDateFormat without the Timezone Offset in Java (GMT+00:00) for Custom Timezone

Is it possible to format a date time in Java using the SimpleDateFormat class to give the timezone part of a date without having the +0000 after it.
Edit
We are changing the Default Timezone within Java as follows:
SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");
TimeZone.setDefault(tz);
Unfortunately, I am in no position to remove this code. I would hazard a guess at the whole system stopping working. I think the initial author put this in to work around some day light saving issues.
With this in mind, I want to format the date as:
2011-12-27 09:00 GMT
or
2011-12-27 09:00 BST
I can only get the SimpleDateFormat to output as:
2011-12-27 09:00:00 GMT+00:00
which uses the format string yyyy-MM-dd HH:mm:ss z
I cannot see anywhere where the simple timezone has any reference to winter time (GMT) id or summer time id (BST).
This Question and the Answers are now outmoded. They use old date-time classes outmoded by the java.time framework built into Java 8 and later. The old classes are poorly designed, confusing, and troublesome; Avoid them.
Avoid 3-4 Letter Zone Codes
Avoid the 3-4 letter codes such as BST. They are neither standardized nor unique. They do not actually represent time zones. And they add even more confusion to the problem of Daylight Saving Time (DST).
Instead, use proper time zones. Most are continent/region format such as Europe/London.
Avoid setting default time zone
Calling java.util.TimeZone.setDefault should be done only in the most extreme cases. This call affects all code running in all threads of all apps within the JVM immediately during runtime.
Instead, in all your date-time code, specify the desired/expected time zone. If omitted, Java falls back by implicitly relying on the JVM’s current default time zone. As noted above this default can change at any moment during runtime! Instead, specify explicitly. If you specify your desired/expected time zone as a passed argument routinely then the current default time zone is moot, irrelevant.
java.time
The java.time framework is built into Java 8 and later. See Tutorial. Defined by JSR 310. Inspired by the highly successful Joda-Time library.
Instant
An Instant is a moment on the timeline in UTC.
The following example shows how the java.time classes can parse/generate strings by default if in standard ISO 8601 format, with no need to specify a parsing pattern. Use DateTimeFormatter class to specify other non-standard patterns.
Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );
ZonedDateTime
Apply a time zone as needed, producing a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
Generating Strings
You can produce textual representations of the ZonedDateTime object using a DateTimeFormatter. You can specify custom patterns. Or, as I recommend, let java.time localize for you.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );
Best to specify the desired/expected Locale for the same reason as time zone… the JVM’s current default can be changed at any moment by any code in any thread of any app running within the JVM. The Locale determines (a) the human language used for names of day & month, and (b) the cultural norms such as commas versus periods and the order of the parts such as month or day or year coming first.
formatter = formatter.withLocale( Locale.CANADA_FRENCH );
String output = zdt.format( formatter );
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, 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.
I think that you are using the correct pattern for your requirements, however the JDK doesn't know the name of your timezone, so it switches over to using a GMT offset value instead.
When I format a date using your pattern, I get "GMT" for the timezone part.
What does TimeZone.getDefault().getDisplayName() give you? For me, I get "Greenwich Mean Time".
Not an elegant solution at all but it works for us. I had to create a custom implementation for DateFormat/SimpleDateFormat. This looks like something as follows:
static {
// this would be initialized like something as follows when the application starts
// which causes the headaches of SimpleDateFormat not to work...
SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");
TimeZone.setDefault(tz);
}
// therefore this class will workaround the issue,
public class OurOwnCustomDateFormat
extends SimpleDateFormat {
/** The pattern to use as the format string. */
protected String pattern;
public OurOwnCustomDateFormat(String pattern) {
super(pattern);
// store the pattern
this.pattern = pattern;
}
#Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {
// custom implementation to format the date and time based on our TimeZone
toAppendTo.insert(pos.getBeginIndex(), "the date with our custom format calculated here");
return toAppendTo;
}
Since I cannot reproduce this problem on my computer. I guess this would relate about localization. Try this
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z",Locale.US).format(new Date()));
Hope this helps.
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(new Date())); for me just returns 2011-11-22 13:42:16 GMT - so appears to work as you wish. Looks like it might be a problem elsewhere, you shouldn't need to create your own formatter class though.

Categories