-1

I have one service which requires the data of date and time which I am collecting from my database. The data in the database is stored according to the UTC time zone. Now I want to get those data from the data and present it to the user in the time zone whatever the want it to be in or just so the data of time and data as per there systems default time zone. As right now I have some hard coded thing that makes the changes if the Daylight Saving Time changes For example I the DST starts it substracts 4 hours(as per EDT) from the data that is in the system and if the DST ends I have to manually change the substracted hour with 5(as per EST) hours and the present it to the user.

I am currently doing it as bellow

Here I m using

  1. Date from java.util.Date

  2. getObtainedDate is for getting data from the database

  3. I have added this minus so that it will substract that amount of time from the date.

    Instant ins = attachment.getObtainedDate().toInstant(); ins = ins.minus(5, Chronounit.HOURS); // without DST Date alteredDate = Date.from(ins);

    Instant ins = attachment.getObtainedDate().toInstant(); ins = ins.minus(4, ChronoUnit.HOURS); // during DST 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

Patel Harsh
  • 231
  • 1
  • 2
  • 7
  • 1
    An `Instant` should never be modified for daylight savings time. You should be turning it into a `ZonedDateTime` and then to a `LocalDateTime`, which will correctly reflect DST changes with the time zone used in the conversion. – Louis Wasserman Nov 09 '22 at 21:43
  • 1
    @LouisWasserman Converting from `ZonedDateTime` to `LocalDateTime` is unnecessary, introduces ambiguity, and discards vital information. – Basil Bourque Nov 09 '22 at 21:49
  • You are welcome to think that, but I think that holding on to a ZonedDateTime creates more ambiguity than its elimination. I would never have a variable of type ZonedDateTime. – Louis Wasserman Nov 10 '22 at 01:10
  • 1
    @LouisWasserman Sorry, that’s nonsense. You can do in your code as you like, of course, but the fact is: for representing the Eastern Time zone equivalent of an `Instant` `ZonedDateTime` is unambiguous and `LocalDateTime` is ambiguous. And you are completely correct: An `Instant` should never be modified for daylight saving time or for time zone at all. – Ole V.V. Nov 10 '22 at 05:44
  • If you add a day to a ZonedDateTime, does that mean 24 hours, or whatever the same time is next day? You should keep the time zone, of course, but separately, so it's always clear whether you're working in physical or civil time. – Louis Wasserman Nov 10 '22 at 16:41
  • @LouisWasserman Adding 1 day to a `ZonedDateTime` at 10 AM will as far as posible give you 10 AM the next day, no matter if that effectively boils down to adding 23 or 25 hours or some other amount. I think we’re digressing, though. – Ole V.V. Nov 10 '22 at 20:30

2 Answers2

2

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. 

If handed an object of the terribly flawed legacy class java.util.Date, immediately convert to its modern replacement class java.time.Instant. Use new conversion methods added to the old class.

Instant instant = myJavaUtilDate.toInstant() ;
ZonedDateTime zdt = instant.atZone( ZoneId.systemDefault() ) ;

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 ) ;

If you want to use the JVM‘s current default time zone:

ZoneId z = ZoneId.systemDefault() ;

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

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

  1. Date from java.util.Date
  2. ZonedDateTime from java.time.ZonedDateTime
  3. DateTimeFormatter from java.time.DateTimeFormatter
  4. 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();
Mustafa Poya
  • 2,615
  • 5
  • 22
  • 36
Patel Harsh
  • 231
  • 1
  • 2
  • 7