11

I a newbie to java and hence haven't been able figure this out since quite some time.

I am using Windows XP and the machine is set to TimeZone: Eastern Time (US & Canada).

I have a Java application, which takes the current system time and timezone info and writes a string like: 20101012 15:56:00 EST, to a file.

The last piece of Date above, i.e.: the timezone, changes from EST to EDT as i change my system date.

Being precise: From November(eg: Nov2009) to March (Mar 2010), it is EST, otherwise EDT.

EST is what I want ALWAYS and not EDT.

Is there any particular class / function, by which I can always read it as EST?

Awaiting for response.


Thanks for your replies. Well, I forgot to mention a few things.

  1. I want my machine to be set to: Eastern Time (US & Canada) in the windows time zone settings.

  2. In simple terms, What i want to do is: get my machine time, and write it to a text file

  3. I am aware of the daylight saving which happens from March to Nov.

But the problem is, when I write my machine time to the file, it is written as 2010 01 12 15:56:00 EST if daylight saving (DST) is not present and as 20101012 15:56:00 EDT, if DST is present. My concern is, whether it is DST or not, I want to write EST always.

ViV
  • 1,998
  • 8
  • 27
  • 54
  • 2
    If the time in the file is `20101012 15:56:00 EDT` do you want to read it as `20101012 15:56:00 EST` or `20101012 14:56:00 EST`? I'll venture you are calculating time offsets and you're getting burned by time changes. – Tony Ennis Oct 14 '10 at 13:15
  • 2
    If this is for logging reasons, consider logging the time as UTC instead. – Powerlord Oct 14 '10 at 15:52

7 Answers7

3

I don't think you should do what you are suggesting.

You are saying that regardless of what your system timezone is currently (Eastern Time is NOT your time zone, but UTC+5 or +4 is), you want it to display EST. This is just plainly wrong. Suppose it's in the summer, and your computer thinks it's 2010/6/15 15:00 locally. You print the current time and you get:

The time I print this out at: 2010 06 15 15:00:00 EDT

For whatever reason, you think that the EDT is unpleasing, and so you change it to EST:

I print this out at: 2010 06 15 15:00:00 EST

however, if you then send that snippet to someone else within the next hour, they'll be forced to think you traveled from the future! Since 15:00:00 EST is 16:00:00 EDT.

Mike Axiak
  • 11,827
  • 2
  • 33
  • 49
  • 1
    Ha Ha ... Nice example. You're very right. But, am dealing with a server to whom I need to tell: "Do a task at 20101015 15:30:30 xxx" xxx being the timezone. The server understands only EST and not EDT whatever month it is. Hence, EDT is unpleasing. – ViV Oct 15 '10 at 05:37
3

Date-time work is tricky

I a newbie to java and hence haven't been able figure this out since quite some time.

Date-time handling is surprisingly tricky for even experienced programmers. The concepts are rather slippery. All kinds of practices have developed by various people in various industries, thereby complicating matters.

Fortunately, Java now has built-in the industry-leading framework for date-time work: java.time defined in JSR 310.

Explicitly specify desired/expected time zone

I am using Windows XP and the machine is set to TimeZone:

The host OS should not affect your date-time handling work in Java.

Never rely on the host machine's current default time zone. That default can change at any time, so it is outside your control as a programmer. Instead, specify your desired/expected time zone within your Java code.

ZoneId z = ZoneId.of( "America/New_York" ) ;

EDT / Eastern Time is not a time zone

… Eastern Time (US & Canada).

There is not really such a thing as "Eastern Time". This imprecise term is a grab-bag collective noun used to describe the current offset-from-UTC used by various time zones. When doing programming, forget all about "Eastern Time", "EST", and other pseudo-zones.

Offset versus zone

Understand that an offset is merely a number of hours-minutes-seconds ahead or behind the prime meridian. An offset looks like +05:30 or -05:00.

A time zone is much more. A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region. The rules of a time zone are set capriciously by politicians, and change with surprising frequency.

A proper time zone name is composed as Continent/Region such as America/Montreal or America/New_York. See this list of zones at Wikipedia (may not be up-to-date).

ISO 8601

writes a string like: 20101012 15:56:00 EST, to a file.

We have a formal international standard for the formats of date-time values being serialized as text: ISO 8601. Do not invent your own! The standard formats are wisely designed to be practical, easy to parse by machine, and easy to read by humans across cultures.

For example, nearly 4 PM on the twelveth of October in 2010 in Québec would be:

2010-10-12T15:56-04:00

The java.time classes use the ISO 8601 formats by default when parsing/generating text. So no need to specify a formatting pattern. Use ZonedDateTime to represent a moment as seen through a particular time zone.

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.of( 2010 , 10 , 12 , 15 , 56 , 0 , 0 , z ) ;

The ZonedDateTime::toString method wisely extends the standard format to append the name of the zone in square brackets.

zdt.toString(): 2010-10-12T15:56-04:00[America/Montreal]

Parsing such a string.

ZonedDateTime zdt2 = ZonedDateTime.parse( "2010-10-12T15:56-04:00[America/Montreal]" ) ;
boolean sameZdts = zdt.equals ( zdt2 ) ;

sameZdts: true

See that code run live at IdeOne.com.

Daylight Saving Time (DST)

EST is what I want ALWAYS and not EDT.

Your goal does not make sense.

Those pseudo-zones (EST & EDT) are meant to indicate when Daylight Saving Time (DST) is in effect and when standard time is in effect. So wanting to always be using standard time in a region (a time zone) that observes DST is a contradiction, and not possible.

So if you are trying to represent a moment as seen through the wall-clock time used by the people of a particular region (a time zone), you should specify the date, the time-of-day, and the time zone via ZoneId, and let java.time handle the issue of whether DST is in effect or not.

LocalDate ld = LocalDate.of( 2010 , Month.OCTOBER , 12 ) ;
LocalTime lt = LocalTime.of( 15 , 56 , 0 ) ;
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

zdt.toString(): 2010-10-12T15:56-04:00[America/New_York]

To see that same moment in UTC, extract an Instant. Same moment, same point on the timeline, different wall-clock-time.

Instant instant = zdt.toInstant() ;

instant.toString(): 2010-10-12T19:56:00Z

See that code above run live at IdeOne.com.

Booking future appointment

am dealing with a server to whom I need to tell: "Do a task at 20101015 15:30:30 xxx" xxx being the timezone. The server understands only EST and not EDT whatever month it is. Hence, EDT is unpleasing.

Regarding the EST versus EDT, we already covered your concern as senseless/irrelevant. These flags for standard time versus Daylight Saving Time automatically switch over when a particular time zone cuts over to/from DST.

As for booking an appointment in the future, you cannot know if Daylight Saving Time (DST) is in effect or not. You cannot know if some other wacky adjustment has been made to the rules of your time zone.

As mentioned above, time zone definitions are controlled by capricious politicians. Around the world, they have shown a surprising penchant for frequent changes. The US has changed the dates of their DST cutovers multiple times over the decades. Russia has adopted and dropped DST multiple times in recent years. The latest fad is to stay on DST year-round, done recently by Turkey and Morocco, and the United States is on the verge of going this way as well.

So if you want an appointment or a task to be done at a certain time-of-day, you have represent that as a LocalDateTime which represents a date and time-of-day without the context of an offset/zone, plus represent separately the intended time zone (ZoneId).

LocalDate ld = LocalDate.of( 2020 , Month.MARCH , 15 ) ;
LocalTime lt = LocalTime.of( 15 , 0 ) ;
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;
ZoneId z = ZoneId.of( "America/Thunder_Bay" ) ;

That code above describes when we intend something to occur, but cannot determine a moment. We do not know when 3 PM will happen on March 15, because the politicians controlling the America/Thunder_Bay time zone may redefine the time zone at any moment. So all we can do is occasionally take a stab at it, dynamically. When you need to build a calendar, or schedule something to occur, you must apply the time zone to the LocalDateTime (not a moment) to produce a ZonedDateTime (a moment).

ZonedDateTime zdt = ZonedDateTime.of( ldt , z ) ;
Instant instant = zdt.toInstant() ;  // Adjust from zone to UTC (an offset of zero). Same moment, same point on the timeline.

Table of date-time types in Java, both modern and legacy

Executors

To schedule your task to run, learn about the Executors framework built into Java. Specifically, the ScheduledExecutorService class.

Firs calculate your elapsed time to wait until running the task.

Duration duration = Duration.between( Instant.now() , instant );

Define the task to be run as a Runnable. Here we use modern lambda syntax, but that is beside the point.

Runnable runnable = ( ) -> {
    System.out.println( "Running our task now: " + Instant.now() );
};

Schedule your task to run. Optionally capture the returned ScheduledFuture if you want to track completion.

final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture future = scheduler.schedule( runnable , duration.toMinutes() , TimeUnit.MINUTES );

Important: Be sure to gracefully shutdown your ScheduledExecutorService. Otherwise, the thread pool may continue running, even after you end your program.

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

I would create a custom zone:

TimeZone alwaysEst = TimeZone.getTimeZone("EST+5");

That will report as EST and will always be 5 hours ahead of UTC. In particular, do not choose an existing timezone or you will eventually get burned when a zone update changes the definition.

Do be aware that by forcing EST the dates you log will only match the time displayed by the system for 5 months out of the year. The other 7 months you'll be an hour off. It may simplify parsing the file, but it will confuse users.

Devon_C_Miller
  • 16,248
  • 3
  • 45
  • 71
0

It should be noted that during the Summer months of the Eastern timezone, pretty much every major center uses Daylight Savings Time, so you are correctly being shown the time that people in that timezone care about.

If you want it to be a specific timezone, rather than the default/system timezone, then you can force the TimeZone to EST via something like this:

TimeZone est = TimeZone.getTimeZone("EST");

Although as Michael mentioned above, the documentation recommends using a local full name such as "America/New York" rather than the general timezone abbreviation.

If you want to claim that it really is EST even though you know it to be EDT, then I suppose you could do the following: use a SimpleDateFormat instance with a custom pattern that doesn't include the timezone information, then tack "EST" onto the end of the String you write out.

Ophidian
  • 9,775
  • 2
  • 29
  • 27
0

Your question is still not clear.

I didn't undestand if you simply want to force 'EST' chars, even if your machine is set to automatically chage DST, or what you want is to get the actual time on EST.

So you have two options:

  1. Your machine time is set to 2:15pm and DST in on effect, and you want to write 2:15pm EST (which is not the correct actual time) you should use SimpleDateFormat. This way, you will be lying about the time. But, anyway, you know what best fits for you.

  2. Your machine time is set to 2:15pm and DST in on effect, and you want to write 1:15pm EST, you should use: TimeZone.setDefault(TimeZone.getTimeZone("EST"))

L. Holanda
  • 4,432
  • 1
  • 36
  • 44
  • Thanks for the clarity you brought in. I would look to implement option 1, tough it is incorrect sense. Can you please elaborate on, How can I use SimpleDateFormat to write it as 2.15 pm EST ! Thanks – ViV Oct 15 '10 at 05:58
  • 1
    Try System.out.println(new SimpleDateFormat("yyyyMMdd hh:mm:ss a 'EST'").format(yourDate)); and see the results. Look into SimpleDateFormat javadoc for inumerous pattern letters you have. – L. Holanda Oct 21 '10 at 21:12
0

The solution depends on why you're writing this time out and what you want to do with it when you read it back in (what it's going to be used to do, not "what you want"). Always writing it out as EST is a misrepresentation of fact. When EDT is in effect it is not, in fact, EST. If you're trying to track some "absolute" point in time I recommend working in GMT instead of any timezone.

Stephen P
  • 14,422
  • 2
  • 43
  • 67
  • You're very right Stephen. Answering your question, this is how the written time is being used -- I am dealing with a server to whom I need to tell: "Do a task at 20101015 15:30:30 xxx" (This is the time string that I write to file). xxx being the timezone. The server understands only EST and not EDT whichever month it is. Writing EDT as EST is misinterpretation of fact, I agree. But I'm kinda forced to do so. – ViV Oct 15 '10 at 05:49
-1

the machine is set to TimeZone: Eastern Time (US & Canada).

That's not a real time zone (neither are EDT and EST). A time zone (as understood by Java) is something like "America/Phoenix", which is an ID for an administrative timezone that has both a base offset and (optionally) switches to daylight savings time at specific dates. Both of these can change, and it's necessary to take such changes into account when interpreting historical dates.

Thus, if you don't want to have DST switches, choose a timezone that does not observe DST. It is possible that there is no such timezone and trying to act like there is would introduce impossible dates.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720