I am collecting some time and dates data from the database and for which the time is stored in UTC timezone. I want to do some changes in the code currently I am having which some what hard coded so that every year when the DST starts the data that I am collecting should start substracting 4 hours from the time as in EST the DST offset is -400 and when it ends it should substract 5 hours as after the DST the offset will be -500
I am currently doing it as bellow
Instant ins = attachment.getObtainedDate().toInstant();
ins = ins.minus(5, ChronoUnit.HOURS); // during DST
Date alteredDate = Date.from(ins);
Instant ins = attachment.getObtainedDate().toInstant();
ins = ins.minus(4, ChronoUnit.HOURS); // after DST ends
Date alteredDate = Date.from(ins);
I want to get rid of this hard coded thing as I have to manually change the 5 and 4 whenever the DST starts and ends.
Thank you in advance
CodePudding user response:
tl;dr
You said:
some time and dates data from the database and for which the time is stored in UTC timezone
and you said:
from UTC to EST without worrying about Daylight Saving Time (DST)
myResultSet
.getObject( … , OffsetDateTime.class ) // Returns a `OffsetDateTime` object, the appropriate class mapping to the standard SQL type `TIMESTAMP WITH TIME ZONE`.
.atZoneSameInstant( ZoneId.of( "America/New_York" ) ) // Returns a `ZonedDateTime` object.
Details
Your Question is confusing and convoluted. You may be trying too hard.
You said:
time and dates data from the database and for which the time is stored in UTC timezone
If your database stores moments as a date with time with an offset of zero hours-minutes-seconds from UTC, then your database table column must be of a type akin to the standard SQL type TIMESTAMP WITH TIME ZONE
. If so, you should retrieve using the Java type OffsetDateTime
.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
You said:
when the DST starts the data that I am collecting should start substracting
If you want to see that same moment through the wall-clock time of a particular time zone, apply a ZoneId
to get a ZonedDateTime
object.
Note that EST
is not a real time zone name. Perhaps you meant America/New_York
.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
You said:
I am currently doing it as bellow
Instant ins =
…
Instant
represents a moment in UTC, always in UTC. But this class does not map to any standard SQL type. Use OffsetDateTime
to exchange a moment (a specific point on the timeline) with your database.
You said:
Date alteredDate = Date.from(ins);
As for either of the Date
classes, java.util.Date
& java.sql.Date
: (a) I don’t know which you intended, and (b) neither should be used. Both Date
classes are terribly flawed, and are now legacy, supplanted by the modern java.time classes.
You said:
should start substracting 4 hours from the time as in EST the DST offset is -400 and when it ends it should substract 5 hours
No need for you to do the math. No need for you to track the DST cutover dates.
- Do your logging, debugging, data storage, data exchange, and most of your business logic in UTC (an offset of zero).
- Apply a time zone only for presentation to the user, and where required by a particular rule in your business logic.
By using ZoneId
and ZonedDateTime
classes, the DST cutovers and adjustments are handled for you.
CodePudding user response:
I manage to get the time as per the timezone where the system is using this code.
This code also manages to change the offset as per the timezone.
I am here using
- Date from java.util.Date
- ZonedDateTime from java.time.ZonedDateTime
- DateTimeFormatter from java.time.DateTimeFormatter
- Instant from java.time.Instant
The code for solving this issue
Date date = attachment.getObtainedDate(); // for getting the date in the system
// Here I m setting the zone to system default
ZoneId zoneId = ZoneId.systemDefault(); // for setting the zoneId as per the location you want
ZonedDateTime zonedDateTime = Instant.ofEpochMilli(date.getTime()).atZone(zoneId);
// for formatting date and time
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm");
String requiredDate = zonedDateTime.format(dtf);
If you want to check the offset for the time zone while debugging for more information, you can add one more line to the code
ZoneOffset offset = zonedDateTime.getOffset();