Reputation: 478
I'm parsing a String "11/15/2020" into a date. I need to set the time zone to EDT but this changes date to 11/14/2020. I'm assuming because I'm in CST it's removing that hour time difference from : Sun Nov 15 00:00:00 CST 2020 and this becomes the prior day.
I would like to set the timezone without modifying the date. How can I go about doing this? It would not be sufficient to just add an hour.
dateFormat dataFormat = new SimpleDateFormat("MM/dd/yy");
dataFormat.setTimeZone(TimeZone.getTimeZone(Constants.EDT_TZN));
Upvotes: 0
Views: 862
Reputation: 340118
I would like to set the timezone without modifying the date.
A date-only value such as November 15 of 2020 has no notion of time zone. You have no need to worry about time zones.
You are using terrible date-time classes that were supplanted years ago by the java.time classes defined in JSR 310. Never use SimpleDateFormat
, Date
, or Calendar
.
LocalDate
In Java, a date-only value without time-of-day and without time-of-day is represented by the LocalDate
class.
String input = "11/15/2020" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
See this code run live at IdeOne.com.
ld.toString: 2020-11-15
Perhaps you do want a moment rather than just a date. I assume that would mean you want the first moment of the day.
Do not assume the day starts at 00:00:00. Anomalies such as Daylight Saving Time (DST) means the day may start at a time such as 01:00:00. Let java.time determine what a particular day in a particular time zone begins.
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
, EDT
, CST
, or IST
as they are not true time zones, not standardized, and not even unique(!). For example, CST
could be China Standard Time just as easily as Central Standard Time in the Americas.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
zdt.toString(): 2020-11-15T00:00-05:00[America/Montreal]
Generally best to store and exchange moments in UTC. To adjust from our specified time zone to UTC, extract a Instant
from the ZonedDateTime
. An Instant
is always in UTC by definition.
Instant instant = zdt.toInstant() ;
instant.toString(): 2020-11-15T05:00:00Z
Generate text in standard ISO 8601 format. The Z
on the end means UTC, and is pronounced “Zulu”.
instant.toString(): 2020-11-15T05:00:00Z
If you must interoperate with old code not yet updated to java.time, you can convert back-and-forth. Look to new to…
/from…
methods added to the old classes.
The legacy class Date
, though misnamed, is equivalent to Instant
, both representing a moment in UTC. Instant
uses a finer resolution of nanoseconds rather than milliseconds.
Date d = java.util.Date.from( instant ) ;
…and…
Instant instant = d.toInstant() ;
Be aware that the Date::toString
method tells a lie, applying the current default time zone. While well-intentioned, in practice this is quite confusing. One of many reasons to avoid this class.
Upvotes: 2
Reputation: 35106
Time in Java (as per the Date object and System.currentTimeMillis) is defined as the milliseconds past January 1, 1970, 00:00:00 GMT. All setting the TimeZone does is localize the offset in hours at a specific (Java) time.
So you have three choices:
Upvotes: 1